From 8f6cf9cfe89f2bedafbf7788a72cb04f11c31e1f Mon Sep 17 00:00:00 2001 From: Ayoub Belarbi Date: Fri, 23 Jun 2023 13:13:43 +0000 Subject: [PATCH] Blast SDK 5.0.1 - PhysX SDK 5.2.1 (33015808) --- blast/VERSION.md | 2 +- blast/deps/repo-deps.packman.xml | 4 +- blast/docs/CHANGELOG.md | 6 + blast/repo.bat | 2 +- blast/repo.sh | 2 +- .../NvBlastExtAuthoringBondGeneratorImpl.cpp | 10 +- ...vBlastExtAuthoringCollisionBuilderImpl.cpp | 4 +- .../stress/NvBlastExtStressSolver.cpp | 2 +- blast/tools/packman/bootstrap/configure.bat | 4 +- .../packman/bootstrap/install_package.py | 9 +- blast/tools/packman/packman | 12 +- blast/tools/packman/packmanconf.py | 10 +- physx/CHANGELOG.md | 284 + physx/README.md | 3 +- physx/buildtools/cmake_generate_projects.py | 66 +- .../bootstrap/download_file_from_url.ps1 | 207 - .../fetch_file_from_packman_bootstrap.cmd | 2 +- physx/buildtools/packman/packman | 2 +- physx/compiler/public/CMakeLists.txt | 20 +- physx/dependencies.xml | 12 +- .../platformreadme/linux/README_LINUX.md | 2 +- .../platformreadme/windows/README_WINDOWS.md | 3 +- physx/generate_projects.bat | 9 +- physx/generate_projects.sh | 18 +- physx/include/PxActor.h | 7 - physx/include/PxAggregate.h | 6 +- physx/include/PxAnisotropy.h | 222 + physx/include/PxArrayConverter.h | 98 + physx/include/PxArticulationFlag.h | 27 +- .../PxArticulationJointReducedCoordinate.h | 128 +- .../include/PxArticulationReducedCoordinate.h | 147 +- physx/include/PxAttachment.h | 13 +- physx/include/PxBuffer.h | 136 - physx/include/PxConeLimitedConstraint.h | 59 +- physx/include/PxConstraint.h | 6 +- physx/include/PxConstraintDesc.h | 53 +- physx/include/PxContact.h | 25 +- physx/include/PxContactModifyCallback.h | 16 +- .../PxCustomParticleSystemSolverCallback.h | 105 - physx/include/PxFEMClothFlags.h | 9 +- physx/include/PxFEMClothMaterial.h | 34 - physx/include/PxFEMSoftBodyMaterial.h | 26 + physx/include/PxFiltering.h | 77 +- physx/include/PxHairSystemFlag.h | 1 - physx/include/PxImmediateMode.h | 77 +- physx/include/PxIsosurfaceExtraction.h | 352 + physx/include/PxLineStripSkinning.h | 119 + physx/include/PxPBDMaterial.h | 13 - physx/include/PxParticleGpu.h | 2 - .../include/PxParticleNeighborhoodProvider.h | 134 + physx/include/PxParticleSolverType.h | 3 +- physx/include/PxParticleSystem.h | 82 +- physx/include/PxPhysics.h | 219 +- physx/include/PxPhysicsAPI.h | 1 - physx/include/PxQueryFiltering.h | 25 +- physx/include/PxRigidBody.h | 16 +- physx/include/PxScene.h | 48 +- physx/include/PxSceneDesc.h | 28 +- physx/include/PxShape.h | 204 +- physx/include/PxSmoothing.h | 190 + physx/include/PxSoftBody.h | 333 +- physx/include/PxSoftBodyFlag.h | 61 +- .../include/characterkinematic/PxController.h | 14 - physx/include/characterkinematic/PxExtended.h | 221 +- physx/include/common/PxBase.h | 6 - physx/include/common/PxCoreUtilityTypes.h | 6 - physx/include/common/PxInsertionCallback.h | 2 - physx/include/common/PxPhysXCommonConfig.h | 3 + physx/include/common/PxRenderOutput.h | 6 +- physx/include/common/PxSerialFramework.h | 12 +- physx/include/common/PxTolerancesScale.h | 2 +- physx/include/common/PxTypeInfo.h | 4 - physx/include/cooking/PxBVHDesc.h | 5 - physx/include/cooking/PxConvexMeshDesc.h | 9 +- physx/include/cooking/PxCooking.h | 873 +- physx/include/cooking/PxCookingInternal.h | 4 +- physx/include/cooking/PxSDFDesc.h | 6 + .../cudamanager/PxCudaContextManager.h | 83 +- physx/include/cudamanager/PxCudaTypes.h | 10 +- physx/include/extensions/PxContactJoint.h | 17 +- physx/include/extensions/PxD6Joint.h | 76 - physx/include/extensions/PxDefaultAllocator.h | 7 + physx/include/extensions/PxDistanceJoint.h | 28 - physx/include/extensions/PxExtensionsAPI.h | 3 + physx/include/extensions/PxFixedJoint.h | 66 - physx/include/extensions/PxGearJoint.h | 8 + physx/include/extensions/PxJoint.h | 12 - physx/include/extensions/PxJointLimit.h | 126 +- .../extensions/PxParticleClothCooker.h | 5 +- physx/include/extensions/PxPrismaticJoint.h | 65 - .../include/extensions/PxRackAndPinionJoint.h | 8 + physx/include/extensions/PxRepXSerializer.h | 15 +- physx/include/extensions/PxRepXSimpleType.h | 16 +- physx/include/extensions/PxRevoluteJoint.h | 66 - physx/include/extensions/PxRigidActorExt.h | 1 - physx/include/extensions/PxSerialization.h | 19 +- physx/include/extensions/PxShapeExt.h | 6 +- physx/include/extensions/PxSoftBodyExt.h | 97 +- physx/include/extensions/PxSphericalJoint.h | 33 - physx/include/extensions/PxTetMakerExt.h | 43 +- .../include/extensions/PxTetrahedronMeshExt.h | 12 +- physx/include/foundation/PxAlloca.h | 34 +- physx/include/foundation/PxAllocator.h | 43 +- physx/include/foundation/PxAssert.h | 55 +- physx/include/foundation/PxBasicTemplates.h | 14 +- physx/include/foundation/PxBitMap.h | 104 +- physx/include/foundation/PxFoundation.h | 12 +- physx/include/foundation/PxHashInternals.h | 4 +- physx/include/foundation/PxMat33.h | 87 + physx/include/foundation/PxMathUtils.h | 31 +- physx/include/foundation/PxPhysicsVersion.h | 4 +- physx/include/foundation/PxPreprocessor.h | 9 +- physx/include/foundation/PxSIMDHelpers.h | 62 + physx/include/foundation/PxTransform.h | 90 +- physx/include/foundation/PxVecQuat.h | 17 +- physx/include/foundation/PxVecTransform.h | 2 +- .../foundation/unix/PxUnixIntrinsics.h | 4 + .../foundation/unix/sse2/PxUnixSse2AoS.h | 2 +- .../unix/sse2/PxUnixSse2InlineAoS.h | 8 +- .../foundation/windows/PxWindowsInclude.h | 4 +- physx/include/geometry/PxBVH.h | 44 - physx/include/geometry/PxGeometryQuery.h | 28 +- physx/include/geometry/PxHeightFieldSample.h | 7 - physx/include/geometry/PxMeshScale.h | 6 - physx/include/geometry/PxTetrahedronMesh.h | 7 + physx/include/gpu/PxGpu.h | 8 + physx/include/gpu/PxPhysicsGpu.h | 174 + physx/include/solver/PxSolverDefs.h | 2 +- physx/include/task/PxTaskManager.h | 5 +- physx/include/vehicle/PxVehicleDrive.h | 12 - physx/include/vehicle/PxVehicleDrive4W.h | 12 - physx/include/vehicle/PxVehicleDriveNW.h | 12 - physx/include/vehicle/PxVehicleDriveTank.h | 6 - physx/include/vehicle/PxVehicleNoDrive.h | 6 - physx/include/vehicle/PxVehicleWheels.h | 18 - .../PxVehiclePhysXActorComponents.h | 9 +- .../physxActor/PxVehiclePhysXActorFunctions.h | 10 +- .../PxVehiclePhysXRoadGeometryComponents.h | 5 +- .../PxVehiclePhysXRoadGeometryFunctions.h | 13 +- .../PxVehiclePhysXRoadGeometryParams.h | 22 +- .../vehicle2/pvd/PxVehiclePvdComponents.h | 88 +- .../vehicle2/pvd/PxVehiclePvdFunctions.h | 67 +- .../vehicle2/pvd/PxVehiclePvdHelpers.h | 15 +- .../vehicle2/tire/PxVehicleTireComponents.h | 2 +- .../pvdruntime/compiler/cmake/CMakeLists.txt | 14 - .../compiler/cmake/PVDRuntime.cmake | 5 + physx/pvdruntime/include/OmniPvdCommands.h | 28 +- physx/pvdruntime/include/OmniPvdDefines.h | 3 +- .../include/OmniPvdLibraryFunctions.h | 10 +- physx/pvdruntime/include/OmniPvdLoader.h | 4 +- physx/pvdruntime/include/OmniPvdReadStream.h | 4 +- physx/pvdruntime/include/OmniPvdReader.h | 29 +- physx/pvdruntime/include/OmniPvdWriteStream.h | 2 +- physx/pvdruntime/include/OmniPvdWriter.h | 138 +- .../src/OmniPvdDefinesInternal.h} | 12 +- .../src/OmniPvdFileReadStreamImpl.cpp | 2 +- .../src/OmniPvdFileReadStreamImpl.h | 4 +- .../src/OmniPvdFileWriteStreamImpl.cpp | 2 +- .../src/OmniPvdFileWriteStreamImpl.h | 2 +- physx/pvdruntime/src/OmniPvdHelpers.cpp | 4 +- .../src/OmniPvdLibraryFunctionsImpl.cpp | 20 +- .../src/OmniPvdMemoryReadStreamImpl.cpp | 2 +- .../src/OmniPvdMemoryReadStreamImpl.h | 4 +- .../src/OmniPvdMemoryStreamImpl.cpp | 4 +- .../pvdruntime/src/OmniPvdMemoryStreamImpl.h | 4 +- .../src/OmniPvdMemoryWriteStreamImpl.cpp | 2 +- .../src/OmniPvdMemoryWriteStreamImpl.h | 2 +- physx/pvdruntime/src/OmniPvdReaderImpl.cpp | 222 +- physx/pvdruntime/src/OmniPvdReaderImpl.h | 23 +- physx/pvdruntime/src/OmniPvdWriterImpl.cpp | 240 +- physx/pvdruntime/src/OmniPvdWriterImpl.h | 33 +- physx/snippets/compiler/cmake/CMakeLists.txt | 22 +- .../compiler/cmake/SnippetRender.cmake | 14 +- .../compiler/cmake/SnippetTemplate.cmake | 1 - .../compiler/cmake/linux/SnippetRender.cmake | 20 +- .../cmake/linux/SnippetTemplate.cmake | 4 - .../cmake/windows/SnippetRender.cmake | 8 +- .../cmake/windows/SnippetTemplate.cmake | 12 +- physx/snippets/media/vehicledata/Base.json | 6 +- .../SnippetArticulation.cpp | 14 +- .../snippetcustomconvex/CustomConvex.cpp | 2 +- .../snippetcustomgeometry/VoxelMap.cpp | 2 +- .../SnippetCustomGeometryCollision.cpp | 2 +- .../snippetcustomjoint/PulleyJoint.cpp | 13 +- .../SnippetDelayLoadHook.cpp | 2 +- .../SnippetGeometryQueryRender.cpp | 6 +- .../snippethellogrb/SnippetHelloGRBRender.cpp | 5 - .../SnippetImmediateArticulation.cpp | 99 +- .../SnippetImmediateMode.cpp | 2 +- .../snippetisosurface/SnippetIsosurface.cpp | 501 ++ .../SnippetIsosurfaceRender.cpp | 268 + physx/snippets/snippetjoint/SnippetJoint.cpp | 2 +- .../snippetjointdrive/SnippetJointDrive.cpp | 48 +- .../SnippetJointDriveRender.cpp | 8 +- .../snippetkinematicsoftbody/MeshGenerator.h | 108 + .../SnippetKinematicSoftBody.cpp | 413 + .../SnippetKinematicSoftBody.h | 90 + .../SnippetKinematicSoftBodyRender.cpp | 100 + .../SnippetLoadCollection.cpp | 10 +- .../SnippetMultiPruners.cpp | 3 +- .../snippetomnipvd/SnippetOmniPvd.cpp | 23 +- .../snippetomnipvd/SnippetOmniPvdRender.cpp | 3 + .../snippetpbdcloth/SnippetPBDClothRender.cpp | 17 +- .../SnippetPBDInflatableRender.cpp | 17 +- .../snippets/snippetpbf/SnippetPBFRender.cpp | 19 +- .../SnippetPBFMultiMatRender.cpp | 13 +- .../SnippetPointDistanceQueryRender.cpp | 7 +- .../SnippetQuerySystemAllQueries.cpp | 6 +- .../SnippetQuerySystemCustomCompound.cpp | 6 +- .../snippets/snippetrender/SnippetRender.cpp | 10 +- physx/snippets/snippetrender/SnippetRender.h | 2 +- physx/snippets/snippetsdf/SnippetSDF.cpp | 6 +- .../snippets/snippetsdf/SnippetSDFRender.cpp | 5 - .../SnippetSerialization.cpp | 17 +- .../snippetsoftbody/SnippetSoftBody.cpp | 28 +- .../snippetsoftbody/SnippetSoftBody.h | 37 +- .../snippetsoftbody/SnippetSoftBodyRender.cpp | 5 - .../SnippetSoftBodyAttachment.cpp | 25 +- .../SnippetSoftBodyAttachmentRender.cpp | 5 - .../snippetsplitsim/SnippetSplitSim.cpp | 18 +- .../SnippetStandaloneBroadphase.cpp | 2 +- .../SnippetStandaloneBVH.cpp | 12 +- .../SnippetStandaloneQuerySystem.cpp | 6 +- .../snippetstepper/SnippetStepper.cpp | 2 +- .../SnippetTriangleMeshCreate.cpp | 25 +- .../snippettriggers/SnippetTriggers.cpp | 33 +- physx/snippets/snippetutils/SnippetUtils.cpp | 57 - physx/snippets/snippetutils/SnippetUtils.h | 10 - .../enginedrivetrain/EngineDrivetrain.h | 2 + .../physxintegration/PhysXIntegration.cpp | 3 +- .../physxintegration/PhysXIntegration.h | 2 + .../CustomSuspension.cpp | 2 +- physx/source/common/src/CmConeLimitHelper.h | 90 +- physx/source/common/src/CmFlushPool.h | 4 +- physx/source/common/src/CmPtrTable.h | 7 - physx/source/common/src/CmRefCountable.h | 6 - physx/source/common/src/CmTask.h | 12 + physx/source/common/src/CmTransformUtils.h | 2 + physx/source/common/src/CmUtils.h | 15 +- physx/source/common/src/CmVisualization.cpp | 18 +- physx/source/common/src/CmVisualization.h | 32 +- physx/source/compiler/cmake/CMakeLists.txt | 24 +- physx/source/compiler/cmake/LowLevel.cmake | 2 - .../compiler/cmake/LowLevelDynamics.cmake | 5 +- physx/source/compiler/cmake/PhysX.cmake | 59 +- physx/source/compiler/cmake/PhysXCommon.cmake | 7 +- .../compiler/cmake/PhysXExtensions.cmake | 17 +- .../compiler/cmake/SimulationController.cmake | 15 +- .../compiler/cmake/linux/CMakeLists.txt | 33 +- physx/source/compiler/cmake/linux/PhysX.cmake | 1 + .../cmake/modules/ConfigureFileMT.cmake | 44 + .../modules/GetCompilerAndPlatform.cmake | 142 + .../cmake/modules/NvidiaBuildOptions.cmake | 250 + .../cmake/modules/SetOutputPaths.cmake | 121 + .../cmake/modules/linux/LinuxAarch64.cmake | 41 + ...hain.aarch64-unknown-linux-gnueabihf.cmake | 61 + ...oolchain.arm-unknown-linux-gnueabihf.cmake | 64 + ...ssToolchain.x86_64-unknown-linux-gnu.cmake | 61 + .../compiler/cmake/windows/CMakeLists.txt | 24 +- .../source/compiler/cmake/windows/PhysX.cmake | 5 +- .../compiler/cmake/windows/PhysXCommon.cmake | 4 +- .../compiler/cmake/windows/PhysXCooking.cmake | 3 +- .../cmake/windows/PhysXFoundation.cmake | 3 +- .../resource/PhysX.rc} | 21 +- .../resource}/PhysXCommon.rc | 20 +- .../resource/PhysXCooking.rc} | 21 +- .../resource}/PhysXFoundation.rc | Bin 4448 -> 4530 bytes .../resource}/resource.h | 21 +- physx/source/foundation/FdAssert.cpp | 57 +- physx/source/foundation/FdFoundation.cpp | 165 +- physx/source/foundation/FdFoundation.h | 9 +- physx/source/foundation/FdMathUtils.cpp | 29 - physx/source/foundation/unix/FdUnixSocket.cpp | 6 +- .../windows/FdWindowsPrintString.cpp | 5 +- .../foundation/windows/FdWindowsSocket.cpp | 47 +- .../include/GuDistancePointTriangle.h | 16 +- .../include/GuDistanceSegmentSegment.h | 14 +- .../source/geomutils/include/GuOverlapTests.h | 3 - physx/source/geomutils/src/GuAABBPruner.cpp | 3 +- physx/source/geomutils/src/GuBVH.cpp | 86 - physx/source/geomutils/src/GuBVH.h | 26 +- physx/source/geomutils/src/GuCookingSDF.cpp | 48 +- physx/source/geomutils/src/GuGeometryChecks.h | 2 + .../source/geomutils/src/GuGeometryQuery.cpp | 26 +- physx/source/geomutils/src/GuGjkQuery.cpp | 2 +- physx/source/geomutils/src/GuMTD.cpp | 56 +- physx/source/geomutils/src/GuMTD.h | 7 +- physx/source/geomutils/src/GuOverlapTests.cpp | 134 +- physx/source/geomutils/src/GuPruningPool.cpp | 4 +- physx/source/geomutils/src/GuRaycastTests.cpp | 22 +- physx/source/geomutils/src/GuSDF.cpp | 238 +- physx/source/geomutils/src/GuSDF.h | 40 + physx/source/geomutils/src/GuSweepTests.cpp | 71 +- .../geomutils/src/ccd/GuCCDSweepConvexMesh.h | 24 +- .../src/ccd/GuCCDSweepPrimitives.cpp | 8 +- .../src/common/GuBarycentricCoordinates.cpp | 12 +- .../geomutils/src/common/GuMeshAnalysis.cpp | 50 +- .../geomutils/src/common/GuMeshAnalysis.h | 24 +- .../src/contact/GuContactCapsuleConvex.cpp | 2 +- .../src/contact/GuContactMethodImpl.h | 14 +- .../src/contact/GuContactSphereBox.cpp | 2 +- .../geomutils/src/convex/GuBigConvexData.h | 14 - .../geomutils/src/convex/GuBigConvexData2.h | 6 - .../geomutils/src/convex/GuConvexMesh.h | 6 - .../geomutils/src/convex/GuConvexMeshData.h | 20 - .../geomutils/src/cooking/GuCookingBVH.cpp | 9 +- .../src/cooking/GuCookingConvexMesh.cpp | 9 +- .../geomutils/src/cooking/GuCookingHF.cpp | 17 +- .../GuCookingQuickHullConvexHullLib.cpp | 16 +- .../src/cooking/GuCookingTetrahedronMesh.cpp | 27 +- .../src/cooking/GuCookingTriangleMesh.cpp | 33 +- .../src/cooking/GuCookingTriangleMesh.h | 2 +- .../src/distance/GuDistancePointTriangle.cpp | 1 - .../src/distance/GuDistancePointTriangle.h | 123 - .../src/distance/GuDistanceSegmentSegment.cpp | 1 - .../distance/GuDistanceSegmentTriangle.cpp | 39 +- .../src/distance/GuDistanceSegmentTriangle.h | 18 +- .../geomutils/src/gjk/GuVecTetrahedron.h | 2 +- .../source/geomutils/src/gjk/GuVecTriangle.h | 2 +- physx/source/geomutils/src/hf/GuHeightField.h | 6 - .../src/intersection/GuIntersectionRayBox.cpp | 1 - .../src/intersection/GuIntersectionRayBox.h | 7 +- .../src/mesh/GuBV4_CapsuleSweep_Internal.h | 2 +- .../geomutils/src/mesh/GuMidphaseRTree.cpp | 1 - physx/source/geomutils/src/mesh/GuRTree.h | 13 - .../geomutils/src/mesh/GuTetrahedronMesh.h | 7 +- .../src/mesh/GuTetrahedronMeshUtils.cpp | 101 + .../GuTetrahedronMeshUtils.h} | 24 +- .../geomutils/src/mesh/GuTriangleMesh.h | 6 - .../geomutils/src/pcm/GuPCMContactBoxBox.cpp | 30 +- .../src/pcm/GuPCMContactBoxConvex.cpp | 21 +- .../src/pcm/GuPCMContactCapsuleBox.cpp | 4 +- .../src/pcm/GuPCMContactCapsuleCapsule.cpp | 12 +- .../src/pcm/GuPCMContactCapsuleConvex.cpp | 14 +- .../src/pcm/GuPCMContactCapsuleMesh.cpp | 75 +- .../src/pcm/GuPCMContactConvexCommon.cpp | 14 +- .../src/pcm/GuPCMContactConvexCommon.h | 34 +- .../src/pcm/GuPCMContactConvexConvex.cpp | 33 +- .../src/pcm/GuPCMContactConvexHeightField.cpp | 2 +- .../src/pcm/GuPCMContactConvexMesh.cpp | 6 +- .../geomutils/src/pcm/GuPCMContactGen.h | 27 +- .../src/pcm/GuPCMContactGenBoxConvex.cpp | 79 +- .../src/pcm/GuPCMContactGenSphereCapsule.cpp | 26 +- .../geomutils/src/pcm/GuPCMContactGenUtil.cpp | 19 +- .../geomutils/src/pcm/GuPCMContactGenUtil.h | 10 +- .../src/pcm/GuPCMContactPlaneBox.cpp | 2 +- .../src/pcm/GuPCMContactSphereCapsule.cpp | 2 +- .../src/pcm/GuPCMContactSphereConvex.cpp | 2 +- .../src/pcm/GuPCMContactSphereSphere.cpp | 8 +- .../src/pcm/GuPCMTriangleContactGen.cpp | 164 +- .../src/pcm/GuPersistentContactManifold.cpp | 289 +- .../src/pcm/GuPersistentContactManifold.h | 12 +- .../src/sweep/GuSweepCapsuleTriangle.cpp | 1 - .../immediatemode/src/NpImmediateMode.cpp | 476 +- .../api/include/PxsFEMClothMaterialCore.h | 26 +- .../api/include/PxsFEMSoftBodyMaterialCore.h | 19 +- .../lowlevel/api/include/PxsMaterialManager.h | 4 - .../lowlevel/api/include/PxsPBDMaterialCore.h | 11 - .../source/lowlevel/api/include/PxvDynamics.h | 18 +- .../source/lowlevel/api/include/PxvGeometry.h | 24 +- .../source/lowlevel/api/include/PxvGlobals.h | 8 - physx/source/lowlevel/api/src/px_globals.cpp | 20 +- .../common/include/pipeline/PxcContactCache.h | 2 +- .../include/pipeline/PxcNpContactPrepShared.h | 4 +- .../common/src/pipeline/PxcContactCache.cpp | 2 +- .../src/pipeline/PxcContactMethodImpl.cpp | 114 +- .../src/pipeline/PxcMaterialMethodImpl.cpp | 6 +- .../common/src/pipeline/PxcNpBatch.cpp | 27 +- .../src/pipeline/PxcNpContactPrepShared.cpp | 91 +- .../common/src/pipeline/PxcNpMemBlockPool.cpp | 36 +- .../source/lowlevel/software/include/PxsCCD.h | 16 - .../software/include/PxsContactManager.h | 2 - .../software/include/PxsContactManagerState.h | 11 - .../lowlevel/software/include/PxsContext.h | 20 +- .../software/include/PxsIslandManagerTypes.h | 82 +- .../lowlevel/software/include/PxsIslandSim.h | 199 +- .../software/include/PxsKernelWrangler.h | 2 + .../software/include/PxsNphaseCommon.h | 3 +- .../include/PxsNphaseImplementationContext.h | 144 +- .../lowlevel/software/include/PxsRigidBody.h | 6 +- .../software/include/PxsSimpleIslandManager.h | 8 +- .../include/PxsSimulationController.h | 420 +- .../include/PxvNphaseImplementationContext.h | 92 +- physx/source/lowlevel/software/src/PxsCCD.cpp | 259 +- .../software/src/PxsContactManager.cpp | 7 +- .../lowlevel/software/src/PxsContext.cpp | 86 +- .../software/src/PxsDefaultMemoryManager.cpp | 1 - .../lowlevel/software/src/PxsIslandSim.cpp | 402 +- .../src/PxsNphaseImplementationContext.cpp | 121 +- .../software/src/PxsSimpleIslandManager.cpp | 107 +- .../lowlevelaabb/include/BpAABBManager.h | 10 +- .../lowlevelaabb/include/BpAABBManagerBase.h | 51 +- .../source/lowlevelaabb/include/BpFiltering.h | 3 +- .../lowlevelaabb/include/BpVolumeData.h | 2 +- .../source/lowlevelaabb/src/BpAABBManager.cpp | 192 +- .../lowlevelaabb/src/BpAABBManagerBase.cpp | 2 - .../include/DyArticulationCore.h | 6 - .../include/DyArticulationJointCore.h | 6 - .../lowleveldynamics/include/DyConstraint.h | 25 +- .../lowleveldynamics/include/DyContext.h | 239 +- .../lowleveldynamics/include/DyFEMClothCore.h | 20 +- .../include/DyFeatherstoneArticulation.h | 466 +- .../lowleveldynamics/include/DyHairSystem.h | 5 +- .../include/DyHairSystemCore.h | 239 +- .../include/DyParticleSystemCore.h | 16 +- .../lowleveldynamics/include/DySoftBody.h | 4 +- .../lowleveldynamics/include/DySoftBodyCore.h | 24 +- .../src/DyArticulationPImpl.h | 91 +- .../src/DyArticulationUtils.h | 1 - .../src/DyBodyCoreIntegrator.h | 237 +- .../src/DyConstraintPartition.cpp | 167 +- .../src/DyConstraintPartition.h | 139 +- .../src/DyConstraintSetup.cpp | 3 +- .../src/DyConstraintSetupBlock.cpp | 15 +- .../lowleveldynamics/src/DyContactPrep.cpp | 38 +- .../lowleveldynamics/src/DyContactPrep4.cpp | 144 +- .../lowleveldynamics/src/DyContactPrep4PF.cpp | 50 +- .../lowleveldynamics/src/DyContactPrepPF.cpp | 36 +- .../src/DyContactPrepShared.h | 30 +- .../lowleveldynamics/src/DyContactReduction.h | 2 +- .../src/DyCorrelationBuffer.h | 30 +- .../lowleveldynamics/src/DyDynamics.cpp | 371 +- .../source/lowleveldynamics/src/DyDynamics.h | 194 +- .../src/DyFeatherstoneArticulation.cpp | 844 +- .../src/DyFeatherstoneForwardDynamic.cpp | 1271 +-- .../src/DyFeatherstoneInverseDynamic.cpp | 95 +- .../src/DyFrictionCorrelation.cpp | 60 +- .../src/DyPGS.h} | 32 +- .../src/DyRigidBodyToSolverBody.cpp | 7 +- physx/source/lowleveldynamics/src/DySleep.cpp | 236 + .../src/DySleep.h} | 15 +- .../lowleveldynamics/src/DySolverBody.h | 6 +- .../src/DySolverConstraintDesc.h | 9 - .../src/DySolverConstraintTypes.h | 17 +- .../src/DySolverConstraints.cpp | 142 +- .../src/DySolverConstraintsBlock.cpp | 78 +- .../lowleveldynamics/src/DySolverContact.h | 57 +- .../lowleveldynamics/src/DySolverContact4.h | 15 +- .../lowleveldynamics/src/DySolverControl.cpp | 237 +- .../lowleveldynamics/src/DySolverControl.h | 16 +- .../src/DySolverControlPF.cpp | 333 +- .../lowleveldynamics/src/DySolverControlPF.h | 2 +- .../lowleveldynamics/src/DySolverCore.h | 35 +- .../src/DySolverPFConstraints.cpp | 82 +- .../src/DySolverPFConstraintsBlock.cpp | 93 +- physx/source/lowleveldynamics/src/DySpatial.h | 139 - .../src/DyTGS.h} | 61 +- .../lowleveldynamics/src/DyTGSContactPrep.cpp | 247 +- .../lowleveldynamics/src/DyTGSContactPrep.h | 24 - .../src/DyTGSContactPrepBlock.cpp | 277 +- .../lowleveldynamics/src/DyTGSDynamics.cpp | 505 +- .../lowleveldynamics/src/DyTGSDynamics.h | 244 +- physx/source/physx/src/NpActor.cpp | 21 +- physx/source/physx/src/NpActor.h | 14 +- physx/source/physx/src/NpActorTemplate.h | 6 - physx/source/physx/src/NpAggregate.cpp | 102 +- physx/source/physx/src/NpAggregate.h | 17 +- .../NpArticulationJointReducedCoordinate.cpp | 63 +- .../NpArticulationJointReducedCoordinate.h | 6 - physx/source/physx/src/NpArticulationLink.cpp | 185 +- physx/source/physx/src/NpArticulationLink.h | 14 +- .../src/NpArticulationReducedCoordinate.cpp | 45 +- .../src/NpArticulationReducedCoordinate.h | 6 - physx/source/physx/src/NpArticulationTendon.h | 12 - physx/source/physx/src/NpBase.h | 1 - physx/source/physx/src/NpConnector.h | 14 - physx/source/physx/src/NpConstraint.h | 6 - physx/source/physx/src/NpDebugViz.cpp | 295 +- physx/source/physx/src/NpFEMCloth.cpp | 179 +- physx/source/physx/src/NpFEMCloth.h | 32 +- physx/source/physx/src/NpFEMClothMaterial.cpp | 36 +- physx/source/physx/src/NpFEMClothMaterial.h | 10 - .../physx/src/NpFEMSoftBodyMaterial.cpp | 26 +- .../source/physx/src/NpFEMSoftBodyMaterial.h | 8 +- physx/source/physx/src/NpFLIPMaterial.cpp | 4 +- physx/source/physx/src/NpFLIPMaterial.h | 6 - physx/source/physx/src/NpFactory.cpp | 288 +- physx/source/physx/src/NpFactory.h | 77 +- physx/source/physx/src/NpHairSystem.cpp | 243 +- physx/source/physx/src/NpHairSystem.h | 11 +- physx/source/physx/src/NpMPMMaterial.cpp | 4 +- physx/source/physx/src/NpMPMMaterial.h | 6 - physx/source/physx/src/NpMaterial.cpp | 18 +- physx/source/physx/src/NpMaterial.h | 6 - physx/source/physx/src/NpMetaData.cpp | 29 +- physx/source/physx/src/NpPBDMaterial.cpp | 141 +- physx/source/physx/src/NpPBDMaterial.h | 72 - physx/source/physx/src/NpParticleSystem.cpp | 125 - physx/source/physx/src/NpParticleSystem.h | 58 +- physx/source/physx/src/NpPhysics.cpp | 1114 +-- physx/source/physx/src/NpPhysics.h | 159 +- physx/source/physx/src/NpPvdSceneClient.cpp | 103 +- physx/source/physx/src/NpPvdSceneClient.h | 11 - physx/source/physx/src/NpRigidActorTemplate.h | 4 +- physx/source/physx/src/NpRigidBodyTemplate.h | 79 +- physx/source/physx/src/NpRigidDynamic.cpp | 16 +- physx/source/physx/src/NpRigidDynamic.h | 7 +- physx/source/physx/src/NpRigidStatic.h | 6 - physx/source/physx/src/NpScene.cpp | 414 +- physx/source/physx/src/NpScene.h | 37 +- .../source/physx/src/NpSceneFetchResults.cpp | 86 +- physx/source/physx/src/NpShape.cpp | 119 +- physx/source/physx/src/NpShape.h | 159 +- physx/source/physx/src/NpShapeManager.cpp | 13 +- physx/source/physx/src/NpShapeManager.h | 6 - physx/source/physx/src/NpSoftBody.cpp | 277 +- physx/source/physx/src/NpSoftBody.h | 62 +- .../physx/src/PvdMetaDataPvdBinding.cpp | 48 +- .../source/physx/src/PvdMetaDataPvdBinding.h | 4 - physx/source/physx/src/PvdPhysicsClient.cpp | 1 + .../device/windows/PhysXIndicatorWindows.cpp | 5 +- physx/source/physx/src/gpu/PxGpu.cpp | 46 +- .../physx/src/gpu/PxPhysXGpuModuleLoader.cpp | 58 +- physx/source/physx/src/omnipvd/NpOmniPvd.cpp | 4 +- .../physx/src/omnipvd/OmniPvdPxSampler.cpp | 632 +- .../physx/src/omnipvd/OmniPvdPxSampler.h | 137 +- physx/source/physx/src/omnipvd/OmniPvdTypes.h | 839 +- .../src/CctBoxController.cpp | 12 +- .../src/CctCapsuleController.cpp | 24 +- .../src/CctCharacterController.cpp | 34 +- .../src/CctCharacterControllerCallbacks.cpp | 53 +- .../src/CctController.cpp | 2 +- .../src/CctObstacleContext.cpp | 4 +- .../src/CctSweptVolume.cpp | 4 +- .../physxcharacterkinematic/src/CctUtils.h | 44 +- physx/source/physxcooking/src/Cooking.cpp | 186 +- physx/source/physxcooking/src/Cooking.h | 47 - .../physxextensions/src/ExtConstraintHelper.h | 145 +- .../physxextensions/src/ExtContactJoint.cpp | 48 +- .../src/ExtCustomGeometryExt.cpp | 19 +- .../source/physxextensions/src/ExtD6Joint.cpp | 531 +- physx/source/physxextensions/src/ExtD6Joint.h | 15 - .../physxextensions/src/ExtD6JointCreate.cpp | 44 +- .../src/ExtDefaultSimulationFilterShader.cpp | 17 + .../physxextensions/src/ExtDistanceJoint.cpp | 149 +- .../physxextensions/src/ExtDistanceJoint.h | 16 - .../physxextensions/src/ExtFixedJoint.cpp | 66 +- .../physxextensions/src/ExtFixedJoint.h | 19 - .../physxextensions/src/ExtGearJoint.cpp | 59 +- .../source/physxextensions/src/ExtGearJoint.h | 1 + physx/source/physxextensions/src/ExtJoint.cpp | 34 +- physx/source/physxextensions/src/ExtJoint.h | 75 +- .../source/physxextensions/src/ExtJointData.h | 11 +- .../physxextensions/src/ExtMetaData.cpp | 19 +- .../src/ExtParticleClothCooker.cpp | 38 +- .../physxextensions/src/ExtParticleExt.cpp | 26 +- .../physxextensions/src/ExtPrismaticJoint.cpp | 138 +- .../physxextensions/src/ExtPrismaticJoint.h | 19 - .../src/ExtRackAndPinionJoint.cpp | 76 +- .../src/ExtRackAndPinionJoint.h | 1 + .../physxextensions/src/ExtRaycastCCD.cpp | 17 +- .../physxextensions/src/ExtRevoluteJoint.cpp | 182 +- .../physxextensions/src/ExtRevoluteJoint.h | 22 +- .../physxextensions/src/ExtRigidBodyExt.cpp | 29 +- .../physxextensions/src/ExtSimpleFactory.cpp | 2 +- .../physxextensions/src/ExtSoftBodyExt.cpp | 352 +- .../physxextensions/src/ExtSphericalJoint.cpp | 130 +- .../physxextensions/src/ExtSphericalJoint.h | 16 - .../source/physxextensions/src/ExtSqQuery.cpp | 13 +- .../physxextensions/src/ExtTetMakerExt.cpp | 162 +- .../src/ExtTetrahedronMeshExt.cpp | 166 + .../omnipvd/OmniPvdPxExtensionsSampler.cpp | 97 +- .../src/omnipvd/OmniPvdPxExtensionsSampler.h | 121 +- .../src/omnipvd/OmniPvdPxExtensionsTypes.h | 385 +- .../Binary/SnBinaryDeserialization.cpp | 6 +- .../Binary/SnSerializationContext.h | 43 - .../serialization/Xml/SnJointRepXSerializer.h | 16 +- .../Xml/SnRepXCoreSerializer.cpp | 28 +- .../serialization/Xml/SnRepXCoreSerializer.h | 20 +- .../serialization/Xml/SnXmlMemoryAllocator.h | 4 +- .../serialization/Xml/SnXmlSerialization.cpp | 8 +- .../serialization/Xml/SnXmlVisitorWriter.h | 2 +- .../src/serialization/Xml/SnXmlWriter.h | 2 +- .../src/tet/ExtDelaunayBoundaryInserter.cpp | 159 +- .../src/tet/ExtDelaunayTetrahedralizer.cpp | 108 +- .../src/tet/ExtDelaunayTetrahedralizer.h | 40 +- .../src/tet/ExtFastWindingNumber.cpp | 10 +- .../src/tet/ExtFastWindingNumber.h | 10 +- .../src/tet/ExtMeshSimplificator.cpp | 123 +- .../src/tet/ExtMeshSimplificator.h | 32 +- .../src/tet/ExtOctreeTetrahedralizer.cpp | 86 +- .../src/tet/ExtOctreeTetrahedralizer.h | 16 +- .../physxextensions/src/tet/ExtRemesher.cpp | 31 +- .../physxextensions/src/tet/ExtRemesher.h | 7 +- .../src/tet/ExtTetSplitting.cpp | 4 +- .../physxextensions/src/tet/ExtTetSplitting.h | 2 +- .../physxextensions/src/tet/ExtUtilities.cpp | 13 +- .../physxextensions/src/tet/ExtUtilities.h | 4 +- .../source/physxextensions/src/tet/ExtVec3.h | 162 +- physx/source/physxgpu/include/PxPhysXGpu.h | 41 +- .../PxAutoGeneratedMetaDataObjectNames.h | 6 +- .../include/PxAutoGeneratedMetaDataObjects.h | 239 +- .../src/PxAutoGeneratedMetaDataObjects.cpp | 24 +- .../core/src/PxMetaDataObjects.cpp | 35 +- ...xtensionAutoGeneratedMetaDataObjectNames.h | 11 - .../PxExtensionAutoGeneratedMetaDataObjects.h | 86 +- ...xExtensionAutoGeneratedMetaDataObjects.cpp | 46 +- .../src/PxVehicleSuspLimitConstraintShader.h | 6 - .../src/PxVehicleSuspWheelTire4.h | 12 - .../physxvehicle/src/PxVehicleUpdate.cpp | 17 +- .../physxvehicle/src/PxVehicleWheels.cpp | 7 +- .../src/physxActor/VhPhysXActorFunctions.cpp | 4 +- .../VhPhysXConstraintHelpers.cpp | 1 - .../VhPhysXRoadGeometryFunctions.cpp | 14 +- .../physxvehicle2/src/pvd/VhPvdFunctions.cpp | 517 +- .../physxvehicle2/src/pvd/VhPvdHelpers.cpp | 189 +- .../physxvehicle2/src/pvd/VhPvdWriter.cpp | 972 +- .../physxvehicle2/src/pvd/VhPvdWriter.h | 238 +- .../src/suspension/VhSuspensionFunctions.cpp | 32 +- .../src/wheel/VhWheelFunctions.cpp | 5 +- physx/source/pvd/include/PxPvdUserRenderer.h | 8 +- physx/source/pvd/src/PxPvdUserRenderer.cpp | 18 +- physx/source/scenequery/src/SqQuery.cpp | 18 +- .../include/ScActorCore.h | 22 +- .../include/ScArticulationCore.h | 23 +- .../include/ScArticulationJointCore.h | 10 +- .../simulationcontroller/include/ScBodyCore.h | 24 +- .../include/ScBroadphase.h} | 53 +- .../include/ScConstraintCore.h | 10 - .../include/ScFEMClothCore.h | 32 +- .../include/ScHairSystemCore.h | 141 +- .../include/ScIterators.h | 11 +- .../include/ScParticleSystemCore.h | 29 +- .../simulationcontroller/include/ScPhysics.h | 1 - .../include/ScRigidCore.h | 6 - .../simulationcontroller/include/ScScene.h | 768 +- .../include/ScShapeCore.h | 30 +- .../include/ScSoftBodyCore.h | 40 +- .../include/ScStaticCore.h | 9 +- .../simulationcontroller/src/ScActorSim.cpp | 101 +- .../simulationcontroller/src/ScActorSim.h | 62 +- .../src/ScArticulationCore.cpp | 15 +- .../src/ScArticulationJointSim.cpp | 9 +- .../src/ScArticulationJointSim.h | 11 +- .../src/ScArticulationSim.cpp | 156 +- .../src/ScArticulationSim.h | 31 +- .../simulationcontroller/src/ScBodyCore.cpp | 48 +- .../simulationcontroller/src/ScBodySim.cpp | 407 +- .../simulationcontroller/src/ScBodySim.h | 169 +- .../simulationcontroller/src/ScBroadphase.cpp | 132 + .../source/simulationcontroller/src/ScCCD.cpp | 555 +- .../src/ScConstraintBreakage.cpp | 130 + .../src/ScConstraintCore.cpp | 1 - .../src/ScConstraintGroupNode.cpp | 136 - .../src/ScConstraintGroupNode.h | 176 - .../src/ScConstraintInteraction.cpp | 15 +- .../src/ScConstraintInteraction.h | 4 +- .../src/ScConstraintProjectionManager.cpp | 504 -- .../src/ScConstraintProjectionManager.h | 82 - .../src/ScConstraintProjectionTree.cpp | 565 -- .../src/ScConstraintSim.cpp | 358 +- .../src/ScConstraintSim.h | 33 +- .../src/ScContactStream.h | 1 + .../src/ScElementInteractionMarker.cpp | 7 +- .../src/ScElementInteractionMarker.h | 12 +- .../simulationcontroller/src/ScElementSim.cpp | 19 +- .../simulationcontroller/src/ScElementSim.h | 23 +- .../src/ScElementSimInteraction.h | 11 +- .../src/ScFEMClothCore.cpp | 28 +- .../src/ScFEMClothShapeSim.h | 4 +- .../src/ScFEMClothSim.cpp | 31 +- .../simulationcontroller/src/ScFEMClothSim.h | 19 +- .../simulationcontroller/src/ScFiltering.cpp | 783 ++ .../src/ScFiltering.h} | 24 +- .../src/ScHairSystemCore.cpp | 234 +- .../src/ScHairSystemShapeCore.cpp | 90 +- .../src/ScHairSystemShapeCore.h | 10 +- .../src/ScHairSystemShapeSim.h | 5 +- .../src/ScHairSystemSim.cpp | 19 +- .../src/ScHairSystemSim.h | 19 +- .../simulationcontroller/src/ScInteraction.h | 37 +- .../simulationcontroller/src/ScKinematics.cpp | 470 + .../simulationcontroller/src/ScMetaData.cpp | 5 +- .../simulationcontroller/src/ScNPhaseCore.cpp | 1186 +-- .../simulationcontroller/src/ScNPhaseCore.h | 108 +- .../src/ScParticleSystemCore.cpp | 9 - .../src/ScParticleSystemShapeCore.cpp | 1 - .../src/ScParticleSystemShapeCore.h | 14 +- .../src/ScParticleSystemShapeSim.cpp | 2 +- .../src/ScParticleSystemShapeSim.h | 5 +- .../src/ScParticleSystemSim.cpp | 13 +- .../src/ScParticleSystemSim.h | 22 +- .../simulationcontroller/src/ScPipeline.cpp | 2355 +++++ .../simulationcontroller/src/ScRigidCore.cpp | 8 +- .../simulationcontroller/src/ScScene.cpp | 7922 +++++------------ .../simulationcontroller/src/ScShapeCore.cpp | 18 +- .../src/ScShapeInteraction.cpp | 117 +- .../src/ScShapeInteraction.h | 36 +- .../simulationcontroller/src/ScShapeSim.cpp | 33 +- .../simulationcontroller/src/ScShapeSim.h | 28 +- .../src/ScShapeSimBase.cpp | 22 +- .../simulationcontroller/src/ScShapeSimBase.h | 12 +- .../src/ScSimulationController.cpp | 21 +- .../src/ScSimulationController.h | 242 +- .../simulationcontroller/src/ScSleep.cpp | 315 + .../src/ScSoftBodyCore.cpp | 71 +- .../src/ScSoftBodyShapeSim.h | 6 +- .../src/ScSoftBodySim.cpp | 23 +- .../simulationcontroller/src/ScSoftBodySim.h | 29 +- .../src/ScTriggerInteraction.cpp | 17 +- .../src/ScTriggerInteraction.h | 4 +- .../simulationcontroller/src/ScVisualize.cpp | 206 + physx/version.txt | 2 +- 703 files changed, 27161 insertions(+), 31034 deletions(-) create mode 100644 physx/include/PxAnisotropy.h create mode 100644 physx/include/PxArrayConverter.h delete mode 100644 physx/include/PxBuffer.h delete mode 100644 physx/include/PxCustomParticleSystemSolverCallback.h create mode 100644 physx/include/PxIsosurfaceExtraction.h create mode 100644 physx/include/PxLineStripSkinning.h create mode 100644 physx/include/PxParticleNeighborhoodProvider.h create mode 100644 physx/include/PxSmoothing.h create mode 100644 physx/include/gpu/PxPhysicsGpu.h rename physx/{source/lowlevel/software/include/PxsDefaultMemoryManager.h => pvdruntime/src/OmniPvdDefinesInternal.h} (87%) create mode 100644 physx/snippets/snippetisosurface/SnippetIsosurface.cpp create mode 100644 physx/snippets/snippetisosurface/SnippetIsosurfaceRender.cpp create mode 100644 physx/snippets/snippetkinematicsoftbody/MeshGenerator.h create mode 100644 physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBody.cpp create mode 100644 physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBody.h create mode 100644 physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBodyRender.cpp create mode 100644 physx/source/compiler/cmake/modules/ConfigureFileMT.cmake create mode 100644 physx/source/compiler/cmake/modules/GetCompilerAndPlatform.cmake create mode 100644 physx/source/compiler/cmake/modules/NvidiaBuildOptions.cmake create mode 100644 physx/source/compiler/cmake/modules/SetOutputPaths.cmake create mode 100644 physx/source/compiler/cmake/modules/linux/LinuxAarch64.cmake create mode 100644 physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.aarch64-unknown-linux-gnueabihf.cmake create mode 100644 physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.arm-unknown-linux-gnueabihf.cmake create mode 100644 physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.x86_64-unknown-linux-gnu.cmake rename physx/source/compiler/{resource_x64/PhysXCooking.rc => windows/resource/PhysX.rc} (73%) rename physx/source/compiler/{resource_x64 => windows/resource}/PhysXCommon.rc (73%) rename physx/source/compiler/{resource_x64/PhysX.rc => windows/resource/PhysXCooking.rc} (73%) rename physx/source/compiler/{resource_x64 => windows/resource}/PhysXFoundation.rc (86%) rename physx/source/compiler/{resource_x64 => windows/resource}/resource.h (75%) delete mode 100644 physx/source/geomutils/src/distance/GuDistancePointTriangle.h create mode 100644 physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.cpp rename physx/source/geomutils/src/{distance/GuDistancePointTriangleSIMD.h => mesh/GuTetrahedronMeshUtils.h} (71%) rename physx/source/{geomutils/src/distance/GuDistanceSegmentTriangleSIMD.h => lowleveldynamics/src/DyPGS.h} (68%) create mode 100644 physx/source/lowleveldynamics/src/DySleep.cpp rename physx/source/{lowlevel/software/include/PxsIncrementalConstraintPartitioning.h => lowleveldynamics/src/DySleep.h} (85%) delete mode 100644 physx/source/lowleveldynamics/src/DySpatial.h rename physx/source/{simulationcontroller/src/ScConstraintProjectionTree.h => lowleveldynamics/src/DyTGS.h} (54%) rename physx/source/{geomutils/src/distance/GuDistanceSegmentSegmentSIMD.h => simulationcontroller/include/ScBroadphase.h} (63%) create mode 100644 physx/source/simulationcontroller/src/ScBroadphase.cpp create mode 100644 physx/source/simulationcontroller/src/ScConstraintBreakage.cpp delete mode 100644 physx/source/simulationcontroller/src/ScConstraintGroupNode.cpp delete mode 100644 physx/source/simulationcontroller/src/ScConstraintGroupNode.h delete mode 100644 physx/source/simulationcontroller/src/ScConstraintProjectionManager.cpp delete mode 100644 physx/source/simulationcontroller/src/ScConstraintProjectionManager.h delete mode 100644 physx/source/simulationcontroller/src/ScConstraintProjectionTree.cpp create mode 100644 physx/source/simulationcontroller/src/ScFiltering.cpp rename physx/source/{geomutils/src/intersection/GuIntersectionRayBoxSIMD.h => simulationcontroller/src/ScFiltering.h} (78%) create mode 100644 physx/source/simulationcontroller/src/ScKinematics.cpp create mode 100644 physx/source/simulationcontroller/src/ScPipeline.cpp create mode 100644 physx/source/simulationcontroller/src/ScSleep.cpp create mode 100644 physx/source/simulationcontroller/src/ScVisualize.cpp diff --git a/blast/VERSION.md b/blast/VERSION.md index 0062ac971..6b244dcd6 100644 --- a/blast/VERSION.md +++ b/blast/VERSION.md @@ -1 +1 @@ -5.0.0 +5.0.1 diff --git a/blast/deps/repo-deps.packman.xml b/blast/deps/repo-deps.packman.xml index 4544873e7..e175ebac4 100644 --- a/blast/deps/repo-deps.packman.xml +++ b/blast/deps/repo-deps.packman.xml @@ -1,8 +1,8 @@ - + - + diff --git a/blast/docs/CHANGELOG.md b/blast/docs/CHANGELOG.md index b46a72a81..f1d028246 100644 --- a/blast/docs/CHANGELOG.md +++ b/blast/docs/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [5.0.1] - 22-June-2023 + +### Bugfixes +- Use proper constructors for NvTransform and NvVec3 to avoid using garbage data + + ## [5.0.0] - 23-Jan-2023 ### Changes diff --git a/blast/repo.bat b/blast/repo.bat index c760407d1..6e713c601 100644 --- a/blast/repo.bat +++ b/blast/repo.bat @@ -1,6 +1,6 @@ @echo off -call "%~dp0tools\packman\python.bat" %~dp0tools\repoman\repoman.py %* +call "%~dp0tools\packman\python.bat" "%~dp0tools\repoman\repoman.py" %* if %errorlevel% neq 0 ( goto Error ) :Success diff --git a/blast/repo.sh b/blast/repo.sh index 2297585db..a5649e402 100755 --- a/blast/repo.sh +++ b/blast/repo.sh @@ -5,4 +5,4 @@ set -e SCRIPT_DIR=$(dirname ${BASH_SOURCE}) cd "$SCRIPT_DIR" -exec "tools/packman/python.sh" tools/repoman/repoman.py $@ +exec "tools/packman/python.sh" tools/repoman/repoman.py "$@" diff --git a/blast/source/sdk/extensions/authoring/NvBlastExtAuthoringBondGeneratorImpl.cpp b/blast/source/sdk/extensions/authoring/NvBlastExtAuthoringBondGeneratorImpl.cpp index 38945abde..7c85100d7 100644 --- a/blast/source/sdk/extensions/authoring/NvBlastExtAuthoringBondGeneratorImpl.cpp +++ b/blast/source/sdk/extensions/authoring/NvBlastExtAuthoringBondGeneratorImpl.cpp @@ -303,9 +303,9 @@ float BlastBondGeneratorImpl::processWithMidplanes(TriangleProcessor* trProcesso const float maxSeparation = maxRelSeparation * std::sqrt(std::max(aBounds.getExtents().magnitudeSquared(), bBounds.getExtents().magnitudeSquared())); Separation separation; - if (!importerHullsInProximityApexFree(hull1p.size(), hull1p.data(), aBounds, NvTransform(), + if (!importerHullsInProximityApexFree(hull1p.size(), hull1p.data(), aBounds, NvTransform(NvIdentity), NvVec3(1, 1, 1), hull2p.size(), hull2p.data(), bBounds, - NvTransform(), NvVec3(1, 1, 1), 2.0f * maxSeparation, &separation)) + NvTransform(NvIdentity), NvVec3(1, 1, 1), 2.0f * maxSeparation, &separation)) { return 0.0f; } @@ -917,15 +917,15 @@ int32_t BlastBondGeneratorImpl::createBondForcedInternal(const std::vectorpointsCount, toNvShared(in[hull]->points), hullsBounds[hull], - NvTransform(), NvVec3(1, 1, 1), in[hull2]->pointsCount, - toNvShared(in[hull2]->points), hullsBounds[hull2], NvTransform(), + NvTransform(NvIdentity), NvVec3(1, 1, 1), in[hull2]->pointsCount, + toNvShared(in[hull2]->points), hullsBounds[hull2], NvTransform(NvIdentity), NvVec3(1, 1, 1), 0.0, ¶ms) == false) { continue; diff --git a/blast/source/sdk/extensions/stress/NvBlastExtStressSolver.cpp b/blast/source/sdk/extensions/stress/NvBlastExtStressSolver.cpp index a0c1c10cb..4562e8a1d 100644 --- a/blast/source/sdk/extensions/stress/NvBlastExtStressSolver.cpp +++ b/blast/source/sdk/extensions/stress/NvBlastExtStressSolver.cpp @@ -1251,7 +1251,7 @@ void ExtStressSolverImpl::setAllNodesInfoFromLL(float density) if (chunkIndex0 >= chunkCount) { // chunkIndex is invalid means it is static node (represents world) - m_graphProcessor->setNodeInfo(node0, 0.0f, 0.0f, NvVec3()); + m_graphProcessor->setNodeInfo(node0, 0.0f, 0.0f, NvVec3(NvZero)); } else { diff --git a/blast/tools/packman/bootstrap/configure.bat b/blast/tools/packman/bootstrap/configure.bat index 7c7369a13..3dad020b1 100644 --- a/blast/tools/packman/bootstrap/configure.bat +++ b/blast/tools/packman/bootstrap/configure.bat @@ -12,7 +12,7 @@ :: See the License for the specific language governing permissions and :: limitations under the License. -set PM_PACKMAN_VERSION=6.46 +set PM_PACKMAN_VERSION=6.56 :: Specify where packman command is rooted set PM_INSTALL_PATH=%~dp0.. @@ -138,7 +138,7 @@ if %errorlevel% neq 0 ( del "%TARGET%" :ENSURE_7ZA -set PM_7Za_VERSION=16.02.4 +set PM_7Za_VERSION=22.01-1 set PM_7Za_PATH=%PM_PACKAGES_ROOT%\7za\%PM_7ZA_VERSION% if exist "%PM_7Za_PATH%" goto END set PM_7Za_PATH=%PM_PACKAGES_ROOT%\chk\7za\%PM_7ZA_VERSION% diff --git a/blast/tools/packman/bootstrap/install_package.py b/blast/tools/packman/bootstrap/install_package.py index 14f8125fc..b8ae7f642 100644 --- a/blast/tools/packman/bootstrap/install_package.py +++ b/blast/tools/packman/bootstrap/install_package.py @@ -144,4 +144,11 @@ def install_package(package_path, install_path): if __name__ == "__main__": - install_package(sys.argv[1], sys.argv[2]) + executable_paths = os.getenv("PATH") + paths_list = executable_paths.split(os.path.pathsep) if executable_paths else [] + target_path_np = os.path.normpath(sys.argv[2]) + target_path_np_nc = os.path.normcase(target_path_np) + for exec_path in paths_list: + if os.path.normcase(os.path.normpath(exec_path)) == target_path_np_nc: + raise RuntimeError(f"packman will not install to executable path '{exec_path}'") + install_package(sys.argv[1], target_path_np) diff --git a/blast/tools/packman/packman b/blast/tools/packman/packman index b5edca5bb..cd4dfd34b 100644 --- a/blast/tools/packman/packman +++ b/blast/tools/packman/packman @@ -22,7 +22,7 @@ else PM_CURL_SILENT="-s -S" PM_WGET_QUIET="--quiet" fi -PM_PACKMAN_VERSION=6.46 +PM_PACKMAN_VERSION=6.56 # This is necessary for newer macOS if [ `uname` == 'Darwin' ]; then @@ -42,9 +42,13 @@ export PM_INSTALL_PATH="$(get_abs_filename "$(dirname "${BASH_SOURCE}")")" if [ -z "${PM_PACKAGES_ROOT:-}" ]; then # Set variable temporarily in this process so that the following execution will work if [ `uname` == 'Darwin' ]; then - export PM_PACKAGES_ROOT="/Library/Caches/packman" + export PM_PACKAGES_ROOT="${HOME}/Library/Application Support/packman-cache" else - export PM_PACKAGES_ROOT="/var/tmp/packman" + if [ -z "${XDG_CACHE_HOME:-}" ]; then + export PM_PACKAGES_ROOT="${HOME}/.cache/packman" + else + export PM_PACKAGES_ROOT="${XDG_CACHE_HOME}/packman" + fi fi fi @@ -151,7 +155,7 @@ if [ ! -f "$PM_MODULE" ]; then fi # Ensure 7za package exists: -PM_7za_VERSION=16.02.4 +PM_7za_VERSION=22.01-1 export PM_7za_PATH="$PM_PACKAGES_ROOT/7za/$PM_7za_VERSION" if [ ! -d "$PM_7za_PATH" ]; then export PM_7za_PATH="$PM_PACKAGES_ROOT/chk/7za/$PM_7za_VERSION" diff --git a/blast/tools/packman/packmanconf.py b/blast/tools/packman/packmanconf.py index 108a847aa..48d0e37d3 100644 --- a/blast/tools/packman/packmanconf.py +++ b/blast/tools/packman/packmanconf.py @@ -55,9 +55,15 @@ def get_packages_root(conf_dir: str) -> str: root = os.path.join(drive, "packman-repo") elif platform_name == "Darwin": # macOS - root = "/Library/Caches/packman" + root = os.path.join( + os.path.expanduser("~"), "/Library/Application Support/packman-cache" + ) elif platform_name == "Linux": - root = "/var/tmp/packman" + try: + cache_root = os.environ["XDG_HOME_CACHE"] + except KeyError: + cache_root = os.path.join(os.path.expanduser("~"), ".cache") + return os.path.join(cache_root, "packman") else: raise RuntimeError(f"Unsupported platform '{platform_name}'") # make sure the path exists: diff --git a/physx/CHANGELOG.md b/physx/CHANGELOG.md index d6a6bc14b..b72470ab2 100644 --- a/physx/CHANGELOG.md +++ b/physx/CHANGELOG.md @@ -1,3 +1,281 @@ +# v5.2.0 & v5.2.1 + +## Supported Platforms + +### Runtime + +* Linux (tested on Ubuntu 20.04) +* Microsoft Windows 10 or later (GPU acceleration: display driver and GPU supporting CUDA 11 / CUDA ARCH 3.0) + +### Development + +* Microsoft Windows 10 or later +* Microsoft Visual Studio 2017, 2019, 2022 + +## General + +* PhysX GPU binaries built with CUDA toolkit 11.8. + * Added compute capability 8.9 (Ada) and 9.0 (Hopper) + * Removed compute capability 5.0 (Maxwell) + * Enabled multi-threaded cuda kernel compilation + +### Changed: + +* INVALID_FILTER_PAIR_INDEX has been moved out of the public API. It was incorrectly exposed to users. +* The API for the filter callback changed slightly. The pairID parameter in PxSimulationFilterCallback::pairFound(), PxSimulationFilterCallback::pairLost() and PxSimulationFilterCallback::statusChange() is now a PxU64 instead of a PxU32. The filter callback will now be called from multiple threads. +* Minimum required Windows OS version was changed from Windows XP to Windows 7 +* Replaced all calls to `select` with calls to `poll` in the socket implementations +* PxSceneFlag::eENABLE_DIRECT_GPU_API and its predecessor PxSceneFlag::eSUPPRESS_READBACK are now immutable. +* CmakeModules is no longer an external dependency. It's now included in PhysX source. + +### Fixed + +* A bug that produced duplicate broadphase pairs and led to rapidly increasing GPU memory consumption was fixed. +* An immediate mode bug has been fixed. It was happening in the contact generation code, using persistent contacts, and could produce jittering. +* An indexing error was corrected that caused the CPU PGS solver with point friction to skip velocity and impulse writebacks in some scenarios. +* A thread synchronization issue was addressed that may have caused nondeterministic behavior in the CPU PGS solver. +* A crash that appeared when overflowing the maximum amount of aggregate pairs in the GPU broadphase has been fixed. +* A bug that generated broadphase pairs for removed shapes has been fixed. +* A crash that occurred when using excessively small contact buffers and/or patch buffers on the GPU. Now, contacts that don't fit into the buffer are dropped, and an error is reported. +* A bug when running generate_projects.bat if one of the parent directories contain a space. + +### Deprecated + +* PxSceneFlag::eFORCE_READBACK is deprecated. There is no replacement. +* PxSceneFlag::eSUPPRESS_READBACK is deprecated. The replacement is PxSceneFlag::eENABLE_DIRECT_GPU_API. + +### Removed + +* PxBVHStructure has been removed. Use PxBVH. +* PxBVHStructureDesc has been removed. Use PxBVHDesc. +* PxPhysics::getBVHStructures() has been removed. Use PxPhysics::getBVHs() +* PxGetAssertHandler() and PxSetAssertHandler() have been removed. +* PxMassModificationProps has been removed. Use PxConstraintInvMassScale instead. +* PxRegisterImmediateArticulations, PxRegisterArticulationsReducedCoordinate, PxRegisterHeightFields, PxCreateBasePhysics have been removed. Articulations and heightfields are now always enabled. +* PxBuffer has been removed. There is no replacement. The soft body interface now exposes direct access to GPU buffers. +* GpuExtension library has been removed. +* The deprecated PxPhysicsInsertionCallback has been removed. Please use PxInsertionCallback instead. +* The deprecated PxTaskType::Enum entries TT_CPU, TT_NOT_PRESENT and TT_COMPLETED have been removed. These entries were replaced with eCPU, eNOT_PRESENT and eCOMPLETED. +* These deprecated immediate-mode types have been removed: PxFeatherstoneArticulationJointData, PxFeatherstoneArticulationLinkData, PxFeatherstoneArticulationData, PxMutableLinkData, PxLinkData. +* The deprecated PxPhysics::createBVHStructure() and PxPhysics::getNbBVHStructures() functions have been removed. +* A deprecated PxPhysics::createAggregate() function has been removed. +* Deprecated passthrough functions in PxShape such as `getGeometryType()` and the specialized `getGeometry()` were removed. Calls to these functions should be replaced by the accessing the underlying geometry directly with `getGeometry()`. +* Context creation for CUDA/Graphics interoperability has been deprecated. interopMode has been removed from PxCudaContextManagerDesc. +* No more Support for Microsoft Visual Studio 2013 and 2015. +* All 32 bits presets are removed. + +## Rigid Body + +### Fixed + +* A crash involving static or kinematic aggregates used in combination with PxPairFilteringMode::eKILL has been fixed. +* PxRigidDynamicLockFlags (especially the linear lock flags) did not work properly with PGS. This has been fixed. +* A rare bug involving GPU aggregates, in which newly created actors could freely move through existing actors, has been fixed. +* A crash with invalid setups, where multiple materials were set on a shape referencing a triangle mesh that had no per-triangle material indices, has been fixed. Additionally this invalid setup will now trigger an error message. +* The convex-vs-mesh PCM contact generation is now more robust (CPU/GPU). Some jittering cases have been fixed. +* The capsule-vs-mesh PCM contact generation is now more robust (GPU). Some jittering cases have been fixed. +* A bug that produced jittering when contact modification was used has been fixed. It happened mainly for primitives-vs-mesh contacts, in cases where multiple contact patches were involved. +* A bug in GPU box-box contact generation that caused memory overflows and nondeterministic behavior as a result. +* A bug in the constraint solver that was using wrong indices to solve friction constraints. +* A crash in the GPU broadphase with empty aggregates has been fixed. +* Limited the maximum amount of memory that the SDF debug visualizer uses to avoid out-of-memory errors on high-resolution SDFs. +* A sufficiently large number of contacts is now generated for a dynamic object with an SDF collider lying on a single, large static triangle represented by a triangle mesh collider. +* Improved robustness to imperfect input when cooking SDFs; for example, duplicate triangles with opposite winding now produce a correct SDF. +* Fixed a rare case where the SDF contact generation algorithm could get stuck on SDF singularities and produce incorrect contacts. +* Resolved a crash that occurred when a sphere primitive collider comes into contact with an SDF collider. + +## Articulations + +### Added + +* A new feature that computes and reports the force applied by a joint to a child link has been added. The reported force is in the joint's child frame. A more detailed specification of the reported force may be found in the doxy for the newly added array PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCES. The force may be queried on CPU using the newly added flag PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCES in conjunction with the newly added array PxArticulationCache::linkIncomingJointForce and the pre-existing function PxArticulationReducedCoordinate::copyInternalStateToCache(). The equivalent with the direct GPU API is to use the newly added enumeration PxArticulationGpuDataType::eLINK_INCOMING_JOINT_FORCE in conjunction with the pre-existing function PxScene::copyArticulationData(). + +### Fixed + +* A rare bug involving articulations in aggregates has been fixed. An internal counter was not correctly updated, and could lead to internal asserts and potential crashes. +* Setting root link transforms or joint positions with the PxScene GPU API could result in incorrect collision behavior if an articulation contained links with no shapes. +* Incorrect values for link acceleration were reported with PxSceneFlag::eENABLE_GPU_DYNAMICS raised and lowered and with PxSceneFlag::eSUPPRESS_READBACK raised and lowered. This affected PxArticulationReducedCoordinate::getLinkAcceleration(), PxArticulationCache::linkAcceleration and PxScene::copyArticulationData(). This bug has been fixed. +* Incorrect values for joint acceleration were reported when PxSceneFlag::eENABLE_GPU_DYNAMICS was raised. This affected PxArticulationGpuDataType::eJOINT_ACCELERATION/PxScene::copyArticulationData() with PxSceneFlag::eSUPPRESS_READBACK raised and PxArticulationCacheFlag::eACCELERATION/PxArticulationReducedCoordinate::copyInternalStateToCache()/PxArticulationCache::jointAcceleration with PxSceneFlag::eSUPPRESS_READBACK lowered. This bug has been fixed. +* Setting a target velocity on a modifiable contact of an articulation link was not working properly. This has been fixed. +* A crash that appeared when adding an articulation was added and removed from a scene without running a sim step in-between has been fixed. +* Articulation links with extremely large mass in excess of approximately 1e+7 mass units had a tendency to fall through the ground due to internal threshold guards. This affected all solver types running on CPU. This has been fixed. +* A floating-point precision issue resulting in slower-than-expected moving prismatic joints under certain simulation conditions with the TGS solver on GPU has been fixed. + +### Deprecated + +* PxArticulationSensor has been deprecated. Along with this, PxArticulationCache::sensorForces, PxArticulationCacheFlag::eSENSOR_FORCES, PxArticulationGpuDataType::eSENSOR_FORCE, and PxArticulationSensorFlag have also been deprecated. +* PxArticulationCache::jointSolverForces has been deprecated. The replacement is PxArticulationCache::linkIncomingJointForces. Along with this, the PxArticulationFlag::eCOMPUTE_JOINT_FORCES is also deprecated. + +### Removed + +* Deprecated PxArticulationJointReducedCoordinate::setLimit and PxArticulationJointReducedCoordinate::getLimit were removed. Use PxArticulationJointReducedCoordinate::setLimitParams and PxArticulationJointReducedCoordinate::getLimitParams instead. +* Deprecated PxArticulationJointReducedCoordinate::setDrive and PxArticulationJointReducedCoordinate::getDrive were removed. Use PxArticulationJointReducedCoordinate::setDriveParams and PxArticulationJointReducedCoordinate::getDriveParams instead. + +### Changed + +* Debug visualization of articulation links (body mass axes) will now show their sleeping state (similar to rigid bodies). + +## Joints + +### Changed + +* The debug visualization color of active limits has changed from red to yellow. + +### Removed + +* Joint projection has been removed. +* The joint's "contact distance" parameter has been removed. The limits are now always active. + +### Fixed + +* The D6 joint's twist drive was using the wrong actor's axis (B instead of A). This has been fixed, and it could affect joint setups in existing scenes. To fix this in existing content it might be enough to flip the joint frames of involved actors, but this may not be possible depending on which other features (joint limits, etc) have been setup for the same joint. In the worst case it might be necessary to re-tune these joints. +* D6 joints configured to act as fixed joints (i.e. all motions locked) between static actors or world and a floating articulation base link did not constrain the rotational degrees of freedom. + +### Deprecated + +* PxContactJoint, PxJacobianRow and PxContactJointCreate() have all been marked as deprecated and will be removed in a later release. + +## Scene queries + +### Removed + +* Deprecated PxBVH::raycast(), PxBVH::sweep() and PxBVH::overlap() functions have been removed. Use the new versions with callbacks. +* A deprecated PxQueryFilterCallback::postFilter() function has been removed. Use the similar function with a different signature. +* The deprecated PxGeometryQuery::getWorldBounds() function has been removed. Please use PxGeometryQuery::computeGeomBounds() instead. +* A deprecated PxGeometryQuery::raycast() function has been removed. Please use the other function with the same name but a different signature. + +### Fixed + +* Overlap queries could still return a non-zero number of hits when all hits got filtered in the post-filter callback (e.g. using PxQueryHitType::eNONE). This has been fixed. + +### Added + +* PxScene::evaluateSDFDistances() to evaluate sdf distances and gradients at given sample points for a batch of shapes + +## Cooking + +### Removed + +* The deprecated PxCooking class has been removed. Use the standalone "immediate cooking" functions instead (e.g. PxCookBVH, PxCreateBVH...) +* PxCooking::cookBVHStructure() has been removed. Use PxCooking::cookBVH() +* PxCooking::createBVHStructure() has been removed. Use PxCooking::createBVH() + +### Deprecated + +* PxConvexFlag::eGPU_COMPATIBLE has been deprecated. Set PxCookingParams::buildGPUData to true to cook convex meshes that need to be GPU compatible. + +### Fixed + +* When convex hull cooking hit the polygon limit, the coplanar faces merge step was not run. + +## Serialization + +### Changed: + +* Version mismatch checks etc. when deserializing binary data are now applied in profile and release build configurations too. PxSerialization::createCollectionFromBinary() will return NULL if the checks fail and error messages will get sent. + +### Fixed: + +* When deserializing materials (any PxBaseMaterial-derived), their userData member was wrongly re-initialized to zero, overwriting the serialized value. + +## Pvd + +### Changed: + +* The OmniPVD API has been reworked to be more consistent and provide less room for confusion. Among the various changes are: + * The "Set" attribute type has been renamed to "UniqueList". As a consequence, the OmniPvdWriter methods registerSetAttribute, addToSetAttribute.., removeFromSetAttribute.. have been renamed to registerUniqueListAttribute, addToUniqueListAttribute, removeFromUniqueListAttribute. The enum values eOmniPvdRegisterSetAttribute, eOmniPvdAddToSetAttribute, eOmniPvdRemoveFromSetAttribute have been renamed to eREGISTER_UNIQUE_LIST_ATTRIBUTE, eADD_TO_UNIQUE_LIST_ATTRIBUTE, eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE. + * OmniPvdCommandEnum has been renamed to OmniPvdCommand and all enum values have been renamed too. + * OmniPvdDataTypeEnum has been renamed to OmniPvdDataType + * OmniPvdAttributeDataType has been removed and its usage in the API methods replaced with OmniPvdDataType::Enum + * The OmniPvdWriter methods setAttributeShallow, addToSetAttributeShallow, removeFromSetAttributeShallow have been renamed to setAttribute, addToUniqueListAttribute, removeFromUniqueListAttribute and can be dinstinguished from the more generic versions with the same name by the argument list. + * The order of the handleDepth and attributeHandles params has flipped in the OmniPvdWriter methods setAttribute, addToUniqueListAttribute, removeFromUniqueListAttribute (formerly called addToSetAttribute, removeFromSetAttribute) methods. + * The order of the enumClassHandle and attributeName parameters has flipped in the OmniPvdWriter::registerFlagsAttribute() method. + * OmniPvdReader::getCommandType() has been removed. The information is already available as part of the OmniPvdReader::getNextCommand() method. + * The parameters in OmniPvdReader::startReading() have turned from pointers to references. + * The stream parameters in OmniPvdWriter::setWriteStream() and OmniPvdReader::setReadStream() have turned from pointers to references. + * The input parameters for the following functions have turned from pointers to references: destroyOmniPvdReaderFp, destroyOmniPvdWriterFp, destroyOmniPvdFileReadStreamFp, destroyOmniPvdFileWriteStreamFp, destroyOmniPvdMemoryStreamFp + * Various input parameters in the methods of OmniPvdWriter, OmniPvdReadStream, OmniPvdWriteStream have changed from const to non-const. + * The returned data pointers of the methods getClassName(), getAttributeName(), getObjectName(), getAttributeDataPointer() of OmniPvdReader are now const. +* The OmniPVD snippet now aborts in release build configuration since PVD is not available in release. +* Unit tests can now export single or series of automatically time stamped files, when the omnipvdfile command line parameter is set to a directory +* Crash bugs in the contact reports fixed +* OmniPVD now uses the OmniPVD API derived class support to stream debug data + * Removes attribute duplication for shared base classes + * Removed ambiguity about which class a certain object is part of + * No need to have a class type attribute in streamed debug objects, the class is the type + * As a consequece greatly simplifies object and class handling in the OmniPVD extension + +## Vehicles2 + +### Fixed: + +* When using sweeps for vehicle wheel vs. ground collision detection, PxVehiclePhysXRoadGeometryQueryUpdate() wrongly treated the case of an exactly zero hit distance (wheel touching ground with suspension being exactly at max compression) as no hit. +* Undesired sleep/wake cycle for vehicles that are not moving while engines are revving. Applying throttle will keep vehicles awake now. +* Negative suspension jounce (and an assert) could result in certain scenarios where PxVehicleSuspensionStateCalculationParams::limitSuspensionExpansionVelocity was set to true and gravity was pointing in the opposite direction of the suspension travel direction. +* Various PVD related bugs. +* If the wheel IDs in PxVehicleAxleDescription::wheelIdsInAxleOrder were shuffled, the wrong road geometry velocity information was used to compute the tire slip speeds. +* When driving backwards, the thresholdForwardSpeedForWheelAngleIntegration parameter (see PxVehicleSimulationContext) was ignored. + +### Changed: + +* PxVehiclePhysXRoadGeometryQueryParams has been adjusted to allow for wheel specific filter data. As a consequence, the method PxVehiclePhysXRoadGeometryQueryUpdate() has been adjusted too. See the migration guide for more details. +* Only the engine drivetrain or direct drivetrain properties are recorded in PVD now (and not both for the same vehicle). +* All the methods in PxVehiclePvdFunctions.h and PxVehiclePvdHelpers.h have been adjusted to use references to OmniPvdWriter, PxVehiclePvdObjectHandles or PxVehiclePvdAttributeHandles objects instead of pointers to make it even clearer that these parameters are required. +* The PxVehiclePvdAttributeHandles parameter of the PxVehiclePvdObjectRelease() method has been removed. +* The PxVehiclePvdAttributeHandles and OmniPvdWriter parameter of the PxVehiclePvdObjectCreate() method have been removed. +* The OmniPvdWriter parameter of the PxVehiclePvdAttributesRelease() method has been removed. + + +## Soft Body + +### Added: + +* Kinematic soft body feature + * PxSoftBodyFlag::eKINEMATIC and PxSoftBodyFlag::ePARTIALLY_KINEMATIC. + * PxSoftBody::setKinematicTargetBufferD function to set kinematic targets based on a device buffer. + * PxConfigureSoftBodyKinematicTarget function to prepare kinematic targets for PxSoftBody::setKinematicTargetBufferD. + * PxSoftBodyExt::relaxSoftBodyMesh function to repose a tetrahedral mesh from one configuration into another. + * Optional outputVertexToInputTriangle, removeDisconnectedPatches parameters for PxTetMaker::simplifyTriangleMesh. + * PxTetrahedronMeshExt::createPointsToTetrahedronMap function to associate points to their closest tetrahedon. + * A snippet that shows how to set up and use a kinematic soft body. +* constraintOffset parameter to PxSoftBody::addSoftBodyAttachment and PxSoftBody::addClothAttachment to specify an offset of the PxConeLimitedConstraint with respect to the PxConeLimitedConstraint::mAxis. + +### Removed: + +* PxBuffer has been removed. Writing and reading the softbody simulation state is now done directly in GPU buffers. For examples, see SnippetSoftBody. + +### Deprecated: + +* PxSoftBodyExt::commit() has been deprecated. The replacement is PxSoftBodyExt::copyToDevice(). + +### Changed: + +* Renamed PxFEMSoftBodyMaterialModel::CO_ROTATIONAL, NEO_HOOKEAN to PxFEMSoftBodyMaterialModel::eCO_ROTATIONAL, eNEO_HOOKEAN. +* PxSoftBodyDataFlag has been renamed to PxSoftBodyGpuDataFlag. +* Default constructor of PxConeLimitedConstraint initializes PxConeLimitedConstraint::mAngle to -1.0 since 0.0f now indicates a 0.0 cone opening angle. +* Soft body flags used to copy stress computation were changed. The stress computation can now be performed via the intermediate data that can be copied from the internal buffers. + +### Fixed: + +* A bug that resulted in changes to PxSoftBodyFlags not being picked up has been fixed. +* Fixed a case where particles colliding with soft bodies could lead to a crash. +* Fixed a corner case where the mass of an internal node could become negative. +* An index bug when rendering tetrahedra in the snippets. + +## Particles + +### Changed: + +* Renamed PxParticleRigidAttachment::mParams to mConeLimitParams +* Added PxParticleRigidAttachment constructor to initialize with PxConeLimitedConstraint and localPose0. +* Added PxConeLimitParams constructor to initialize with PxConeLimitedConstraint. +* Added PxParticleRigidFilterPair constructor to initialize with rigid node ID and particle ID. + +### Fixed: + +* A crash when using a large number of particles has been fixed. +* A bug that resulted in changes to PxParticleFlag not being picked up has been fixed. + # v5.1.3 ## General @@ -9,6 +287,11 @@ ### Fixed * Changing the materials of a shape did not work when using GPU dynamics. +* Fixed exclusive shape binary serialization. + +### Deprecated + +* RepX/Xml serialization has been deprecated. ## Rigid Body @@ -35,6 +318,7 @@ ### Fixed * The Poisson Sampler will not cause number overflows and crashes anymore when called with parameters that lead to too many samples. +* PxParticleClothCooker fixes to support shearing and bending constraints. This will change the behavior of newly cooked cloth assets. ## Pvd diff --git a/physx/README.md b/physx/README.md index 41e8b2471..28a991a4f 100644 --- a/physx/README.md +++ b/physx/README.md @@ -52,8 +52,7 @@ For copyright details, please refer to the license files included in the package | Software | Copyright Holder | Package | |---------------------------|-------------------------------------------------------------------------------------|----------------------------------| -| CMake | Kitware, Inc. and Contributors | CMakeModules | -| FindCUDA | James Bigler: NVIDIA Corp, Abe Stephens: SCI Institute | CMakeModules | +| CMake | Kitware, Inc. and Contributors | cmake | | LLVM | University of Illinois at Urbana-Champaign | clang-physxmetadata | | Visual Studio Locator | Microsoft Corporation | VsWhere | | Freeglut | Pawel W. Olszta | freeglut-windows
opengl-linux | diff --git a/physx/buildtools/cmake_generate_projects.py b/physx/buildtools/cmake_generate_projects.py index dab3dab6d..1f4aa0cb9 100644 --- a/physx/buildtools/cmake_generate_projects.py +++ b/physx/buildtools/cmake_generate_projects.py @@ -21,10 +21,10 @@ def cmakeExt(): def filterPreset(presetName): winPresetFilter = ['win','switch','crosscompile'] - if sys.platform == 'win32': + if sys.platform == 'win32': if any(presetName.find(elem) != -1 for elem in winPresetFilter): return True - else: + else: if all(presetName.find(elem) == -1 for elem in winPresetFilter): return True return False @@ -53,12 +53,12 @@ def noPresetProvided(): print('(' + str(counter) + ') ' + presetXml.get('name') + '.user <--- ' + presetXml.get('comment')) presetList.append(presetXml.get('name') + '.user') - counter = counter + 1 + counter = counter + 1 # Fix Python 2.x. - try: + try: input = raw_input - except NameError: - pass + except NameError: + pass mode = int(eval(input('Enter preset number: '))) return presetList[mode] @@ -117,34 +117,33 @@ def isMultiConfigPlatform(self): def getCMakeSwitches(self): outString = '' + # We need gpuProjectsFound flag to avoid issues when we have both + # PX_GENERATE_GPU_PROJECTS and PX_GENERATE_GPU_PROJECTS_ONLY switches + gpuProjectsFound = False # initialize flag for cmakeSwitch in self.cmakeSwitches: outString = outString + ' ' + cmakeSwitch - if cmakeSwitch.find('PX_GENERATE_GPU_PROJECTS') != -1: + if not gpuProjectsFound and cmakeSwitch.find('PX_GENERATE_GPU_PROJECTS') != -1: + gpuProjectsFound = True # set flag to True when keyword found if os.environ.get('PM_CUDA_PATH') is not None: - outString = outString + ' -DCUDA_TOOLKIT_ROOT_DIR=' + \ - os.environ['PM_CUDA_PATH'] - if self.compiler == 'vc15': - print('VS15CL:' + os.environ['VS150CLPATH']) - outString = outString + ' -DCUDA_HOST_COMPILER=' + \ - os.environ['VS150CLPATH'] - if self.compiler == 'vc16': - print('VS16CL:' + os.environ['VS160CLPATH']) - outString = outString + ' -DCUDA_HOST_COMPILER=' + \ - os.environ['VS160CLPATH'] - if self.compiler == 'vc17': - print('VS17CL:' + os.environ['VS170CLPATH']) - outString = outString + ' -DCUDA_HOST_COMPILER=' + \ - os.environ['VS170CLPATH'] - + outString = outString + ' -DCUDAToolkit_ROOT_DIR=' + \ + os.environ['PM_CUDA_PATH'] + if self.compiler in ['vc15', 'vc16', 'vc17']: + outString = outString + ' -T cuda=' + os.environ['PM_CUDA_PATH'] + # TODO: Need to do the same for gcc (aarch64) when we package it with Packman + elif self.compiler == 'clang': + if os.environ.get('PM_clang_PATH') is not None: + outString = outString + ' -DCMAKE_CUDA_HOST_COMPILER=' + \ + os.environ['PM_clang_PATH'] + '/bin/clang++' return outString def getCMakeParams(self): outString = '' for cmakeParam in self.cmakeParams: - outString = outString + ' ' + cmakeParam + outString = outString + ' ' + cmakeParam # + ' --trace' return outString def getPlatformCMakeParams(self): + cmake_modules_root = os.environ['PHYSX_ROOT_DIR'] + '/source/compiler/cmake/modules' outString = ' ' if self.compiler == 'vc15': outString = outString + '-G \"Visual Studio 15 2017\"' @@ -167,8 +166,7 @@ def getPlatformCMakeParams(self): elif self.targetPlatform == 'switch64': outString = outString + ' -DTARGET_BUILD_PLATFORM=switch' outString = outString + ' -DCMAKE_TOOLCHAIN_FILE=' + \ - os.environ['PM_CMakeModules_PATH'] + \ - '/switch/NX64Toolchain.txt' + cmake_modules_root + '/switch/NX64Toolchain.txt' outString = outString + ' -DCMAKE_GENERATOR_PLATFORM=NX64' return outString elif self.targetPlatform == 'linux': @@ -176,8 +174,8 @@ def getPlatformCMakeParams(self): outString = outString + ' -DPX_OUTPUT_ARCH=x86' if self.compiler == 'clang-crosscompile': outString = outString + ' -DCMAKE_TOOLCHAIN_FILE=' + \ - os.environ['PM_CMakeModules_PATH'] + \ - '/linux/LinuxCrossToolchain.x86_64-unknown-linux-gnu.cmake' + cmake_modules_root + '/linux/LinuxCrossToolchain.x86_64-unknown-linux-gnu.cmake' + outString = outString + ' -DCMAKE_MAKE_PROGRAM=' + os.environ.get('PM_MinGW_PATH') + '/bin/mingw32-make.exe' elif self.compiler == 'clang': if os.environ.get('PM_clang_PATH') is not None: outString = outString + ' -DCMAKE_C_COMPILER=' + \ @@ -193,12 +191,13 @@ def getPlatformCMakeParams(self): outString = outString + ' -DPX_OUTPUT_ARCH=arm' if self.compiler == 'clang-crosscompile': outString = outString + ' -DCMAKE_TOOLCHAIN_FILE=' + \ - os.environ['PM_CMakeModules_PATH'] + \ - '/linux/LinuxCrossToolchain.aarch64-unknown-linux-gnueabihf.cmake' + cmake_modules_root + '/linux/LinuxCrossToolchain.aarch64-unknown-linux-gnueabihf.cmake' + outString = outString + ' -DCMAKE_MAKE_PROGRAM=' + os.environ.get('PM_MinGW_PATH') + '/bin/mingw32-make.exe' elif self.compiler == 'gcc': + # TODO: To change so it uses Packman's compiler. Then add it as + # host compiler for CUDA above. outString = outString + ' -DCMAKE_TOOLCHAIN_FILE=\"' + \ - os.environ['PM_CMakeModules_PATH'] + \ - '/linux/LinuxAarch64.cmake\"' + cmake_modules_root + '/linux/LinuxAarch64.cmake\"' return outString elif self.targetPlatform == 'mac64': outString = outString + ' -DTARGET_BUILD_PLATFORM=mac' @@ -232,7 +231,6 @@ def cleanupCompilerDir(compilerDirName): def presetProvided(pName): parsedPreset = CMakePreset(pName) - print('PM_CMakeModules_PATH: ' + os.environ['PM_CMakeModules_PATH']) print('PM_PATHS: ' + os.environ['PM_PATHS']) if os.environ.get('PM_cmake_PATH') is not None: @@ -284,6 +282,8 @@ def main(): if (sys.version_info[0] < 3) or (sys.version_info[0] == 3 and sys.version_info[1] < 5): print("You are using Python {}. You must use Python 3.5 and up. Please read README.md for requirements.").format(sys.version) exit() + physx_root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)) + os.environ['PHYSX_ROOT_DIR'] = physx_root_dir.replace("\\", "/") if len(sys.argv) != 2: presetName = noPresetProvided() if sys.platform == 'win32': @@ -293,7 +293,7 @@ def main(): # TODO: catch exception and add capture errors else: print('Running generate_projects.sh ' + presetName) - # TODO: once we have Python 3.7.2 for linux, add the text=True instead of universal_newlines + # TODO: once we have Python 3.7.2 for linux, add the text=True instead of universal_newlines cmd = './generate_projects.sh {}'.format(presetName) result = subprocess.run(['bash', './generate_projects.sh', presetName], cwd=os.environ['PHYSX_ROOT_DIR'], check=True, universal_newlines=True) # TODO: catch exception and add capture errors diff --git a/physx/buildtools/packman/bootstrap/download_file_from_url.ps1 b/physx/buildtools/packman/bootstrap/download_file_from_url.ps1 index 3b42d0d22..5a3e2ede8 100644 --- a/physx/buildtools/packman/bootstrap/download_file_from_url.ps1 +++ b/physx/buildtools/packman/bootstrap/download_file_from_url.ps1 @@ -40,210 +40,3 @@ do } } while ($triesLeft -gt 0) - -# SIG # Begin signature block -# MIImJAYJKoZIhvcNAQcCoIImFTCCJhECAQExDzANBglghkgBZQMEAgEFADB5Bgor -# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG -# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD4y8hiwdgKOguV -# zr8Ho7yrS5U2OygFWsyj22De5VrgoKCCDaUwggawMIIEmKADAgECAhAIrUCyYNKc -# TJ9ezam9k67ZMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK -# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV -# BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0z -# NjA0MjgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg -# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg -# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw -# ggIKAoICAQDVtC9C0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0 -# JAfhS0/TeEP0F9ce2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJr -# Q5qZ8sU7H/Lvy0daE6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhF -# LqGfLOEYwhrMxe6TSXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+F -# LEikVoQ11vkunKoAFdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh -# 3K3kGKDYwSNHR7OhD26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJ -# wZPt4bRc4G/rJvmM1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQay -# g9Rc9hUZTO1i4F4z8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbI -# YViY9XwCFjyDKK05huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchAp -# QfDVxW0mdmgRQRNYmtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRro -# OBl8ZhzNeDhFMJlP/2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IB -# WTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+ -# YXsIiGX0TkIwHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P -# AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAk -# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC -# hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v -# dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j -# b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAED -# MAgGBmeBDAEEATANBgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql -# +Eg08yy25nRm95RysQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFF -# UP2cvbaF4HZ+N3HLIvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1h -# mYFW9snjdufE5BtfQ/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3Ryw -# YFzzDaju4ImhvTnhOE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5Ubdld -# AhQfQDN8A+KVssIhdXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw -# 8MzK7/0pNVwfiThV9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnP -# LqR0kq3bPKSchh/jwVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatE -# QOON8BUozu3xGFYHKi8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bn -# KD+sEq6lLyJsQfmCXBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQji -# WQ1tygVQK+pKHJ6l/aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbq -# yK+p/pQd52MbOoZWeE4wggbtMIIE1aADAgECAhANckpaN1orAToeS2xgp8LlMA0G -# CSqGSIb3DQEBCwUAMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg -# SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcg -# UlNBNDA5NiBTSEEzODQgMjAyMSBDQTEwHhcNMjEwNzIzMDAwMDAwWhcNMjQwNzI0 -# MjM1OTU5WjByMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEUMBIG -# A1UEBxMLU2FudGEgQ2xhcmExGzAZBgNVBAoTEk5WSURJQSBDb3Jwb3JhdGlvbjEb -# MBkGA1UEAxMSTlZJRElBIENvcnBvcmF0aW9uMIIBojANBgkqhkiG9w0BAQEFAAOC -# AY8AMIIBigKCAYEA4pwm/KB/nb7mclAKy12ApOSezL0x/GYEFOseNUppsiY77ikb -# 9FVEXWsyQvwumf+W/f4t75pMuxQ8e5dRfcZm1CNVIDPGkp4GoKWYKiAtojfXI6gt -# +e+A50Y5GG+JeEjaQqD3D2MP/qo6RY+p9ql49tTM5Wl6hMVhbnEEC7x5ICbTw+4x -# rPSQuWnOHvyVtk6KGYjITQiQ2E6iCKcNw/kjm3pTyezjXKgg8nub168UX+aCApPd -# +mli/BUpvq/Q1B9V4V5wW1CpolCFcA2hLoAT3+W5WeQ0eDgb9u4/JTHppmU6sClU -# iU4M2iSTWSKnfcYUInfAcRGSElIxsMi5HLqLl5FoMfY+KqsJOp6rmsTuugpW9X1l -# ZrwZaf2zO0qsaLd9iZX8B2b7XVP+xYUQzy76B4r93f2BgqVJFecBE9B1Uw08//Cp -# bYqw3GECuDja/zZtTyIT4rPNspmt7MDk1aqUBglDye0e+pSXR8wGDJQyVNkGv3RU -# FnZJhEUswUmv/vjpAgMBAAGjggIGMIICAjAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG -# +/5hewiIZfROQjAdBgNVHQ4EFgQUaMbgHrrEPsNXuqa/8fzQom0cT/kwDgYDVR0P -# AQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMIG1BgNVHR8Ega0wgaowU6BR -# oE+GTWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENv -# ZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3JsMFOgUaBPhk1odHRwOi8v -# Y3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JT -# QTQwOTZTSEEzODQyMDIxQ0ExLmNybDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcG -# CCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgZQGCCsGAQUF -# BwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20w -# XAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2Vy -# dFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0MAwG -# A1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAJIUzsBmWmt5V/CKSjVdtuZR -# GrAD38g3dV4swTlEa1G68yIWiciPsI1a8g9O7TM9TCechCblzzUvjb02P5BuFYIM -# vtTKj0cN1Vt6GZu2Oexza+xf662tXPpUGdmkpdsmU8a7n7/4WWL6udpe2o0QMZiN -# jS644e8kq66RGyt0WbxA30Dlun9Nd75kl7uqDb7n8306nnq6ZxCFfVarVQ04yjg+ -# wbT/4/sO+m9e0IOm7Tgw7iBKGPu8G+PB5JnEHxFDFEoWh0MdtUCMMz/C6yYRBNfv -# 1h1cZyfi0P0ONoMQBrtkXI+KEcfKGXqIWPYUH8bqVwDSfzvWywNt4jvZvejjN855 -# YJZhUsoPSr7ed4NgOxxgGzUPNFIBj1nGzY9jMi3xOSN/Q7HxBmMy04+MtbBQKZo6 -# dyzz7JGea2DmHlm5ZEFlgTy7SRDbnLFW1U6jWw2BTPlY+ZA+xVQ0WRB+Nddz8g0O -# qaOvBQmLOwl7MrA7HRfCW/AvNO7vBU53cOpRYFNDE4Tidvd9WJgx14I7KBujaScL -# /YLRdUYdxLr5WRSYJXUikEnsT0hy0KXa7IqEH7crQvbi6CcQLCRlgbNm1GOrWDBn -# GmNh8HswhyguGdBAYmjfnfXnbKviF3ZmYZqZLA59rDj84OElqUEhQFC08prGVkec -# 0Jq+GLh/Ami1Pi7pkniyMYIX1TCCF9ECAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUG -# A1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQg -# RzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhANckpaN1or -# AToeS2xgp8LlMA0GCWCGSAFlAwQCAQUAoHwwEAYKKwYBBAGCNwIBDDECMAAwGQYJ -# KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB -# gjcCARUwLwYJKoZIhvcNAQkEMSIEINu1iKtrOAra8umuqk8Ws+fb/Pf4F6pgH+TN -# VzaObTvIMA0GCSqGSIb3DQEBAQUABIIBgIz2ciSp5mz1c5M1C2iXHaFckLK9iZtx -# fGbYkPWy1i6297JiN7GCf+CuUmG/+wNJb00No+RqvDuGwQEbjIcHYDnXVboFBjpD -# rdikf2LuAE7PI1vsVqourUSzii2m1/4ir1DB9nSNY8NSt8u0gnDLF/dGtfPEr3LK -# w0/Jz+4cxnciKMmWf0lWEV0Edkz1aXuZlP7Cf6auLRUGBpYoW+DHoYHF41KU6G3f -# 7tZvSgobbH9gCIxrIa6a/FcZ6CuqHuRPnQZUfwOuQCqAHlCRviLITOsrFf7y3G1q -# K+Ggp3xpEIKoGzvi19S1d+Q37rVUEmRXO3rBSX8seXtlI2CosIuINOCFPPuXrPuD -# MtvdTXT3obR0MwNSMfoxnuPAFphLAKqCsGQPT5QhGGHZxGb93359pUsBVlrHVFFs -# CKmSlU/wphImYo3+cMSITkrmag4HUOcTVxschCQTQnQlK9Xs5BzE6ppL2FOFUkZW -# Dg9fi7o04stiuDVl6SUnU/+MZKScz7ilqKGCFSswghUnBgorBgEEAYI3AwMBMYIV -# FzCCFRMGCSqGSIb3DQEHAqCCFQQwghUAAgEDMQ0wCwYJYIZIAWUDBAIBMIHzBgsq -# hkiG9w0BCRABBKCB4wSB4DCB3QIBAQYKYIZIAYb6bAoDBTAxMA0GCWCGSAFlAwQC -# AQUABCCrk4h7SAvmuYEBn1mnNwedI0mnA6GUB7XT7rH8pnUj3AIIcE808vz85ccY -# DzIwMjIxMTA4MTA1NTIwWjADAgEBoHmkdzB1MQswCQYDVQQGEwJDQTEQMA4GA1UE -# CBMHT250YXJpbzEPMA0GA1UEBxMGT3R0YXdhMRYwFAYDVQQKEw1FbnRydXN0LCBJ -# bmMuMSswKQYDVQQDEyJFbnRydXN0IFRpbWVzdGFtcCBBdXRob3JpdHkgLSBUU0Ex -# oIIPWDCCBCowggMSoAMCAQICBDhj3vgwDQYJKoZIhvcNAQEFBQAwgbQxFDASBgNV -# BAoTC0VudHJ1c3QubmV0MUAwPgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvQ1BTXzIw -# NDggaW5jb3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykg -# MTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBD -# ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAoMjA0OCkwHhcNOTkxMjI0MTc1MDUxWhcN -# MjkwNzI0MTQxNTEyWjCBtDEUMBIGA1UEChMLRW50cnVzdC5uZXQxQDA+BgNVBAsU -# N3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxpbWl0 -# cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQx -# MzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgy -# MDQ4KTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1NS6kShrLqoyAH -# FRZkKitL0b8LSk2O7YB2pWe3eEDAc0LIaMDbUyvdXrh2mDWTixqdfBM6Dh9btx7P -# 5SQUHrGBqY19uMxrSwPxAgzcq6VAJAB/dJShnQgps4gL9Yd3nVXN5MN+12pkq4UU -# hpVblzJQbz3IumYM4/y9uEnBdolJGf3AqL2Jo2cvxp+8cRlguC3pLMmQdmZ7lOKv -# eNZlU1081pyyzykD+S+kULLUSM4FMlWK/bJkTA7kmAd123/fuQhVYIUwKfl7SKRp -# huM1Px6GXXp6Fb3vAI4VIlQXAJAmk7wOSWiRv/hH052VQsEOTd9vJs/DGCFiZkNw -# 1tXAB+ECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w -# HQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMA0GCSqGSIb3DQEBBQUAA4IB -# AQA7m49WmzDnU5l8enmnTZfXGZWQ+wYfyjN8RmOPlmYk+kAbISfK5nJz8k/+MZn9 -# yAxMaFPGgIITmPq2rdpdPfHObvYVEZSCDO4/la8Rqw/XL94fA49XLB7Ju5oaRJXr -# GE+mH819VxAvmwQJWoS1btgdOuHWntFseV55HBTF49BMkztlPO3fPb6m5ZUaw7UZ -# w71eW7v/I+9oGcsSkydcAy1vMNAethqs3lr30aqoJ6b+eYHEeZkzV7oSsKngQmyT -# ylbe/m2ECwiLfo3q15ghxvPnPHkvXpzRTBWN4ewiN8yaQwuX3ICQjbNnm29ICBVW -# z7/xK3xemnbpWZDFfIM1EWVRMIIFEzCCA/ugAwIBAgIMWNoT/wAAAABRzg33MA0G -# CSqGSIb3DQEBCwUAMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3 -# d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRz -# IGxpYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEz -# MDEGA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIw -# NDgpMB4XDTE1MDcyMjE5MDI1NFoXDTI5MDYyMjE5MzI1NFowgbIxCzAJBgNVBAYT -# AlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVu -# dHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0 -# LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJjAkBgNVBAMTHUVudHJ1 -# c3QgVGltZXN0YW1waW5nIENBIC0gVFMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -# MIIBCgKCAQEA2SPmFKTofEuFcVj7+IHmcotdRsOIAB840Irh1m5WMOWv2mRQfcIT -# Ofu9ZrTahPuD0Cgfy3boYFBpm/POTxPiwT7B3xLLMqP4XkQiDsw66Y1JuWB0yN5U -# PUFeQ18oRqmmt8oQKyK8W01bjBdlEob9LHfVxaCMysKD4EdXfOdwrmJFJzEYCtTA -# pBhVUvdgxgRLs91oMm4QHzQRuBJ4ZPHuqeD347EijzRaZcuK9OFFUHTfk5emNObQ -# TDufN0lSp1NOny5nXO2W/KW/dFGI46qOvdmxL19QMBb0UWAia5nL/+FUO7n7RDil -# CDkjm2lH+jzE0Oeq30ay7PKKGawpsjiVdQIDAQABo4IBIzCCAR8wEgYDVR0TAQH/ -# BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOwYDVR0gBDQwMjAwBgRVHSAAMCgw -# JgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuZW50cnVzdC5uZXQvcnBhMDMGCCsGAQUF -# BwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZW50cnVzdC5uZXQwMgYD -# VR0fBCswKTAnoCWgI4YhaHR0cDovL2NybC5lbnRydXN0Lm5ldC8yMDQ4Y2EuY3Js -# MBMGA1UdJQQMMAoGCCsGAQUFBwMIMB0GA1UdDgQWBBTDwnHSe9doBa47OZs0JQxi -# A8dXaDAfBgNVHSMEGDAWgBRV5IHREYC+2Im5CKMx+aEkCRa5cDANBgkqhkiG9w0B -# AQsFAAOCAQEAHSTnmnRbqnD8sQ4xRdcsAH9mOiugmjSqrGNtifmf3w13/SQj/E+c -# t2+P8/QftsH91hzEjIhmwWONuld307gaHshRrcxgNhqHaijqEWXezDwsjHS36FBD -# 08wo6BVsESqfFJUpyQVXtWc26Dypg+9BwSEW0373LRFHZnZgghJpjHZVcw/fL0td -# 6Wwj+Af2tX3WaUWcWH1hLvx4S0NOiZFGRCygU6hFofYWWLuRE/JLxd8LwOeuKXq9 -# RbPncDDnNI7revbTtdHeaxOZRrOL0k2TdbXxb7/cACjCJb+856NlNOw/DR2XjPqq -# iCKkGDXbBY524xDIKY9j0K6sGNnaxJ9REjCCBg8wggT3oAMCAQICEFarlXUonKWf -# DhfUC+oFwx8wDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK -# Ew1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xl -# Z2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9y -# IGF1dGhvcml6ZWQgdXNlIG9ubHkxJjAkBgNVBAMTHUVudHJ1c3QgVGltZXN0YW1w -# aW5nIENBIC0gVFMxMB4XDTIyMTAwNDE3MjEwM1oXDTI5MDEwMTAwMDAwMFowdTEL -# MAkGA1UEBhMCQ0ExEDAOBgNVBAgTB09udGFyaW8xDzANBgNVBAcTBk90dGF3YTEW -# MBQGA1UEChMNRW50cnVzdCwgSW5jLjErMCkGA1UEAxMiRW50cnVzdCBUaW1lc3Rh -# bXAgQXV0aG9yaXR5IC0gVFNBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -# ggIBAMHqoyWORTQXyvWzxRnMCLMLE06gcvbupHZQWA9G2BfpuHdUaYBxuopfWGc+ -# Z1jvTlDN+sbZbhMzj63Drkb2Z05tQzeLid34F53T0un5YkP+pKRU6cq3muBKKvli -# EdCtZ1xY/hpMSWpfFh+0ZZQeEBaUm3ft850bUl8ZGXXb7s9nWa3LLkpjDrGCd1pv -# Y03ouCLsLwrbTJslnoMrZBm2t3Slw7pMDU2vA+YWbeTwGLOjZ8VXrO6zL69+fCuG -# em2yydoUUjK2MVAm6vZPMAqpOBXDqop0SC9Gd/8FhMin5GCF+bzZhiCqDNypoz/8 -# k5RLlazbVLWvw/19LkHjoyCGUEVB1C42MSj2Ci/3wTrNBhQ++qdJwVRKusB+50kH -# hEpcma5nAgRIqbTlxR3tjx2xPyTCBwdiHEvFNulU6otrnXRL+qoBJydPuvp9J83t -# Zo0neBcOvIdzzm19yY6WOKJLFexXQHimwIHZyQNs2+Mv8cqCq0B9rJpwGuLfPptY -# ZCtrbw9oHiVnPnrdAb5jlFHTWoR0so8p2i8kurbPbkvNDb+B3pG3NeaShS0DwZ8U -# wsVc33koOgh4Y+4hqzJ1gN/1BA7fRtzGqbOazXbbc1cfDA0w/W91CbyfizO78GQ8 -# /LndYoOyvJeslzHoOcXMsku/l2SY3S4q/sQn8FcVTVFPhK0DAgMBAAGjggFbMIIB -# VzAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBRKDtGm6oLNjldj7P2+AzdAkCSj2DAf -# BgNVHSMEGDAWgBTDwnHSe9doBa47OZs0JQxiA8dXaDBoBggrBgEFBQcBAQRcMFow -# IwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLmVudHJ1c3QubmV0MDMGCCsGAQUFBzAC -# hidodHRwOi8vYWlhLmVudHJ1c3QubmV0L3RzMS1jaGFpbjI1Ni5jZXIwMQYDVR0f -# BCowKDAmoCSgIoYgaHR0cDovL2NybC5lbnRydXN0Lm5ldC90czFjYS5jcmwwDgYD -# VR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMEIGA1UdIAQ7MDkw -# NwYKYIZIAYb6bAoBBzApMCcGCCsGAQUFBwIBFhtodHRwczovL3d3dy5lbnRydXN0 -# Lm5ldC9ycGEwDQYJKoZIhvcNAQELBQADggEBALHAWjNiHGozMuYkMD5vxuawUjQd -# qUg7Bw3ukGTEqsqtexpHb4H3zzHEwvoGKLkXvC6EDtJHNf6ueOdjFeDaJQSxY9ML -# w+ujjEEpEeXqmO7I3cUV9sdUGv5Ujbso9gUbBIKoM4aWyI+0wiAFRAsCW6MmWuxM -# tGm+2PxARF3Fx0FuPze1eBPmlRTt3s7KhLPQ288roPzus/6IAF+msHnZmg8/XZfl -# n0IPHOfvsOmvcw24eZoCV5prbEsUKs6uVabPseuxoWDebdwvJlPhPXMusQiccocp -# yIVQiMzqXwickHqqyrCb6upAM+IiFdLRd36/GJgivr3ySD/MAtLStuubSaQxggSY -# MIIElAIBATCBxzCBsjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIElu -# Yy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3 -# BgNVBAsTMChjKSAyMDE1IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1 -# c2Ugb25seTEmMCQGA1UEAxMdRW50cnVzdCBUaW1lc3RhbXBpbmcgQ0EgLSBUUzEC -# EFarlXUonKWfDhfUC+oFwx8wCwYJYIZIAWUDBAIBoIIBpTAaBgkqhkiG9w0BCQMx -# DQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIyMTEwODEwNTUyMFowKQYJ -# KoZIhvcNAQk0MRwwGjALBglghkgBZQMEAgGhCwYJKoZIhvcNAQELMC8GCSqGSIb3 -# DQEJBDEiBCCRjNVJ9BjASZpksby7TM3QxFGNg8moHC8Ncz444B6iVzCCAQsGCyqG -# SIb3DQEJEAIvMYH7MIH4MIH1MIHyBCDuYRmrup3Fu4wsgb75vu6ODiX92F6z8aY1 -# NSaB2baLrzCBzTCBuKSBtTCBsjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1 -# c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy -# bXMxOTA3BgNVBAsTMChjKSAyMDE1IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9y -# aXplZCB1c2Ugb25seTEmMCQGA1UEAxMdRW50cnVzdCBUaW1lc3RhbXBpbmcgQ0Eg -# LSBUUzECEFarlXUonKWfDhfUC+oFwx8wCwYJKoZIhvcNAQELBIICAIApOh7mxxvB -# wytMv4ABENOzE049DgFMEVJf1mjcpa7adWr/bnva91tcL9tQBo+Sja2/qmhGsHcb -# F+u7CY9MuvT7noYRaF9DQ0nDXV2kL4VtTYW/UDgbj2B93Lor2imSiiQTtUrcjtRq -# 4Q/IQJIJFXpwS/Kxq5S5vNhll2Lrd4qR3mt3GajSqd6hPLhp0UZ1GQ9mWpOOaZ0+ -# oqQOJZ81KQG264q2s1k11JF3KBUcJ5ryWXwwqFPp5p+k0bEG50wGtMmBi3tAIMEd -# Cqy1UYPoz3fmH6odOJ8gyjkLnNZ1z6X04/zDkCZxR6O3JfTceqRckO9HlDFqGMdL -# Lpl1vYhwlQpAtIGPSBWxyUjQP6aCraehp4WDwwfi+1ReKXhWX/ex00LCSZDzbWOC -# XZWtQsSG717TJH2r7N7enzvD1nqxClcJ0imAhHJN00lwjzq1Sky56Hdog7FKEXSi -# SRmPvFI68WDUdzj+JxcUq6ZWl7z5DXpwVaFnG3Bi7vXud4BnFicKMHyWPMdo5BJ9 -# EqaT9IBxqPZyFy8Qy58oeiJneVTszJ0IfhYLKuTcGG063KQD/FQQ5jnMAlufgwlA -# kPpYqJvCO0bzBVOrHh7pYx2MCrDIma06b2UDFKqLKyTDSNFSN0QvCxWdmGIquzYj -# 7RWYJ3B+iibc278eUkQB8AukJ8RdjOS5 -# SIG # End signature block diff --git a/physx/buildtools/packman/bootstrap/fetch_file_from_packman_bootstrap.cmd b/physx/buildtools/packman/bootstrap/fetch_file_from_packman_bootstrap.cmd index d9b732afa..4339bdc34 100644 --- a/physx/buildtools/packman/bootstrap/fetch_file_from_packman_bootstrap.cmd +++ b/physx/buildtools/packman/bootstrap/fetch_file_from_packman_bootstrap.cmd @@ -20,7 +20,7 @@ @echo Fetching %PACKAGE_NAME% ... @powershell -ExecutionPolicy ByPass -NoLogo -NoProfile -File "%~dp0download_file_from_url.ps1" ^ - -source "https://bootstrap.packman.nvidia.com/%PACKAGE_NAME%" -output %TARGET_PATH% + -source "http://bootstrap.packman.nvidia.com/%PACKAGE_NAME%" -output %TARGET_PATH% :: A bug in powershell prevents the errorlevel code from being set when using the -File execution option :: We must therefore do our own failure analysis, basically make sure the file exists and is larger than 0 bytes: @if not exist %TARGET_PATH% goto ERROR_DOWNLOAD_FAILED diff --git a/physx/buildtools/packman/packman b/physx/buildtools/packman/packman index ac13e801a..f481b87fe 100755 --- a/physx/buildtools/packman/packman +++ b/physx/buildtools/packman/packman @@ -62,7 +62,7 @@ fi fetch_file_from_s3() { SOURCE=$1 - SOURCE_URL=https://bootstrap.packman.nvidia.com/$SOURCE + SOURCE_URL=http://bootstrap.packman.nvidia.com/$SOURCE TARGET=$2 echo "Fetching $SOURCE from bootstrap.packman.nvidia.com ..." if command -v wget >/dev/null 2>&1; then diff --git a/physx/compiler/public/CMakeLists.txt b/physx/compiler/public/CMakeLists.txt index 73c316852..7895a8f6e 100644 --- a/physx/compiler/public/CMakeLists.txt +++ b/physx/compiler/public/CMakeLists.txt @@ -24,11 +24,7 @@ ## ## Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. -IF(TARGET_BUILD_PLATFORM STREQUAL "mac") - cmake_minimum_required(VERSION 3.12) -ELSE() - cmake_minimum_required(VERSION 3.11) -ENDIF() +cmake_minimum_required(VERSION 3.7) project(PhysXSDK C CXX) @@ -36,14 +32,12 @@ OPTION(PX_BUILDSNIPPETS "Generate the snippets" OFF) OPTION(PX_BUILDPVDRUNTIME "Generate the OmniPVD project" OFF) OPTION(PX_CMAKE_SUPPRESS_REGENERATION "Disable zero_check projects" OFF) -IF(NOT DEFINED CMAKEMODULES_VERSION) - SET(CMAKEMODULES_PATH $ENV{PM_CMakeModules_PATH} CACHE INTERNAL "Path to CMakeModules") - SET(CMAKEMODULES_NAME "CMakeModules" CACHE INTERNAL "CMakeModules name") - SET(CMAKEMODULES_VERSION "1.27" CACHE INTERNAL "CMakeModules version from generation batch") +IF(DEFINED ENV{PM_cmake_PATH} AND NOT "$ENV{PM_cmake_PATH}" STREQUAL "") + SET(CMAKEMODULES_PATH "$ENV{PM_cmake_PATH}/share/cmake-3.25/Modules") ENDIF() -SET(CMAKE_MODULE_PATH ${CMAKEMODULES_PATH}) - +LIST(APPEND CMAKEMODULES_PATH ${PHYSX_ROOT_DIR}/source/compiler/cmake/modules) +SET(CMAKE_MODULE_PATH ${CMAKEMODULES_PATH} CACHE INTERNAL "Path to CMakeModules") IF(PX_CMAKE_SUPPRESS_REGENERATION) SET(CMAKE_SUPPRESS_REGENERATION true) @@ -89,6 +83,6 @@ ENDIF() IF(TARGET_BUILD_PLATFORM STREQUAL "switch") - FILE(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ALL_BUILD.vcxproj.user" INPUT "${CMAKE_MODULE_PATH}/switch/Microsoft.Cpp.${NX_TARGET_DEVKIT}.user.props" CONDITION 1) - FILE(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/INSTALL.vcxproj.user" INPUT "${CMAKE_MODULE_PATH}/switch/Microsoft.Cpp.${NX_TARGET_DEVKIT}.user.props" CONDITION 1) + FILE(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/ALL_BUILD.vcxproj.user" INPUT "${PHYSX_ROOT_DIR}/source/compiler/cmake/modules/switch/Microsoft.Cpp.${NX_TARGET_DEVKIT}.user.props" CONDITION 1) + FILE(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/INSTALL.vcxproj.user" INPUT "${PHYSX_ROOT_DIR}/source/compiler/cmake/modules/switch/Microsoft.Cpp.${NX_TARGET_DEVKIT}.user.props" CONDITION 1) ENDIF() \ No newline at end of file diff --git a/physx/dependencies.xml b/physx/dependencies.xml index b92483f8e..9e6a833e5 100644 --- a/physx/dependencies.xml +++ b/physx/dependencies.xml @@ -1,26 +1,22 @@ - - - - - + - + - + - + diff --git a/physx/documentation/platformreadme/linux/README_LINUX.md b/physx/documentation/platformreadme/linux/README_LINUX.md index 44b27506d..9ed91a849 100644 --- a/physx/documentation/platformreadme/linux/README_LINUX.md +++ b/physx/documentation/platformreadme/linux/README_LINUX.md @@ -35,7 +35,7 @@ Compilers: ## PhysX GPU Acceleration: -* Requires CUDA 11.0 compatible display driver and CUDA ARCH 3.0 compatible GPU +* Requires CUDA 11.8 compatible display driver. The corresponding driver version can be found [here](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions__table-cuda-toolkit-driver-versions). ## Required Packages for Building and Running PhysX Snippets: diff --git a/physx/documentation/platformreadme/windows/README_WINDOWS.md b/physx/documentation/platformreadme/windows/README_WINDOWS.md index 0d48eb88d..fe62cc999 100644 --- a/physx/documentation/platformreadme/windows/README_WINDOWS.md +++ b/physx/documentation/platformreadme/windows/README_WINDOWS.md @@ -7,12 +7,13 @@ ## Required packages to generate projects: +* Windows OS + headers for at least Win7 (`_WIN32_WINNT = 0x0601`) * CMake, minimum version 3.21 * Python, minimum version 3.5 ## PhysX GPU Acceleration: -* Requires CUDA 11.0 compatible display driver and CUDA ARCH 3.0 compatible GPU +* Requires CUDA 11.8 compatible display driver. The corresponding driver version can be found [here](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions__table-cuda-toolkit-driver-versions). ## Generating solutions for Visual Studio: diff --git a/physx/generate_projects.bat b/physx/generate_projects.bat index 338f7cdb2..fb7ba5ead 100644 --- a/physx/generate_projects.bat +++ b/physx/generate_projects.bat @@ -2,12 +2,7 @@ @call :CLEAN_EXIT @echo off -pushd %~dp0 -set PHYSX_ROOT_DIR=%CD% -popd -SET PHYSX_ROOT_DIR=%PHYSX_ROOT_DIR:\=/% - -call "%PHYSX_ROOT_DIR%\buildtools\packman\packman" init +call "%~dp0\buildtools\packman\packman" init set "PYTHONPATH=%PM_MODULE_DIR%;%PYTHONPATH%" IF %1.==. GOTO ADDITIONAL_PARAMS_MISSING @@ -73,7 +68,7 @@ if exist "%Install2022Dir%\VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.t ) :ADDITIONAL_PARAMS_MISSING -call "%~dp0buildtools\packman\python" %PHYSX_ROOT_DIR%/buildtools/cmake_generate_projects.py %1 +call "%~dp0buildtools\packman\python" "%~dp0buildtools\cmake_generate_projects.py" %1 if %ERRORLEVEL% neq 0 ( set /p DUMMY=Hit ENTER to continue... exit /b %errorlevel% diff --git a/physx/generate_projects.sh b/physx/generate_projects.sh index 31b828240..d037378cc 100755 --- a/physx/generate_projects.sh +++ b/physx/generate_projects.sh @@ -1,15 +1,19 @@ #!/bin/bash +x -export PHYSX_ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +if [ -n "${BASH_SOURCE[0]}" ]; then + SCRIPT_DIR=$(dirname "${BASH_SOURCE[0]}") +else + SCRIPT_DIR=$(dirname "$0") +fi -PACKMAN_CMD="$PHYSX_ROOT_DIR/buildtools/packman/packman" +PACKMAN_CMD="$SCRIPT_DIR/buildtools/packman/packman" if [ ! -f "$PACKMAN_CMD" ]; then PACKMAN_CMD="${PACKMAN_CMD}.sh" fi source "$PACKMAN_CMD" init if [[ $# -eq 0 ]] ; then - exec "$PHYSX_ROOT_DIR/buildtools/packman/python.sh" "$PHYSX_ROOT_DIR/buildtools/cmake_generate_projects.py" + exec "$SCRIPT_DIR/buildtools/packman/python.sh" "$SCRIPT_DIR/buildtools/cmake_generate_projects.py" exit 1 fi @@ -18,11 +22,11 @@ cutName=${1%%.*} export targetPlatform=$1 if [ "$1" = "$cutName" ] ; then - source "$PACKMAN_CMD" pull "$PHYSX_ROOT_DIR/dependencies.xml" --platform $1 - exec "$PHYSX_ROOT_DIR/buildtools/packman/python.sh" "$PHYSX_ROOT_DIR/buildtools/cmake_generate_projects.py" "$targetPlatform" + source "$PACKMAN_CMD" pull "$SCRIPT_DIR/dependencies.xml" --platform $1 + exec "$SCRIPT_DIR/buildtools/packman/python.sh" "$SCRIPT_DIR/buildtools/cmake_generate_projects.py" "$targetPlatform" else - source "$PACKMAN_CMD" pull "$PHYSX_ROOT_DIR/dependencies.xml" --platform $cutName - exec "$PHYSX_ROOT_DIR/buildtools/packman/python.sh" "$PHYSX_ROOT_DIR/buildtools/cmake_generate_projects.py" "$targetPlatform" + source "$PACKMAN_CMD" pull "$SCRIPT_DIR/dependencies.xml" --platform $cutName + exec "$SCRIPT_DIR/buildtools/packman/python.sh" "$SCRIPT_DIR/buildtools/cmake_generate_projects.py" "$targetPlatform" fi status=$? diff --git a/physx/include/PxActor.h b/physx/include/PxActor.h index cb884ed69..80cd3952e 100644 --- a/physx/include/PxActor.h +++ b/physx/include/PxActor.h @@ -170,13 +170,6 @@ struct PxActorType */ eMPM_PARTICLESYSTEM, - /** - \brief A CUSTOM ParticleSystem - \note In development - @see PxCUSTOMParticleSystem - */ - eCUSTOM_PARTICLESYSTEM, - /** \brief A HairSystem \note In development diff --git a/physx/include/PxAggregate.h b/physx/include/PxAggregate.h index 5a1cd1d43..8e171479c 100644 --- a/physx/include/PxAggregate.h +++ b/physx/include/PxAggregate.h @@ -186,15 +186,11 @@ class PxAggregate : public PxBase /** \brief Retrieves max amount of actors that can be contained in the aggregate. - \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; + virtual PxU32 getMaxNbActors() const = 0; /** \brief Retrieves max amount of shapes that can be contained in the aggregate. diff --git a/physx/include/PxAnisotropy.h b/physx/include/PxAnisotropy.h new file mode 100644 index 000000000..35411be55 --- /dev/null +++ b/physx/include/PxAnisotropy.h @@ -0,0 +1,222 @@ +// 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_ANISOTROPY_H +#define PX_ANISOTROPY_H +/** \addtogroup extensions + @{ +*/ + + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" +#include "PxParticleSystem.h" + +#include "foundation/PxArray.h" +#include "PxParticleGpu.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + class PxgKernelLauncher; + class PxParticleNeighborhoodProvider; + + /** + \brief Computes anisotropy information for a particle system to improve rendering quality + */ + class PxAnisotropyGenerator + { + public: + /** + \brief Schedules the compuation of anisotropy information on the specified cuda stream + + \param[in] gpuParticleSystem A gpu pointer to access particle system data + \param[in] numParticles The number of particles + \param[in] stream The stream on which the cuda call gets scheduled + */ + virtual void generateAnisotropy(PxGpuParticleSystem* gpuParticleSystem, PxU32 numParticles, CUstream stream) = 0; + + /** + \brief Schedules the compuation of anisotropy information on the specified cuda stream + + \param[in] particlePositionsGpu A gpu pointer containing the particle positions + \param[in] neighborhoodProvider A neighborhood provider object that supports fast neighborhood queries + \param[in] numParticles The number of particles + \param[in] particleContactOffset The particle contact offset + \param[in] stream The stream on which the cuda call gets scheduled + */ + virtual void generateAnisotropy(PxVec4* particlePositionsGpu, PxParticleNeighborhoodProvider& neighborhoodProvider, PxU32 numParticles, PxReal particleContactOffset, CUstream stream) = 0; + + /** + \brief Set a host buffer that holds the anisotropy data after the timestep completed + + \param[in] anisotropy1 A host buffer holding the first row of the anisotropy matrix with memory for all particles already allocated + \param[in] anisotropy2 A host buffer holding the second row of the anisotropy matrix with memory for all particles already allocated + \param[in] anisotropy3 A host buffer holding the third row of the anisotropy matrix with memory for all particles already allocated + */ + virtual void setResultBufferHost(PxVec4* anisotropy1, PxVec4* anisotropy2, PxVec4* anisotropy3) = 0; + + /** + \brief Set a device buffer that holds the anisotrpy data after the timestep completed + + \param[in] anisotropy1 A device buffer holding the first row of the anisotropy matrix with memory for all particles already allocated + \param[in] anisotropy2 A device buffer holding the second row of the anisotropy matrix with memory for all particles already allocated + \param[in] anisotropy3 A device buffer holding the third row of the anisotropy matrix with memory for all particles already allocated + */ + virtual void setResultBufferDevice(PxVec4* anisotropy1, PxVec4* anisotropy2, PxVec4* anisotropy3) = 0; + + /** + \brief Sets the maximum value anisotropy can reach in any direction + + \param[in] maxAnisotropy The maximum anisotropy value + */ + virtual void setAnisotropyMax(float maxAnisotropy) = 0; + + /** + \brief Sets the minimum value anisotropy can reach in any direction + + \param[in] minAnisotropy The minimum anisotropy value + */ + virtual void setAnisotropyMin(float minAnisotropy) = 0; + + /** + \brief Sets the anisotropy scale + + \param[in] anisotropyScale The anisotropy scale + */ + virtual void setAnisotropyScale(float anisotropyScale) = 0; + + /** + \brief Gets the maximal number of particles + + \return The maximal number of particles + */ + virtual PxU32 getMaxParticles() const = 0; + + /** + \brief Sets the maximal number of particles + + \param[in] maxParticles The maximal number of particles + */ + virtual void setMaxParticles(PxU32 maxParticles) = 0; + + /** + \brief Gets the device pointer for the anisotropy in x direction. Only available after calling setResultBufferHost or setResultBufferDevice + + \return The device pointer for the anisotropy x direction and scale (w component contains the scale) + */ + virtual PxVec4* getAnisotropy1DevicePointer() const = 0; + + /** + \brief Gets the device pointer for the anisotropy in y direction. Only available after calling setResultBufferHost or setResultBufferDevice + + \return The device pointer for the anisotropy y direction and scale (w component contains the scale) + */ + virtual PxVec4* getAnisotropy2DevicePointer() const = 0; + + /** + \brief Gets the device pointer for the anisotropy in z direction. Only available after calling setResultBufferHost or setResultBufferDevice + + \return The device pointer for the anisotropy z direction and scale (w component contains the scale) + */ + virtual PxVec4* getAnisotropy3DevicePointer() const = 0; + + /** + \brief Enables or disables the anisotropy generator + + \param[in] enabled The boolean to set the generator to enabled or disabled + */ + virtual void setEnabled(bool enabled) = 0; + + /** + \brief Allows to query if the anisotropy generator is enabled + + \return True if enabled, false otherwise + */ + virtual bool isEnabled() const = 0; + + /** + \brief Releases the instance and its data + */ + virtual void release() = 0; + + /** + \brief Destructor + */ + virtual ~PxAnisotropyGenerator() {} + }; + + /** + \brief Default implementation of a particle system callback to trigger anisotropy calculations. A call to fetchResultsParticleSystem() on the + PxScene will synchronize the work such that the caller knows that the post solve task completed. + */ + class PxAnisotropyCallback : public PxParticleSystemCallback + { + public: + /** + \brief Initializes the anisotropy callback + + \param[in] anistropyGenerator The anisotropy generator + */ + void initialize(PxAnisotropyGenerator* anistropyGenerator) + { + mAnistropyGenerator = anistropyGenerator; + } + + virtual void onPostSolve(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) + { + if (mAnistropyGenerator) + { + mAnistropyGenerator->generateAnisotropy(gpuParticleSystem.mDevicePtr, gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream); + } + } + + virtual void onBegin(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + virtual void onAdvance(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + private: + PxAnisotropyGenerator* mAnistropyGenerator; + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/physx/include/PxArrayConverter.h b/physx/include/PxArrayConverter.h new file mode 100644 index 000000000..b31215496 --- /dev/null +++ b/physx/include/PxArrayConverter.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. + +#ifndef PX_ARRAY_CONVERTER_H +#define PX_ARRAY_CONVERTER_H + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + /** + \brief Utility class to convert gpu arrays to a different memory layout + */ + class PxArrayConverter + { + public: + /** + \brief Helper function to merge two separate PxVec4 arrays into one interleaved PxVec3 array + \param[in] verticesD The vertices device memory buffer + \param[in] normalsD The normals device memory buffer + \param[in] length The number of vertices and normals + \param[out] interleavedResultBufferD The resulting interleaved buffer containing 2*length elements with the format vertex0, normal0, vertex1, normal1... + \param[in] stream The cuda stream on which the conversion is processed + */ + virtual void interleaveGpuBuffers(const PxVec4* verticesD, const PxVec4* normalsD, PxU32 length, PxVec3* interleavedResultBufferD, CUstream stream) = 0; + + /** + \brief Helper function to convert the hair system's strand representation to a line list. The conversion is done on the GPU. + \param[in] verticesD The strand vertices device memory buffer + \param[in] numVertices The total number of vertices + \param[in] strandPastEndIndicesD One index per strand (device memory array) to find out where the next strand starts + \param[in] numStrands the number of strands + \param[out] resultD A device memory buffer with 2*numVertices capacity describing line segment where line i extends from result[2*i] to result[2*i+1] + \param[in] stream The cuda stream on which the conversion is processed + */ + virtual void extractLinesFromStrands(const PxVec4* verticesD, PxU32 numVertices, const PxU32* strandPastEndIndicesD, + PxU32 numStrands, PxVec4* resultD, CUstream stream) = 0; + + /** + \brief Helper function to convert the hair system's strand representation to a line list. The conversion is done on the GPU. + \param[in] verticesD The strand vertices device memory buffer + \param[in] numVertices The total number of vertices + \param[in] strandPastEndIndicesD One index per strand (device memory array) to find out where the next strand starts + \param[in] numStrands the number of strands + \param[out] resultD A device memory buffer with 2*numVertices capacity describing line segment where line i extends from result[2*i] to result[2*i+1] + \param[in] stream The cuda stream on which the conversion is processed + */ + virtual void extractLinesFromStrands(const PxVec3* verticesD, PxU32 numVertices, const PxU32* strandPastEndIndicesD, + PxU32 numStrands, PxVec3* resultD, CUstream stream) = 0; + + /** + \brief Destructor + */ + virtual ~PxArrayConverter() {} + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/physx/include/PxArticulationFlag.h b/physx/include/PxArticulationFlag.h index 75870439d..0b4f74dcd 100644 --- a/physx/include/PxArticulationFlag.h +++ b/physx/include/PxArticulationFlag.h @@ -54,14 +54,16 @@ namespace physx 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_SOLVER_FORCE, //!< @deprecated 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() + eSENSOR_FORCE, //!< @deprecated 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_ACCELERATION, //!< The link accelerations including root link, read only, see PxScene::copyArticulationData() + eLINK_INCOMING_JOINT_FORCE, //!< The link incoming jont forces 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() @@ -82,16 +84,17 @@ namespace physx 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. + 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), //!< @deprecated The spatial sensor forces, see PxArticulationCache::sensorForces. + eJOINT_SOLVER_FORCES = (1 << 9), //!< @deprecated Solver constraint joint forces, see PxArticulationCache::jointSolverForces. + eLINK_INCOMING_JOINT_FORCE = (1 << 10), //!< Link incoming joint forces, see PxArticulationCache::linkIncomingJointForce. eALL = (eVELOCITY | eACCELERATION | ePOSITION | eLINK_VELOCITY | eLINK_ACCELERATION | eROOT_TRANSFORM | eROOT_VELOCITIES) }; }; diff --git a/physx/include/PxArticulationJointReducedCoordinate.h b/physx/include/PxArticulationJointReducedCoordinate.h index 4043f7464..db7a6a9aa 100644 --- a/physx/include/PxArticulationJointReducedCoordinate.h +++ b/physx/include/PxArticulationJointReducedCoordinate.h @@ -111,7 +111,9 @@ namespace physx \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. + In order to amend the joint type, remove and then re-add the articulation to the scene. + + Default: PxArticulationJointType::eUNDEFINED @see PxArticulationJointType, getJointType */ @@ -134,6 +136,8 @@ namespace physx \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. + + Default: PxArticulationMotion::eLOCKED @see PxArticulationAxis, PxArticulationMotion, getMotion */ @@ -153,50 +157,6 @@ namespace physx /** \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. @@ -206,7 +166,12 @@ namespace physx \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]. + \note For PxArticulationJointType::eSPHERICAL, limit.min and limit.max must both be in range [-Pi, Pi]. + \note For PxArticulationJointType::eREVOLUTE, limit.min and limit.max must both be in range [-2*Pi, 2*Pi]. + \note For PxArticulationJointType::eREVOLUTE_UNWRAPPED, limit.min and limit.max must both be in range [-PX_MAX_REAL, PX_MAX_REAL]. + \note For PxArticulationJointType::ePRISMATIC, limit.min and limit.max must both be in range [-PX_MAX_REAL, PX_MAX_REAL]. + + Default: (0,0) @see getLimitParams, PxArticulationAxis, PxArticulationLimit */ @@ -228,62 +193,14 @@ namespace physx 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 + + Default: PxArticulationDrive(0.0f, 0.0f, 0.0f, PxArticulationDriveType::eNONE) */ virtual void setDriveParams(PxArticulationAxis::Enum axis, const PxArticulationDrive& drive) = 0; @@ -316,6 +233,8 @@ namespace physx \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 + + Default: 0.0 */ virtual void setDriveTarget(PxArticulationAxis::Enum axis, const PxReal target, bool autowake = true) = 0; @@ -343,6 +262,8 @@ namespace physx \note This call is not allowed while the simulation is running. @see PxArticulationAxis, getDriveVelocity + + Default: 0.0 */ virtual void setDriveVelocity(PxArticulationAxis::Enum axis, const PxReal targetVel, bool autowake = true) = 0; @@ -369,6 +290,8 @@ namespace physx \note This call is not allowed while the simulation is running. @see PxArticulationAxis, getArmature + + Default: 0.0 */ virtual void setArmature(PxArticulationAxis::Enum axis, const PxReal armature) = 0; @@ -396,6 +319,8 @@ namespace physx \note This call is not allowed while the simulation is running. @see getFrictionCoefficient + + Default: 0.05 */ virtual void setFrictionCoefficient(const PxReal coefficient) = 0; @@ -419,6 +344,8 @@ namespace physx \note This call is not allowed while the simulation is running. @see getMaxJointVelocity + + Default: 100.0 */ virtual void setMaxJointVelocity(const PxReal maxJointV) = 0; @@ -443,13 +370,18 @@ namespace physx \note This call is not allowed while the simulation is running. - \note For spherical joints, jointPos must be in range [-Pi, Pi]. + \note For PxArticulationJointType::eSPHERICAL, jointPos must be in range [-Pi, Pi]. + \note For PxArticulationJointType::eREVOLUTE, jointPos must be in range [-2*Pi, 2*Pi]. + \note For PxArticulationJointType::eREVOLUTE_UNWRAPPED, jointPos must be in range [-PX_MAX_REAL, PX_MAX_REAL]. + \note For PxArticulationJointType::ePRISMATIC, jointPos must be in range [-PX_MAX_REAL, PX_MAX_REAL]. \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 + + Default: 0.0 */ virtual void setJointPosition(PxArticulationAxis::Enum axis, const PxReal jointPos) = 0; @@ -482,6 +414,8 @@ namespace physx \note This call is not allowed while the simulation is running. @see PxArticulationAxis, getJointVelocity, PxArticulationCache::jointVelocity, PxArticulationReducedCoordinate::updateKinematic + + Default: 0.0 */ virtual void setJointVelocity(PxArticulationAxis::Enum axis, const PxReal jointVel) = 0; diff --git a/physx/include/PxArticulationReducedCoordinate.h b/physx/include/PxArticulationReducedCoordinate.h index c107dbd33..08ef512db 100644 --- a/physx/include/PxArticulationReducedCoordinate.h +++ b/physx/include/PxArticulationReducedCoordinate.h @@ -109,6 +109,7 @@ namespace physx jointSolverForces (NULL), linkVelocity (NULL), linkAcceleration (NULL), + linkIncomingJointForce(NULL), rootLinkData (NULL), sensorForces (NULL), coefficientMatrix (NULL), @@ -206,6 +207,8 @@ namespace physx PxReal* jointForce; /** + @deprecated Use linkIncomingJointForce instead. + \brief Solver constraint joint DOF forces. - N = getDofs(). @@ -213,7 +216,7 @@ namespace physx - The indexing follows the internal DOF index order, see PxArticulationCache::jointVelocity. - Raise PxArticulationFlag::eCOMPUTE_JOINT_FORCES to enable reading the solver forces. */ - PxReal* jointSolverForces; + PX_DEPRECATED PxReal* jointSolverForces; /** \brief Link spatial velocity. @@ -239,6 +242,18 @@ namespace physx */ PxSpatialVelocity* linkAcceleration; + /** + \brief Link incoming joint force, i.e. the total force transmitted from the parent link to this link. + + - N = getNbLinks(). + - Read using PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCE. + - The indexing follows the internal link indexing, see PxArticulationLink::getLinkIndex. + - The force is reported in the child joint frame of the link's incoming joint. + + @see PxArticulationJointReducedCoordinate::getChildPose + */ + PxSpatialForce* linkIncomingJointForce; + /** \brief Root link transform, velocities, and accelerations. @@ -250,6 +265,8 @@ namespace physx PxArticulationRootLinkData* rootLinkData; /** + @deprecated + \brief Link sensor spatial forces. - N = getNbSensors(). @@ -258,7 +275,7 @@ namespace physx @see PxArticulationSensor */ - PxSpatialForce* sensorForces; + PX_DEPRECATED 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. @@ -288,11 +305,13 @@ namespace physx }; /** + @deprecated + \brief Flags to configure the forces reported by articulation link sensors. @see PxArticulationSensor::setFlag */ - struct PxArticulationSensorFlag + struct PX_DEPRECATED PxArticulationSensorFlag { enum Enum { @@ -302,14 +321,16 @@ namespace physx }; }; - typedef physx::PxFlags PxArticulationSensorFlags; + typedef PX_DEPRECATED physx::PxFlags PxArticulationSensorFlags; /** + @deprecated + \brief A force sensor that can be attached to articulation links to measure spatial force. @see PxArticulationReducedCoordinate::createSensor */ - class PxArticulationSensor : public PxBase + class PX_DEPRECATED PxArticulationSensor : public PxBase { public: /** @@ -471,9 +492,9 @@ namespace physx 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] + + \param[in] minPositionIters Number of position iterations the solver should perform for this articulation. Range: [1,255]. Default: 4. + \param[in] minVelocityIters Number of velocity iterations the solver should perform for this articulation. Range: [0,255]. Default: 1 \note This call may not be made during simulation. @@ -491,16 +512,16 @@ namespace physx /** \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 + When an actor does not move for a period of time, it is no longer simulated in order to reduce computational cost. 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. + \li The wake counter of any link in the articulation is positive (see #setWakeCounter()). + \li The mass-normalized energy of any link in the articulation is above a threshold (see #setSleepThreshold()). + \li A non-zero force or torque has been applied to any joint or link. If an articulation is sleeping, the following state is guaranteed: @@ -519,7 +540,7 @@ namespace physx \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() + @see wakeUp() putToSleep() getSleepThreshold() setSleepThreshold() */ virtual bool isSleeping() const = 0; @@ -532,6 +553,8 @@ namespace physx \note This call may not be made during simulation. + Default: 5e-5f * PxTolerancesScale::speed * PxTolerancesScale::speed; + @see isSleeping() getSleepThreshold() wakeUp() putToSleep() */ virtual void setSleepThreshold(PxReal threshold) = 0; @@ -552,7 +575,7 @@ namespace physx This value has no effect if PxSceneFlag::eENABLE_STABILIZATION was not enabled on the PxSceneDesc. - Default: 0.01 * PxTolerancesScale::speed * PxTolerancesScale::speed + Default: 5e-6f * PxTolerancesScale::speed * PxTolerancesScale::speed \param[in] threshold Energy below which the articulation may participate in stabilization. Range: [0,inf) @@ -576,9 +599,9 @@ namespace physx /** \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. + - The wake counter value specifies a time threshold used to determine whether an articulation may be put to sleep. + - The articulation will be put to sleep if all links have experienced a mass-normalised energy less than a threshold for at least + a threshold time, as specified by the wake counter. - 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) @@ -605,7 +628,7 @@ namespace physx /** \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. + - The articulation will be 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, @@ -639,7 +662,7 @@ namespace physx \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. + \param[in] maxLinearVelocity The maximal linear velocity magnitude. Range: [0, PX_MAX_F32); Default: 1e+6. @see setMaxCOMAngularVelocity, PxRigidBody::setLinearDamping, PxRigidBody::setAngularDamping, PxArticulationJointReducedCoordinate::setMaxJointVelocity */ @@ -666,7 +689,7 @@ namespace physx \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. + \param[in] maxAngularVelocity The maximal angular velocity magnitude. Range: [0, PX_MAX_F32); Default: 1e+6 @see setMaxCOMLinearVelocity, PxRigidBody::setLinearDamping, PxRigidBody::setAngularDamping, PxArticulationJointReducedCoordinate::setMaxJointVelocity */ @@ -692,6 +715,11 @@ namespace physx \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. + \note When the articulation is added to a scene, the root link adopts the specified pose. The pose of the + root link is propagated through the ensemble of links from parent to child after accounting for each child's + inbound joint frames and the joint positions set by PxArticulationJointReducedCoordinate::setJointPosition(). + As a consequence, the pose of each non-root link is automatically overwritten when adding the articulation to the scene. + @see PxArticulationLink */ virtual PxArticulationLink* createLink(PxArticulationLink* parent, const PxTransform& pose) = 0; @@ -702,6 +730,8 @@ namespace physx Attached sensors and tendons are released automatically when the articulation is released. \note This call may not be made during simulation. + + \note This call does not release any PxArticulationCache instance that has been instantiated using #createCache() */ virtual void release() = 0; @@ -739,7 +769,7 @@ namespace physx 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. + \param[in] name A pointer to a char buffer used to specify the name of the articulation. @see getName() */ @@ -769,9 +799,9 @@ namespace physx virtual PxBounds3 getWorldBounds(float inflation = 1.01f) const = 0; /** - \brief Returns the aggregate the articulation might be a part of. + \brief Returns the aggregate associated with the articulation. - \return The aggregate the articulation is a part of, or NULL if the articulation does not belong to an aggregate. + \return The aggregate associated with the articulation or NULL if the articulation does not belong to an aggregate. @see PxAggregate */ @@ -803,7 +833,7 @@ namespace physx /** \brief Returns the articulation's flags. - \return The flags. + \return The articulation's flags. @see PxArticulationFlag */ @@ -895,11 +925,13 @@ namespace physx - 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] maximum The maximal-coordinate joint DOF data, N = (getNbLinks() - 1) * 6 - \param[out] reduced The reduced-coordinate joint DOF data, N = getDofs() + \param[in] maximum The maximal-coordinate joint DOF data with minimum array length N = (getNbLinks() - 1) * 6 + \param[out] reduced The reduced-coordinate joint DOF data with minimum array length N = getDofs() \note The articulation must be in a scene. + \note This can be used as a helper function to prepare per joint cache data such as PxArticulationCache::jointVelocity. + @see unpackJointData */ virtual void packJointData(const PxReal* maximum, PxReal* reduced) const = 0; @@ -910,8 +942,8 @@ namespace physx - 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. + \param[in] reduced The reduced-coordinate joint DOF data with minimum array length N = getDofs(). + \param[out] maximum The maximal-coordinate joint DOF data with minimum array length N = (getNbLinks() - 1) * 6. \note The articulation must be in a scene. @@ -1142,18 +1174,20 @@ namespace physx virtual PxU32 getCoefficientMatrixSize() const = 0; /** - \brief Sets the root link transform (world to actor frame). + \brief Sets the root link transform in the world 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. + \param[in] autowake If true and the articulation is in a scene, the articulation will be woken up and the wake counter of + each link will be reset to #PxSceneDesc::wakeCounterResetValue. \note This call may not be made during simulation. + \note PxArticulationCache::rootLinkData similarly allows the root link pose to be updated and potentially offers better performance + if the root link pose is to be updated along with other state variables. + @see getRootGlobalPose, updateKinematic, PxArticulationCache, applyCache */ virtual void setRootGlobalPose(const PxTransform& pose, bool autowake = true) = 0; @@ -1161,13 +1195,14 @@ namespace physx /** \brief Returns the root link transform (world to actor frame). - 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. + \note PxArticulationCache::rootLinkData similarly allows the root link pose to be queried and potentially offers better performance if the root + link pose is to be queried along with other state variables. + @see setRootGlobalPose, PxArticulationCache, copyInternalStateToCache */ virtual PxTransform getRootGlobalPose() const = 0; @@ -1176,7 +1211,6 @@ namespace physx \brief Sets the root link linear center-of-mass 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 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. @@ -1187,6 +1221,9 @@ namespace physx \note This call may not be made during simulation, except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + \note PxArticulationCache::rootLinkData similarly allows the root link linear velocity to be updated and potentially offers better performance + if the root link linear velocity is to be updated along with other state variables. + @see updateKinematic, getRootLinearVelocity, setRootAngularVelocity, getRootAngularVelocity, PxRigidBody::getCMassLocalPose, PxArticulationCache, applyCache */ virtual void setRootLinearVelocity(const PxVec3& linearVelocity, bool autowake = true) = 0; @@ -1195,13 +1232,15 @@ namespace physx \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. + \note PxArticulationCache::rootLinkData similarly allows the root link linear velocity to be queried and potentially offers better performance + if the root link linear velocity is to be queried along with other state variables. + @see setRootLinearVelocity, setRootAngularVelocity, getRootAngularVelocity, PxRigidBody::getCMassLocalPose, PxArticulationCache, applyCache */ virtual PxVec3 getRootLinearVelocity(void) const = 0; @@ -1209,7 +1248,6 @@ namespace physx /** \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. @@ -1220,6 +1258,9 @@ namespace physx \note This call may not be made during simulation, except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + \note PxArticulationCache::rootLinkData similarly allows the root link angular velocity to be updated and potentially offers better performance + if the root link angular velocity is to be updated along with other state variables. + @see updateKinematic, getRootAngularVelocity, setRootLinearVelocity, getRootLinearVelocity, PxArticulationCache, applyCache */ virtual void setRootAngularVelocity(const PxVec3& angularVelocity, bool autowake = true) = 0; @@ -1227,13 +1268,14 @@ namespace physx /** \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. + \note PxArticulationCache::rootLinkData similarly allows the root link angular velocity to be queried and potentially offers better performance + if the root link angular velocity is to be queried along with other state variables. + @see setRootAngularVelocity, setRootLinearVelocity, getRootLinearVelocity, PxArticulationCache, applyCache */ virtual PxVec3 getRootAngularVelocity(void) const = 0; @@ -1248,8 +1290,9 @@ namespace physx \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. + \note This call may only be made on articulations that are in a scene. It is not allowed to use this method while the simulation + is running. The exceptions to this rule are a split simulation during #PxScene::collide() and up to #PxScene::advance(); + in PxContactModifyCallback; and in contact report callbacks. @see PxArticulationLink::getLinkIndex, PxRigidBody::getCMassLocalPose */ @@ -1258,7 +1301,7 @@ namespace physx /** \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. + \return The GPU index, or 0xFFFFFFFF if the articulation is not in a scene or PxSceneFlag::eENABLE_DIRECT_GPU_API is not set. */ virtual PxU32 getGpuArticulationIndex() = 0; @@ -1270,6 +1313,8 @@ namespace physx \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. + \note The spatial tendon is released with PxArticulationReducedCoordinate::release() + @see PxArticulationSpatialTendon */ virtual PxArticulationSpatialTendon* createSpatialTendon() = 0; @@ -1282,11 +1327,15 @@ namespace physx \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. + \note The fixed tendon is released with PxArticulationReducedCoordinate::release() + @see PxArticulationFixedTendon */ virtual PxArticulationFixedTendon* createFixedTendon() = 0; /** + @deprecated + \brief Creates a force sensor attached to a link of the articulation. \param[in] link The link to attach the sensor to. @@ -1298,9 +1347,11 @@ namespace physx \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. + \note The sensor is released with PxArticulationReducedCoordinate::release() + @see PxArticulationSensor */ - virtual PxArticulationSensor* createSensor(PxArticulationLink* link, const PxTransform& relativePose) = 0; + virtual PX_DEPRECATED PxArticulationSensor* createSensor(PxArticulationLink* link, const PxTransform& relativePose) = 0; /** @@ -1350,6 +1401,8 @@ namespace physx virtual PxU32 getNbFixedTendons() = 0; /** + @deprecated + \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. @@ -1364,19 +1417,21 @@ namespace physx @see PxArticulationSensor, getNbSensors */ - virtual PxU32 getSensors(PxArticulationSensor** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + virtual PX_DEPRECATED PxU32 getSensors(PxArticulationSensor** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; /** + @deprecated + \brief Returns the number of sensors in the articulation. \return The number of sensors. */ - virtual PxU32 getNbSensors() = 0; + virtual PX_DEPRECATED 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. + An alternative that potentially offers better performance is to use the PxArticulationCache API. If the application updates the root state (position and velocity) or joint state via any combination of the non-cache API calls diff --git a/physx/include/PxAttachment.h b/physx/include/PxAttachment.h index 32d0a17c7..3983fb8ca 100644 --- a/physx/include/PxAttachment.h +++ b/physx/include/PxAttachment.h @@ -31,6 +31,7 @@ #include "PxConeLimitedConstraint.h" #include "PxFiltering.h" +#include "PxNodeIndex.h" #include "foundation/PxVec4.h" /** \addtogroup physics @@ -47,9 +48,17 @@ namespace physx */ struct PxParticleRigidAttachment : public PxParticleRigidFilterPair { - PX_ALIGN(16, PxVec4 mLocalPose0); //!< local pose in body frame - except for statics, these are using world positions. + PxParticleRigidAttachment() {} + + PxParticleRigidAttachment(const PxConeLimitedConstraint& coneLimitedConstraint, const PxVec4& localPose0): + PxParticleRigidFilterPair(PxNodeIndex().getInd(), PxNodeIndex().getInd()), + mLocalPose0(localPose0), + mConeLimitParams(coneLimitedConstraint) + { + } - PxConeLimitParams mParams; //!< Parameters to specify cone constraints + PX_ALIGN(16, PxVec4 mLocalPose0); //!< local pose in body frame - except for statics, these are using world positions. + PxConeLimitParams mConeLimitParams; //!< Parameters to specify cone constraints }; #if !PX_DOXYGEN diff --git a/physx/include/PxBuffer.h b/physx/include/PxBuffer.h deleted file mode 100644 index bfb5bf2fb..000000000 --- a/physx/include/PxBuffer.h +++ /dev/null @@ -1,136 +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-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/physx/include/PxConeLimitedConstraint.h b/physx/include/PxConeLimitedConstraint.h index e8e931f99..a314bac7d 100644 --- a/physx/include/PxConeLimitedConstraint.h +++ b/physx/include/PxConeLimitedConstraint.h @@ -47,17 +47,58 @@ namespace physx struct PxConeLimitedConstraint { PxConeLimitedConstraint() + { + setToDefault(); + } + + /** + \brief Set values such that constraint is disabled. + */ + PX_INLINE void setToDefault() { mAxis = PxVec3(0.f, 0.f, 0.f); - mAngle = 0.f; + mAngle = -1.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 Checks for valitity. + + \return true if the constaint is valid + */ + PX_INLINE bool isValid() const + { + //disabled + if (mAngle < 0.f && mLowLimit == 0.f && mHighLimit == 0.f) + { + return true; + } + + if (!mAxis.isNormalized()) + { + return false; + } + + //negative signifies that cone is disabled + if (mAngle >= PxPi) + { + return false; + } + + //zero signifies that distance limits are disabled + if (mLowLimit < 0.f || mHighLimit < 0.f || mLowLimit > mHighLimit) + { + return false; + } + + return true; + } + + PxVec3 mAxis; //!< Axis of the cone in actor space + PxReal mAngle; //!< Opening angle in radians, negative indicates unlimited + PxReal mLowLimit; //!< Minimum distance + PxReal mHighLimit; //!< Maximum distance }; /** @@ -67,6 +108,14 @@ struct PxConeLimitedConstraint PX_ALIGN_PREFIX(16) struct PxConeLimitParams { + PX_CUDA_CALLABLE PxConeLimitParams() {} + + PX_CUDA_CALLABLE PxConeLimitParams(const PxConeLimitedConstraint& coneLimitedConstraint) : + lowHighLimits(coneLimitedConstraint.mLowLimit, coneLimitedConstraint.mHighLimit, 0.0f, 0.0f), + axisAngle(coneLimitedConstraint.mAxis, coneLimitedConstraint.mAngle) + { + } + PxVec4 lowHighLimits; // [lowLimit, highLimit, unused, unused] PxVec4 axisAngle; // [axis.x, axis.y, axis.z, angle] }PX_ALIGN_SUFFIX(16); diff --git a/physx/include/PxConstraint.h b/physx/include/PxConstraint.h index c8aa6c231..9d53790ff 100644 --- a/physx/include/PxConstraint.h +++ b/physx/include/PxConstraint.h @@ -56,9 +56,6 @@ struct PxConstraintFlag enum Enum { 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 @@ -86,7 +83,6 @@ PX_FLAGS_OPERATORS(PxConstraintFlag::Enum, PxU16) struct PxConstraintShaderTable { PxConstraintSolverPrep solverPrep; //!< solver constraint generation function - PxConstraintProject project; //!< @deprecated constraint projection function PxConstraintVisualize visualize; //!< constraint visualization function PxConstraintFlag::Enum flag; //!< constraint flags }; @@ -251,7 +247,7 @@ class PxConstraint : public PxBase \param[in] connector the constraint connector object by which the SDK communicates with the constraint. \param[in] shaders the shader table for the constraint - @see PxConstraintConnector PxConstraintSolverPrep PxConstraintProject PxConstraintVisualize + @see PxConstraintConnector PxConstraintSolverPrep PxConstraintVisualize */ virtual void setConstraintFunctions(PxConstraintConnector& connector, const PxConstraintShaderTable& shaders) = 0; diff --git a/physx/include/PxConstraintDesc.h b/physx/include/PxConstraintDesc.h index 12aa7559d..fcaaa2583 100644 --- a/physx/include/PxConstraintDesc.h +++ b/physx/include/PxConstraintDesc.h @@ -182,13 +182,6 @@ struct PxConstraintVisualizationFlag PX_ALIGN_PREFIX(16) struct PxConstraintInvMassScale { -//= 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. -//================================================================================================== - PxReal linear0; //!< multiplier for inverse mass of body0 PxReal angular0; //!< multiplier for inverse MoI of body0 PxReal linear1; //!< multiplier for inverse mass of body1 @@ -231,24 +224,6 @@ typedef PxU32 (*PxConstraintSolverPrep)(Px1DConstraint* constraints, PxVec3p& cAtW, PxVec3p& cBtW); -/** -\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. - -\param[in] constantBlock The constant data block -\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 PX_DEPRECATED void (*PxConstraintProject)(const void* constantBlock, - PxTransform& bodyAToWorld, - PxTransform& bodyBToWorld, - bool projectToA); - /** \brief API used to visualize details about a constraint. */ @@ -266,38 +241,34 @@ class PxConstraintVisualizer /** \brief Visualize joint linear limit - \param[in] t0 Base transformation - \param[in] t1 End transformation + \param[in] t0 Base transformation + \param[in] t1 End transformation \param[in] value Distance - \param[in] active State of the joint - active/inactive */ - virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value, bool active) = 0; + virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value) = 0; /** \brief Visualize joint angular limit - \param[in] t0 Transformation for the visualization - \param[in] lower Lower limit angle - \param[in] upper Upper limit angle - \param[in] active State of the joint - active/inactive + \param[in] t0 Transformation for the visualization + \param[in] lower Lower limit angle + \param[in] upper Upper limit angle */ - virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper, bool active) = 0; + virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper) = 0; /** \brief Visualize limit cone - \param[in] t Transformation for the visualization + \param[in] t Transformation for the visualization \param[in] tanQSwingY Tangent of the quarter Y angle \param[in] tanQSwingZ Tangent of the quarter Z angle - \param[in] active State of the joint - active/inactive */ - virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ, bool active) = 0; + virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ) = 0; /** \brief Visualize joint double cone - \param[in] t Transformation for the visualization - \param[in] angle Limit angle - \param[in] active State of the joint - active/inactive + \param[in] t Transformation for the visualization + \param[in] angle Limit angle */ - virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle, bool active) = 0; + virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle) = 0; /** \brief Visualize line diff --git a/physx/include/PxContact.h b/physx/include/PxContact.h index f10112bc1..37e40e164 100644 --- a/physx/include/PxContact.h +++ b/physx/include/PxContact.h @@ -35,6 +35,7 @@ #include "foundation/PxVec3.h" #include "foundation/PxAssert.h" +#include "PxConstraintDesc.h" #include "PxNodeIndex.h" #if !PX_DOXYGEN @@ -51,20 +52,6 @@ namespace physx 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 PX_DEPRECATED PxMassModificationProps -{ - PxReal mInvMassScale0; - PxReal mInvInertiaScale0; - PxReal mInvMassScale1; - PxReal mInvInertiaScale1; -} -PX_ALIGN_SUFFIX(16); - /** \brief Header for a contact patch where all points share same material and normal */ @@ -86,7 +73,7 @@ struct PxContactPatch /** \brief Modifiers for scaling the inertia of the involved bodies */ - PX_ALIGN(16, PxMassModificationProps mMassModification); //16 + PX_ALIGN(16, PxConstraintInvMassScale mMassModification); //16 /** \brief Contact normal @@ -441,7 +428,7 @@ struct PxContactStreamIterator */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale0() const { - return patch->mMassModification.mInvMassScale0; + return patch->mMassModification.linear0; } /** @@ -450,7 +437,7 @@ struct PxContactStreamIterator */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvMassScale1() const { - return patch->mMassModification.mInvMassScale1; + return patch->mMassModification.linear1; } /** @@ -459,7 +446,7 @@ struct PxContactStreamIterator */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale0() const { - return patch->mMassModification.mInvInertiaScale0; + return patch->mMassModification.angular0; } /** @@ -468,7 +455,7 @@ struct PxContactStreamIterator */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getInvInertiaScale1() const { - return patch->mMassModification.mInvInertiaScale1; + return patch->mMassModification.angular1; } /** diff --git a/physx/include/PxContactModifyCallback.h b/physx/include/PxContactModifyCallback.h index 6087d08f8..b20419283 100644 --- a/physx/include/PxContactModifyCallback.h +++ b/physx/include/PxContactModifyCallback.h @@ -289,7 +289,7 @@ class PxContactSet PX_FORCE_INLINE PxReal getInvMassScale0() const { PxContactPatch* patch = getPatch(); - return patch->mMassModification.mInvMassScale0; + return patch->mMassModification.linear0; } /** @@ -301,7 +301,7 @@ class PxContactSet PX_FORCE_INLINE PxReal getInvMassScale1() const { PxContactPatch* patch = getPatch(); - return patch->mMassModification.mInvMassScale1; + return patch->mMassModification.linear1; } /** @@ -313,7 +313,7 @@ class PxContactSet PX_FORCE_INLINE PxReal getInvInertiaScale0() const { PxContactPatch* patch = getPatch(); - return patch->mMassModification.mInvInertiaScale0; + return patch->mMassModification.angular0; } /** @@ -325,7 +325,7 @@ class PxContactSet PX_FORCE_INLINE PxReal getInvInertiaScale1() const { PxContactPatch* patch = getPatch(); - return patch->mMassModification.mInvInertiaScale1; + return patch->mMassModification.angular1; } /** @@ -338,7 +338,7 @@ class PxContactSet PX_FORCE_INLINE void setInvMassScale0(const PxReal scale) { PxContactPatch* patch = getPatch(); - patch->mMassModification.mInvMassScale0 = scale; + patch->mMassModification.linear0 = scale; patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; } @@ -352,7 +352,7 @@ class PxContactSet PX_FORCE_INLINE void setInvMassScale1(const PxReal scale) { PxContactPatch* patch = getPatch(); - patch->mMassModification.mInvMassScale1 = scale; + patch->mMassModification.linear1 = scale; patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; } @@ -366,7 +366,7 @@ class PxContactSet PX_FORCE_INLINE void setInvInertiaScale0(const PxReal scale) { PxContactPatch* patch = getPatch(); - patch->mMassModification.mInvInertiaScale0 = scale; + patch->mMassModification.angular0 = scale; patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; } @@ -380,7 +380,7 @@ class PxContactSet PX_FORCE_INLINE void setInvInertiaScale1(const PxReal scale) { PxContactPatch* patch = getPatch(); - patch->mMassModification.mInvInertiaScale1 = scale; + patch->mMassModification.angular1 = scale; patch->internalFlags |= PxContactPatch::eHAS_MODIFIED_MASS_RATIOS; } diff --git a/physx/include/PxCustomParticleSystemSolverCallback.h b/physx/include/PxCustomParticleSystemSolverCallback.h deleted file mode 100644 index be66d7f56..000000000 --- a/physx/include/PxCustomParticleSystemSolverCallback.h +++ /dev/null @@ -1,105 +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-2023 NVIDIA 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/physx/include/PxFEMClothFlags.h b/physx/include/PxFEMClothFlags.h index 43b7b18d6..f4b2c6f79 100644 --- a/physx/include/PxFEMClothFlags.h +++ b/physx/include/PxFEMClothFlags.h @@ -40,9 +40,8 @@ namespace physx /** \brief Identifies input and output buffers for PxFEMCloth. -@see PxFEMClothData::readData(), PxFEMClothData::writeData(), PxBuffer. */ -struct PxFEMClothData +struct PxFEMClothDataFlag { enum Enum { @@ -54,15 +53,15 @@ struct PxFEMClothData }; }; -typedef PxFlags PxFEMClothDataFlags; +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 + eUSE_ANISOTROPIC_CLOTH = 1 << 1, // 0: use isotropic model, 1: use anistropic model + eENABLE_FLATTENING = 1 << 2 // 0: query rest bending angle from rest shape, 1: use zero rest bending angle }; }; diff --git a/physx/include/PxFEMClothMaterial.h b/physx/include/PxFEMClothMaterial.h index c1b99cc4d..4458c23b9 100644 --- a/physx/include/PxFEMClothMaterial.h +++ b/physx/include/PxFEMClothMaterial.h @@ -65,40 +65,6 @@ namespace physx */ 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: diff --git a/physx/include/PxFEMSoftBodyMaterial.h b/physx/include/PxFEMSoftBodyMaterial.h index ad856bffa..5e36a9855 100644 --- a/physx/include/PxFEMSoftBodyMaterial.h +++ b/physx/include/PxFEMSoftBodyMaterial.h @@ -39,6 +39,15 @@ namespace physx { #endif + struct PxFEMSoftBodyMaterialModel + { + enum Enum + { + eCO_ROTATIONAL, //!< Default model. Well suited for high stiffness. Does need tetrahedra with good shapes (no extreme slivers) in the rest pose. + eNEO_HOOKEAN //!< Well suited for lower stiffness. Robust to any tetrahedron shape. + }; + }; + class PxScene; /** \brief Material class to represent a set of softbody FEM material properties. @@ -83,6 +92,23 @@ namespace physx */ virtual PxReal getDampingScale() const = 0; + /** + \brief Sets the material model. + + \param[in] model The material model + + @see getMaterialModel + */ + virtual void setMaterialModel(PxFEMSoftBodyMaterialModel::Enum model) = 0; + + /** + \brief Retrieves the material model. + \return The material model. + + @see setMaterialModel() + */ + virtual PxFEMSoftBodyMaterialModel::Enum getMaterialModel() const = 0; + virtual const char* getConcreteTypeName() const { return "PxFEMSoftBodyMaterial"; } protected: diff --git a/physx/include/PxFiltering.h b/physx/include/PxFiltering.h index 16f54e8c5..b2fb66ab9 100644 --- a/physx/include/PxFiltering.h +++ b/physx/include/PxFiltering.h @@ -43,8 +43,6 @@ namespace physx class PxActor; class PxShape; -static const PxU32 INVALID_FILTER_PAIR_INDEX = 0xffffffff; - /** \brief Collection of flags describing the actions to take for a collision pair. @@ -363,13 +361,6 @@ PX_FLAGS_OPERATORS(PxFilterFlag::Enum, PxU16) */ struct PxFilterData { -//= 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_INLINE PxFilterData(const PxEMPTY) { } @@ -501,8 +492,10 @@ struct PxFilterObjectFlag { enum Enum { - eKINEMATIC = (1<<4), - eTRIGGER = (1<<5) + eKINEMATIC = (1<<4), + eTRIGGER = (1<<5), + + eNEXT_FREE = (1<<6) // Used internally }; }; @@ -641,25 +634,25 @@ class PxSimulationFilterCallback Return the PxFilterFlag flags and set the PxPairFlag flags to define what the simulation should do with the given collision pair. - \param[in] pairID Unique ID of the collision pair used to issue filter status changes for the pair (see #statusChange()) - \param[in] attributes0 The filter attribute of the first object - \param[in] filterData0 The custom filter data of the first object - \param[in] a0 Actor pointer of the first object - \param[in] s0 Shape pointer of the first object (NULL if the object has no shapes) - \param[in] attributes1 The filter attribute of the second object - \param[in] filterData1 The custom filter data of the second object - \param[in] a1 Actor pointer of the second object - \param[in] s1 Shape pointer of the second object (NULL if the object has no shapes) - \param[in,out] pairFlags In: Pair flags returned by the filter shader. Out: Additional information on how an accepted pair should get processed + \param[in] pairID Unique ID of the collision pair used to issue filter status changes for the pair (see #statusChange()) + \param[in] attributes0 The filter attribute of the first object + \param[in] filterData0 The custom filter data of the first object + \param[in] a0 Actor pointer of the first object + \param[in] s0 Shape pointer of the first object (NULL if the object has no shapes) + \param[in] attributes1 The filter attribute of the second object + \param[in] filterData1 The custom filter data of the second object + \param[in] a1 Actor pointer of the second object + \param[in] s1 Shape pointer of the second object (NULL if the object has no shapes) + \param[in,out] pairFlags In: Pair flags returned by the filter shader. Out: Additional information on how an accepted pair should get processed \return Filter flags defining whether the pair should be discarded, temporarily ignored or processed and whether the pair should be tracked and send a report on pair deletion through the filter callback @see PxSimulationFilterShader PxFilterData PxFilterObjectAttributes PxFilterFlag PxPairFlag */ - virtual PxFilterFlags pairFound( PxU32 pairID, - PxFilterObjectAttributes attributes0, PxFilterData filterData0, const PxActor* a0, const PxShape* s0, - PxFilterObjectAttributes attributes1, PxFilterData filterData1, const PxActor* a1, const PxShape* s1, - PxPairFlags& pairFlags) = 0; + virtual PxFilterFlags pairFound( PxU64 pairID, + PxFilterObjectAttributes attributes0, PxFilterData filterData0, const PxActor* a0, const PxShape* s0, + PxFilterObjectAttributes attributes1, PxFilterData filterData1, const PxActor* a1, const PxShape* s1, + PxPairFlags& pairFlags) = 0; /** \brief Callback to inform that a tracked collision pair is gone. @@ -667,21 +660,19 @@ class PxSimulationFilterCallback This method gets called when a collision pair disappears or gets re-filtered. Only applies to collision pairs which have been marked as filter callback pairs (#PxFilterFlag::eNOTIFY set in #pairFound()). - \param[in] pairID Unique ID of the collision pair that disappeared - \param[in] attributes0 The filter attribute of the first object - \param[in] filterData0 The custom filter data of the first object - \param[in] attributes1 The filter attribute of the second object - \param[in] filterData1 The custom filter data of the second object - \param[in] objectRemoved True if the pair was lost because one of the objects got removed from the scene + \param[in] pairID Unique ID of the collision pair that disappeared + \param[in] attributes0 The filter attribute of the first object + \param[in] filterData0 The custom filter data of the first object + \param[in] attributes1 The filter attribute of the second object + \param[in] filterData1 The custom filter data of the second object + \param[in] objectRemoved True if the pair was lost because one of the objects got removed from the scene @see pairFound() PxSimulationFilterShader PxFilterData PxFilterObjectAttributes */ - virtual void pairLost( PxU32 pairID, - PxFilterObjectAttributes attributes0, - PxFilterData filterData0, - PxFilterObjectAttributes attributes1, - PxFilterData filterData1, - bool objectRemoved) = 0; + virtual void pairLost( PxU64 pairID, + PxFilterObjectAttributes attributes0, PxFilterData filterData0, + PxFilterObjectAttributes attributes1, PxFilterData filterData1, + bool objectRemoved) = 0; /** \brief Callback to give the opportunity to change the filter state of a tracked collision pair. @@ -697,15 +688,15 @@ class PxSimulationFilterCallback \note The application is responsible to ensure that this method does not get called for pairs that have been reported as lost, see #pairLost(). - \param[out] pairID ID of the collision pair for which the filter status should be changed - \param[out] pairFlags The new pairFlags to apply to the collision pair - \param[out] filterFlags The new filterFlags to apply to the collision pair + \param[out] pairID ID of the collision pair for which the filter status should be changed + \param[out] pairFlags The new pairFlags to apply to the collision pair + \param[out] filterFlags The new filterFlags to apply to the collision pair \return True if the changes should be applied. In this case the method will get called again. False if no more status changes should be done in the current simulation step. In that case the provided flags will be discarded. @see pairFound() pairLost() PxFilterFlag PxPairFlag */ - virtual bool statusChange(PxU32& pairID, PxPairFlags& pairFlags, PxFilterFlags& filterFlags) = 0; + virtual bool statusChange(PxU64& pairID, PxPairFlags& pairFlags, PxFilterFlags& filterFlags) = 0; protected: virtual ~PxSimulationFilterCallback() {} @@ -749,6 +740,10 @@ struct PxPairFilteringMode */ struct PxParticleRigidFilterPair { + PX_CUDA_CALLABLE PxParticleRigidFilterPair() {} + + PX_CUDA_CALLABLE PxParticleRigidFilterPair(const PxU64 id0, const PxU64 id1): mID0(id0), mID1(id1) {} + PxU64 mID0; //!< Rigid node index PxU64 mID1; //!< Particle/vertex id diff --git a/physx/include/PxHairSystemFlag.h b/physx/include/PxHairSystemFlag.h index 06f6b3164..9c4ee7bb4 100644 --- a/physx/include/PxHairSystemFlag.h +++ b/physx/include/PxHairSystemFlag.h @@ -39,7 +39,6 @@ namespace physx /** \brief Identifies input and output buffers for PxHairSystem - \see PxHairSystemData::readData(), PxHairSystemData::writeData(), PxBuffer */ struct PxHairSystemData { diff --git a/physx/include/PxImmediateMode.h b/physx/include/PxImmediateMode.h index e63debd91..397b14061 100644 --- a/physx/include/PxImmediateMode.h +++ b/physx/include/PxImmediateMode.h @@ -96,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 PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 index) = 0; + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 index) = 0; virtual ~PxContactRecorder(){} }; @@ -269,14 +269,6 @@ namespace immediate 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. - Call this first to enable reduced coordinates articulations in immediate mode. - - @see PxRegisterArticulationsReducedCoordinate - */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxRegisterImmediateArticulations(); - struct PxArticulationJointDataRC { PxTransform parentPose; @@ -386,7 +378,7 @@ namespace immediate struct PxArticulationLinkHandle { - PX_FORCE_INLINE PxArticulationLinkHandle(PxArticulationHandle art=NULL, const PxU32 id=0xffffffff) : articulation(art), linkId(id) {} + PX_FORCE_INLINE PxArticulationLinkHandle(PxArticulationHandle art=NULL, PxU32 id=0xffffffff) : articulation(art), linkId(id) {} PxArticulationHandle articulation; PxU32 linkId; @@ -558,14 +550,14 @@ namespace immediate \param [in] dt Timestep \param [in] invLengthScale 1/lengthScale from PxTolerancesScale. */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxComputeUnconstrainedVelocities(PxArticulationHandle articulation, const PxVec3& gravity, const PxReal dt, const PxReal invLengthScale); + PX_C_EXPORT PX_PHYSX_CORE_API void PxComputeUnconstrainedVelocities(PxArticulationHandle articulation, const PxVec3& gravity, PxReal dt, PxReal invLengthScale); /** \brief Updates bodies for a given articulation. \param [in] articulation Articulation handle \param [in] dt Timestep */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxUpdateArticulationBodies(PxArticulationHandle articulation, const PxReal dt); + PX_C_EXPORT PX_PHYSX_CORE_API void PxUpdateArticulationBodies(PxArticulationHandle articulation, PxReal dt); /** \brief Computes unconstrained velocities for a given articulation. @@ -577,15 +569,15 @@ namespace immediate \param [in] invTotalDt 1/Timestep \param [in] invLengthScale 1/lengthScale from PxTolerancesScale. */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxComputeUnconstrainedVelocitiesTGS( PxArticulationHandle articulation, const PxVec3& gravity, const PxReal dt, - const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal invLengthScale); + PX_C_EXPORT PX_PHYSX_CORE_API void PxComputeUnconstrainedVelocitiesTGS( PxArticulationHandle articulation, const PxVec3& gravity, PxReal dt, + PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal invLengthScale); /** \brief Updates bodies for a given articulation. \param [in] articulation Articulation handle \param [in] dt Timestep */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxUpdateArticulationBodiesTGS(PxArticulationHandle articulation, const PxReal dt); + PX_C_EXPORT PX_PHYSX_CORE_API void PxUpdateArticulationBodiesTGS(PxArticulationHandle articulation, PxReal dt); /** \brief Constructs a PxSolverBodyData structure based on rigid body properties. Applies gravity, damping and clamps maximum velocity. @@ -598,7 +590,7 @@ namespace immediate \param [in] dt The timestep \param [in] gyroscopicForces Indicates whether gyroscopic forces should be integrated */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructSolverBodiesTGS(const PxRigidBodyData* inRigidData, PxTGSSolverBodyVel* outSolverBodyVel, PxTGSSolverBodyTxInertia* outSolverBodyTxInertia, PxTGSSolverBodyData* outSolverBodyData, const PxU32 nbBodies, const PxVec3& gravity, const PxReal dt, const bool gyroscopicForces = false); + PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructSolverBodiesTGS(const PxRigidBodyData* inRigidData, PxTGSSolverBodyVel* outSolverBodyVel, PxTGSSolverBodyTxInertia* outSolverBodyTxInertia, PxTGSSolverBodyData* outSolverBodyData, PxU32 nbBodies, const PxVec3& gravity, PxReal dt, bool gyroscopicForces = false); /** \brief Constructs a PxSolverBodyData structure for a static body at a given pose. @@ -626,9 +618,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 PxBatchConstraintsTGS( const PxSolverConstraintDesc* solverConstraintDescs, const PxU32 nbConstraints, PxTGSSolverBodyVel* solverBodies, const PxU32 nbBodies, + PX_C_EXPORT PX_PHYSX_CORE_API PxU32 PxBatchConstraintsTGS( const PxSolverConstraintDesc* solverConstraintDescs, PxU32 nbConstraints, PxTGSSolverBodyVel* solverBodies, PxU32 nbBodies, PxConstraintBatchHeader* outBatchHeaders, PxSolverConstraintDesc* outOrderedConstraintDescs, - PxArticulationHandle* 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. @@ -648,9 +640,9 @@ namespace immediate \return a boolean to define if this method was successful or not. */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateContactConstraintsTGS( PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, PxTGSSolverContactDesc* contactDescs, - PxConstraintAllocator& allocator, const PxReal invDt, const PxReal invTotalDt, const PxReal bounceThreshold, - const PxReal frictionOffsetThreshold, const PxReal correlationDistance); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateContactConstraintsTGS( PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxTGSSolverContactDesc* contactDescs, + PxConstraintAllocator& allocator, PxReal invDt, PxReal invTotalDt, PxReal bounceThreshold, + PxReal frictionOffsetThreshold, PxReal correlationDistance); /** \brief Creates a set of joint constraint blocks. Note that, depending the results of PxBatchConstraints, the batchHeader may refer to up to 4 solverConstraintDescs @@ -665,9 +657,9 @@ namespace immediate \param [in] lengthScale PxToleranceScale::length, i.e. a meter in simulation units \return a boolean indicating if this method was successful or not. */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsTGS( PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, - PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invDt, - const PxReal invTotalDt, const PxReal lengthScale); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsTGS( PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, + PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt, + PxReal invTotalDt, PxReal lengthScale); /** \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. @@ -684,8 +676,8 @@ namespace immediate \return a boolean indicating if this method was successful or not. @see PxCreateJointConstraints */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithShadersTGS( PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, PxConstraint** constraints, PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, - const PxReal dt, const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal lengthScale); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithShadersTGS( PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxConstraint** constraints, PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, + PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal lengthScale); /** \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. @@ -702,8 +694,8 @@ namespace immediate \return a boolean indicating if this method was successful or not. @see PxCreateJointConstraints */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithImmediateShadersTGS(PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, PxImmediateConstraint* constraints, PxTGSSolverConstraintPrepDesc* jointDescs, - PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal lengthScale); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithImmediateShadersTGS(PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxImmediateConstraint* constraints, PxTGSSolverConstraintPrepDesc* jointDescs, + PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal lengthScale); /** \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. @@ -722,9 +714,9 @@ namespace immediate \param [out] Z Temporary buffer for impulse propagation (only if articulations are used, size should be at least as large as the maximum number of links in any articulations being simulated) \param [out] deltaV Temporary buffer for velocity change (only if articulations are used, size should be at least as large as the maximum number of links in any articulations being simulated) */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxSolveConstraintsTGS( const PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs, - PxTGSSolverBodyVel* solverBodies, PxTGSSolverBodyTxInertia* txInertias, const PxU32 nbSolverBodies, const PxU32 nbPositionIterations, const PxU32 nbVelocityIterations, - const float dt, const float invDt, const PxU32 nbSolverArticulations = 0, PxArticulationHandle* solverArticulations = NULL, PxSpatialVector* Z = NULL, PxSpatialVector* deltaV = NULL); + PX_C_EXPORT PX_PHYSX_CORE_API void PxSolveConstraintsTGS( const PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs, + PxTGSSolverBodyVel* solverBodies, PxTGSSolverBodyTxInertia* txInertias, PxU32 nbSolverBodies, PxU32 nbPositionIterations, PxU32 nbVelocityIterations, + float dt, float invDt, 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, solverBody stores all the body's velocity data. @@ -735,28 +727,7 @@ 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 PxIntegrateSolverBodiesTGS(PxTGSSolverBodyVel* solverBody, PxTGSSolverBodyTxInertia* txInertia, PxTransform* poses, const PxU32 nbBodiesToIntegrate, const PxReal dt); - - /** - * @deprecated - */ - typedef PX_DEPRECATED PxArticulationJointDataRC PxFeatherstoneArticulationJointData; - /** - * @deprecated - */ - typedef PX_DEPRECATED PxArticulationLinkDataRC PxFeatherstoneArticulationLinkData; - /** - * @deprecated - */ - typedef PX_DEPRECATED PxArticulationDataRC PxFeatherstoneArticulationData; - /** - * @deprecated - */ - typedef PX_DEPRECATED PxArticulationLinkMutableDataRC PxMutableLinkData; - /** - * @deprecated - */ - typedef PX_DEPRECATED PxArticulationLinkDerivedDataRC PxLinkData; + PX_C_EXPORT PX_PHYSX_CORE_API void PxIntegrateSolverBodiesTGS(PxTGSSolverBodyVel* solverBody, PxTGSSolverBodyTxInertia* txInertia, PxTransform* poses, PxU32 nbBodiesToIntegrate, PxReal dt); #if !PX_DOXYGEN } diff --git a/physx/include/PxIsosurfaceExtraction.h b/physx/include/PxIsosurfaceExtraction.h new file mode 100644 index 000000000..63afc9f18 --- /dev/null +++ b/physx/include/PxIsosurfaceExtraction.h @@ -0,0 +1,352 @@ +// 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_ISOSURFACE_EXTRACTION_H +#define PX_ISOSURFACE_EXTRACTION_H +/** \addtogroup extensions + @{ +*/ + + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" +#include "PxParticleSystem.h" + +#include "PxSparseGridParams.h" + +#include "foundation/PxArray.h" +#include "PxParticleGpu.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + /** + \brief Identifies filter type to be applied on the isosurface grid. + */ + struct PxIsosurfaceGridFilteringType + { + enum Enum + { + eNONE = 0, //!< No filtering + eSMOOTH = 1, //!< Gaussian-blur-like filtering + eGROW = 2, //!< A dilate/erode operation will be applied that makes the fluid grow approximately one cell size + eSHRINK = 3 //!< A dilate/erode operation will be applied that makes the fluid shrink approximately one cell size + }; + }; + + /** + \brief Parameters to define the isosurface extraction settings like isosurface level, filtering etc. + */ + struct PxIsosurfaceParams + { + /** + \brief Default constructor. + */ + PX_INLINE PxIsosurfaceParams() + { + particleCenterToIsosurfaceDistance = 0.2f; + numMeshSmoothingPasses = 4; + numMeshNormalSmoothingPasses = 4; + gridFilteringFlags = 0; + gridSmoothingRadius = 0.2f; + } + + /** + \brief Clears the filtering operations + */ + PX_INLINE void clearFilteringPasses() + { + gridFilteringFlags = 0; + } + + /** + \brief Adds a smoothing pass after the existing ones + + At most 32 smoothing passes can be defined. Every pass can repeat itself up to 4 times. + + \param[in] operation The smoothing operation to add + \return The index of the smoothing pass that was added + */ + PX_INLINE PxU64 addGridFilteringPass(PxIsosurfaceGridFilteringType::Enum operation) + { + for (PxU32 i = 0; i < 32; ++i) + { + PxIsosurfaceGridFilteringType::Enum o; + if (!getGridFilteringPass(i, o)) + { + setGridFilteringPass(i, operation); + return i; + } + } + return 0xFFFFFFFFFFFFFFFF; + } + + /** + \brief Sets the operation of a smoothing pass + + \param[in] passIndex The index of the smoothing pass whose operation should be set Range: [0, 31] + \param[in] operation The operation the modified smoothing will perform + */ + PX_INLINE void setGridFilteringPass(PxU32 passIndex, PxIsosurfaceGridFilteringType::Enum operation) + { + PX_ASSERT(passIndex < 32u); + PxU32 shift = passIndex * 2; + gridFilteringFlags &= ~(PxU64(3) << shift); + gridFilteringFlags |= PxU64(operation) << shift; + } + + /** + \brief Returns the operation of a smoothing pass + + \param[in] passIndex The index of the smoothing pass whose operation is requested Range: [0, 31] + \param[out] operation The operation the requested smoothing pass will perform + \return true if the requested pass performs an operation + */ + PX_INLINE bool getGridFilteringPass(PxU32 passIndex, PxIsosurfaceGridFilteringType::Enum& operation) const + { + PxU32 shift = passIndex * 2; + PxU64 v = gridFilteringFlags >> shift; + v &= 3; //Extract last 2 bits + operation = PxIsosurfaceGridFilteringType::Enum(v); + return operation != PxIsosurfaceGridFilteringType::eNONE; + } + + PxReal particleCenterToIsosurfaceDistance; //!< Distance form a particle center to the isosurface + PxU32 numMeshSmoothingPasses; //!< Number of Taubin mesh postprocessing smoothing passes. Using an even number of passes lead to less shrinking. + PxU32 numMeshNormalSmoothingPasses; //!< Number of mesh normal postprocessing smoothing passes. + PxU64 gridFilteringFlags; //!< Encodes the smoothing steps to apply on the sparse grid. Use setGridSmoothingPass method to set up. + PxReal gridSmoothingRadius; //!< Gaussian blur smoothing kernel radius used for smoothing operations on the grid + }; + + /** + \brief Base class for isosurface extractors. Allows to register the data arrays for the isosurface and to obtain the number vertices/triangles in use. + */ + class PxIsosurfaceExtractor + { + public: + /** + \brief Returns the isosurface parameters. + + \return The isosurfacesettings used for the isosurface extraction + */ + virtual PxIsosurfaceParams getIsosurfaceParams() const = 0; + + /** + \brief Set the isosurface extraction parameters + + Allows to configure the isosurface extraction by controlling threshold value, smoothing options etc. + + \param[in] params A collection of settings to control the isosurface extraction + */ + virtual void setIsosurfaceParams(const PxIsosurfaceParams& params) = 0; + + /** + \brief Returns the number of vertices that the current isosurface triangle mesh uses + + \return The number of vertices currently in use + */ + virtual PxU32 getNumVertices() const = 0; + + /** + \brief Returns the number of triangles that the current isosurface triangle mesh uses + + \return The number of triangles currently in use + */ + virtual PxU32 getNumTriangles() const = 0; + + /** + \brief Returns the maximum number of vertices that the isosurface triangle mesh can contain + + \return The maximum number of vertices that can be genrated + */ + virtual PxU32 getMaxVertices() const = 0; + + /** + \brief Returns the maximum number of triangles that the isosurface triangle mesh can contain + + \return The maximum number of triangles that can be generated + */ + virtual PxU32 getMaxTriangles() const = 0; + + /** + \brief Resizes the internal triangle mesh buffers. + + If the output buffers are device buffers, nothing will get resized but new output buffers can be set using setResultBufferDevice. + For host side output buffers, temporary buffers will get resized. The new host side result buffers with the same size must be set using setResultBufferHost. + + \param[in] maxNumVertices The maximum number of vertices the output buffer can hold + \param[in] maxNumTriangles The maximum number of triangles the ouput buffer can hold + */ + virtual void setMaxVerticesAndTriangles(PxU32 maxNumVertices, PxU32 maxNumTriangles) = 0; + + /** + \brief The maximal number of particles the isosurface extractor can process + + \return The maximal number of particles + */ + virtual PxU32 getMaxParticles() const = 0; + + /** + \brief Sets the maximal number of particles the isosurface extractor can process + + \param[in] maxParticles The maximal number of particles + */ + virtual void setMaxParticles(PxU32 maxParticles) = 0; + + /** + \brief Releases the isosurface extractor instance and its data + */ + virtual void release() = 0; + + /** + \brief Triggers the compuation of a new isosurface based on the specified particle locations + + \param[in] deviceParticlePos A gpu pointer pointing to the start of the particle array + \param[in] numParticles The number of particles + \param[in] stream The stream on which all the gpu work will be performed + \param[in] phases A phase value per particle + \param[in] validPhaseMask A mask that specifies which phases should contribute to the isosurface. If the binary and operation + between this mask and the particle phase is non zero, then the particle will contribute to the isosurface + \param[in] activeIndices Optional array with indices of all active particles + \param[in] anisotropy1 Optional anisotropy information, x axis direction (xyz) and scale in w component + \param[in] anisotropy2 Optional anisotropy information, y axis direction (xyz) and scale in w component + \param[in] anisotropy3 Optional anisotropy information, z axis direction (xyz) and scale in w component + \param[in] anisotropyFactor A factor to multiply with the anisotropy scale + */ + virtual void extractIsosurface(PxVec4* deviceParticlePos, const PxU32 numParticles, CUstream stream, PxU32* phases = NULL, PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid, + PxU32* activeIndices = NULL, PxVec4* anisotropy1 = NULL, PxVec4* anisotropy2 = NULL, PxVec4* anisotropy3 = NULL, PxReal anisotropyFactor = 1.0f) = 0; + + /** + \brief Allows to register the host buffers into which the final isosurface triangle mesh will get stored + + \param[in] vertices A host buffer to store the vertices of the isosurface mesh + \param[in] triIndices A host buffer to store the triangles of the isosurface mesh + \param[in] normals A host buffer to store the normals of the isosurface mesh + */ + virtual void setResultBufferHost(PxVec4* vertices, PxU32* triIndices, PxVec4* normals = NULL) = 0; + + /** + \brief Allows to register the host buffers into which the final isosurface triangle mesh will get stored + + \param[in] vertices A device buffer to store the vertices of the isosurface mesh + \param[in] triIndices A device buffer to store the triangles of the isosurface mesh + \param[in] normals A device buffer to store the normals of the isosurface mesh + */ + virtual void setResultBufferDevice(PxVec4* vertices, PxU32* triIndices, PxVec4* normals) = 0; + + /** + \brief Enables or disables the isosurface extractor + + \param[in] enabled The boolean to set the extractor to enabled or disabled + */ + virtual void setEnabled(bool enabled) = 0; + + /** + \brief Allows to query if the isosurface extractor is enabled + + \return True if enabled, false otherwise + */ + virtual bool isEnabled() const = 0; + + /** + \brief Destructor + */ + virtual ~PxIsosurfaceExtractor() {} + }; + + /** + \brief Base class for sparse grid based isosurface extractors. Allows to register the data arrays for the isosurface and to obtain the number vertices/triangles in use. + */ + class PxSparseGridIsosurfaceExtractor : public PxIsosurfaceExtractor + { + /** + \brief Returns the sparse grid parameters. + + \return The sparse grid settings used for the isosurface extraction + */ + virtual PxSparseGridParams getSparseGridParams() const = 0; + + /** + \brief Set the sparse grid parameters + + Allows to configure cell size, number of subgrids etc. + + \param[in] params A collection of settings to control the isosurface grid + */ + virtual void setSparseGridParams(const PxSparseGridParams& params) = 0; + }; + + /** + \brief Default implementation of a particle system callback to trigger the isosurface extraction. A call to fetchResultsParticleSystem() on the + PxScene will synchronize the work such that the caller knows that the post solve task completed. + */ + class PxIsosurfaceCallback : public PxParticleSystemCallback + { + public: + /** + \brief Initializes the isosurface callback + + \param[in] isosurfaceExtractor The isosurface extractor + \param[in] validPhaseMask The valid phase mask marking the phase bits that particles must have set in order to contribute to the isosurface + */ + void initialize(PxIsosurfaceExtractor* isosurfaceExtractor, PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid) + { + mIsosurfaceExtractor = isosurfaceExtractor; + mValidPhaseMask = validPhaseMask; + } + + virtual void onPostSolve(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) + { + mIsosurfaceExtractor->extractIsosurface(reinterpret_cast(gpuParticleSystem.mHostPtr->mUnsortedPositions_InvMass), + gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream, gpuParticleSystem.mHostPtr->mUnsortedPhaseArray, mValidPhaseMask); + } + + virtual void onBegin(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + virtual void onAdvance(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + private: + PxIsosurfaceExtractor* mIsosurfaceExtractor; + PxU32 mValidPhaseMask; + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/physx/include/PxLineStripSkinning.h b/physx/include/PxLineStripSkinning.h new file mode 100644 index 000000000..55740651c --- /dev/null +++ b/physx/include/PxLineStripSkinning.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_LINE_STRIP_SKINNING_H +#define PX_LINE_STRIP_SKINNING_H + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" +#include "foundation/PxMat44.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + class PxHairSystemDesc; + + /** + \brief Specifies the position and binding of a point relative to a line strip such that the point moves with the line during simulation. + */ + struct PxLineStripSkinnedVertex + { + PxVec3 mPosition; //!< The position of the vertex that should move with a line strip. Expressed in the same coordinate system as the line strip points when computing the skinning. + PxU32 mSegmentId; //!< The id of the vertex at the beginning of the line segment to which this point is connected + PxReal mSegmentLocation; //!< Parameter in the range 0...1 that specifies the location on the segment where the base coordinate system gets evaluated at runtime to update the skinned position. + + PxLineStripSkinnedVertex() : mPosition(0.0f), mSegmentId(0), mSegmentLocation(0.0f) + { + } + + PxLineStripSkinnedVertex(const PxVec3& position, PxU32 segmentId, PxReal segmentLocation) : mPosition(position), mSegmentId(segmentId), mSegmentLocation(segmentLocation) + { + } + }; + + /** + \brief Utility class to embed high resolution line strips into low resolution line strips + */ + class PxLineStripSkinning + { + public: + /** + \brief Computes the skinning information used to update the skinned points during simulation + + \param[in] simVertices The simulated vertices in the state in which the skinning information shall be computed. These vertices will eventually drive the skinned vertices + \param[in] simStrandPastEndIndices The index after the last strand vertex for the simulation strands (strand = line strip) + \param[in] nbLineStrips The number of line strips + \param[in] skinnedVertices The positions and segment locations of the skinned vertices in the initial frame. They will keep their position relative to the line strip segment during simulation. + \param[in] nbSkinnedVertices The total number of skinned vertices + \param[out] skinnedVertexInterpolationData Must provide space for one entry per skinned vertex. Contains the location of the skinned vertex relative to the interpolated base frame. The w component encodes the location of the base frame along the line segment. + \param[out] skinningInfoRootStrandDirections Must provide space for one entry per line strip. Contains the direction of the first line segment per line strip during the calculation of the skinning information. + \param[out] skinningInfoStrandStartIndices Must provide space for one entry per line strip. Contains the index of the first skinning vertex in the buffer for every line strip. The skinned vertices must be sorted such that vertices attached to the same line strip are adjacent to each other in the buffer. + \param[in] transform Optional transform that gets applied to the simVertices before computing the skinning information + \param[in] catmullRomAlpha Optional parameter in the range 0...1 that allows to control the curve interpolation. + */ + virtual void initializeInterpolatedVertices(const PxVec4* simVertices, const PxU32* simStrandPastEndIndices, PxU32 nbLineStrips, const PxLineStripSkinnedVertex* skinnedVertices, PxU32 nbSkinnedVertices, + PxVec4* skinnedVertexInterpolationData, PxVec3* skinningInfoRootStrandDirections, PxU32* skinningInfoStrandStartIndices, const PxMat44& transform = PxMat44(PxIdentity), PxReal catmullRomAlpha = 0.5f) = 0; + + /** + \brief Evaluates and updates the skinned positions based on the interpolation data on the GPU. All input arrays are GPU arrays. + \param[in] simVertices The simulation vertices (device pointer) according to which the skinned positions shall be computed. + \param[in] simStrandPastEndIndices Device pointer containing the index after the last strand vertex for the simulation strands (strand = line strip) + \param[in] nbSimStrands The number of line strips + \param[in] skinnedVertexInterpolationData Device pointer containing the location of the skinned vertex relative to the interpolated base frame. The w component encodes the location of the base frame along the line segment. + \param[in] skinningInfoStrandStartIndices Device pointer containing the index of the first skinning vertex in the buffer for every line strip. The skinned vertices must be sorted such that vertices attached to the same line strip are adjacent to each other in the buffer. + \param[in] skinningInfoRootStrandDirections Device pointer containing the direction of the first line segment per line strip during the calculation of the skinning information. + \param[in] nbSkinnedVertices The total number of skinned vertices + \param[out] result The skinned vertex positions where the updated positions will be written + \param[in] stream The cuda stream on which ther kernel call gets scheduled + \param[in] transform Optional device array holding a transform that gets applied to the simVertices before computing the skinning information + \param[in] catmullRomAlpha Optional parameter in the range 0...1 that allows to control the curve interpolation. + */ + virtual void evaluateInterpolatedVertices(const PxVec4* simVertices, const PxU32* simStrandPastEndIndices, PxU32 nbSimStrands, const PxVec4* skinnedVertexInterpolationData, + const PxU32* skinningInfoStrandStartIndices, const PxVec3* skinningInfoRootStrandDirections, PxU32 nbSkinnedVertices, PxVec3* result, CUstream stream, const PxReal* transform = NULL, PxReal catmullRomAlpha = 0.5f) = 0; + + /** + \brief Destructor + */ + virtual ~PxLineStripSkinning() {} + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/physx/include/PxPBDMaterial.h b/physx/include/PxPBDMaterial.h index f58184368..1f63e002f 100644 --- a/physx/include/PxPBDMaterial.h +++ b/physx/include/PxPBDMaterial.h @@ -210,19 +210,6 @@ namespace physx 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 diff --git a/physx/include/PxParticleGpu.h b/physx/include/PxParticleGpu.h index 3201d0150..86e21ed5f 100644 --- a/physx/include/PxParticleGpu.h +++ b/physx/include/PxParticleGpu.h @@ -113,8 +113,6 @@ class PxNeighborhoodIterator */ 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. diff --git a/physx/include/PxParticleNeighborhoodProvider.h b/physx/include/PxParticleNeighborhoodProvider.h new file mode 100644 index 000000000..bfe2c5823 --- /dev/null +++ b/physx/include/PxParticleNeighborhoodProvider.h @@ -0,0 +1,134 @@ +// 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_NEIGHBORHOOD_PROVIDER_H +#define PX_PARTICLE_NEIGHBORHOOD_PROVIDER_H +/** \addtogroup extensions + @{ +*/ + + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" +#include "PxParticleSystem.h" + +#include "foundation/PxArray.h" +#include "PxParticleGpu.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + /** + \brief Computes neighborhood information for a point cloud + */ + class PxParticleNeighborhoodProvider + { + public: + /** + \brief Schedules the compuation of neighborhood information on the specified cuda stream + + \param[in] deviceParticlePos A gpu pointer containing the particle positions + \param[in] numParticles The number of particles + \param[in] stream The stream on which the cuda call gets scheduled + \param[in] devicePhases An optional gpu pointer with particle phases + \param[in] validPhaseMask An optional phase mask to define which particles should be included into the neighborhood computation + \param[in] deviceActiveIndices An optional device pointer containing all indices of particles that are currently active + */ + virtual void buildNeighborhood(PxVec4* deviceParticlePos, const PxU32 numParticles, CUstream stream, PxU32* devicePhases = NULL, + PxU32 validPhaseMask = PxParticlePhaseFlag::eParticlePhaseFluid, const PxU32* deviceActiveIndices = NULL) = 0; + + /** + \brief Gets the maximal number of particles + + \return The maximal number of particles + */ + virtual PxU32 getMaxParticles() const = 0; + + /** + \brief Sets the maximal number of particles + + \param[in] maxParticles The maximal number of particles + */ + virtual void setMaxParticles(PxU32 maxParticles) = 0; + + /** + \brief Gets the maximal number of grid cells + + \return The maximal number of grid cells + */ + virtual PxU32 getMaxGridCells() const = 0; + + /** + \brief Gets the cell size + + \return The cell size + */ + virtual PxReal getCellSize() const = 0; + + /** + \brief Gets the number of grid cells in use + + \return The number of grid cells in use + */ + virtual PxU32 getNumGridCellsInUse() const = 0; + + /** + \brief Sets the maximal number of particles + + \param[in] maxGridCells The maximal number of grid cells + \param[in] cellSize The cell size. Should be equal to 2*contactOffset for PBD particle systems. + */ + virtual void setCellProperties(PxU32 maxGridCells, PxReal cellSize) = 0; + + /** + \brief Releases the instance and its data + */ + virtual void release() = 0; + + /** + \brief Destructor + */ + virtual ~PxParticleNeighborhoodProvider() {} + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/physx/include/PxParticleSolverType.h b/physx/include/PxParticleSolverType.h index 671220ef3..a5c920635 100644 --- a/physx/include/PxParticleSolverType.h +++ b/physx/include/PxParticleSolverType.h @@ -53,8 +53,7 @@ struct PxParticleSolverType { 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. + eMPM = 1 << 2 //!< The MPM (material point method) solver that can handle a variety of materials. See #PxMPMParticleSystem. }; }; diff --git a/physx/include/PxParticleSystem.h b/physx/include/PxParticleSystem.h index 0cabdeac6..1f9859d97 100644 --- a/physx/include/PxParticleSystem.h +++ b/physx/include/PxParticleSystem.h @@ -36,6 +36,7 @@ #include "PxActor.h" #include "PxFiltering.h" #include "PxParticleSystemFlag.h" +#include "foundation/PxArray.h" #include "cudamanager/PxCudaTypes.h" @@ -109,6 +110,69 @@ class PxParticleSystemCallback virtual ~PxParticleSystemCallback() {} }; +/** +\brief Special callback that forwards calls to arbitrarily many sub-callbacks +*/ +class PxMultiCallback : public PxParticleSystemCallback +{ +private: + PxArray mCallbacks; + +public: + PxMultiCallback() : mCallbacks(0) {} + + virtual void onPostSolve(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) PX_OVERRIDE + { + for (PxU32 i = 0; i < mCallbacks.size(); ++i) + mCallbacks[i]->onPostSolve(gpuParticleSystem, stream); + } + + virtual void onBegin(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) PX_OVERRIDE + { + for (PxU32 i = 0; i < mCallbacks.size(); ++i) + mCallbacks[i]->onBegin(gpuParticleSystem, stream); + } + + virtual void onAdvance(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) PX_OVERRIDE + { + for (PxU32 i = 0; i < mCallbacks.size(); ++i) + mCallbacks[i]->onAdvance(gpuParticleSystem, stream); + } + + /** + \brief Adds a callback + + \param[in] callback The callback to add + \return True if the callback was added + */ + bool addCallback(PxParticleSystemCallback* callback) + { + if (mCallbacks.find(callback) != mCallbacks.end()) + return false; + mCallbacks.pushBack(callback); + return true; + } + + /** + \brief Removes a callback + + \param[in] callback The callback to remove + \return True if the callback was removed + */ + bool removeCallback(const PxParticleSystemCallback* callback) + { + for (PxU32 i = 0; i < mCallbacks.size(); ++i) + { + if (mCallbacks[i] == callback) + { + mCallbacks.remove(i); + return true; + } + } + return false; + } +}; + /** \brief Flags which control the behaviour of a particle system. @@ -390,22 +454,6 @@ class PxParticleSystem : public PxActor */ 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*. @@ -424,7 +472,7 @@ class PxParticleSystem : public PxActor /** \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. + \return The GPU index, if the particle system is in a scene and PxSceneFlag::eENABLE_DIRECT_GPU_API is set, or 0xFFFFFFFF otherwise. */ virtual PxU32 getGpuParticleSystemIndex() = 0; diff --git a/physx/include/PxPhysics.h b/physx/include/PxPhysics.h index 21fe137f1..4ff56306b 100644 --- a/physx/include/PxPhysics.h +++ b/physx/include/PxPhysics.h @@ -38,7 +38,6 @@ #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 @@ -67,10 +66,6 @@ class PxFoundation; class PxPruningStructure; class PxBVH; -/** - * @deprecated - */ -typedef PX_DEPRECATED PxBVH PxBVHStructure; class PxParticleClothBuffer; class PxParticleRigidBuffer; @@ -83,9 +78,9 @@ class PxSoftBodyMesh; 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. +You can get an instance of this class by calling PxCreatePhysics(). -@see PxCreatePhysics() PxCreateBasePhysics() PxScene +@see PxCreatePhysics() PxScene */ class PxPhysics { @@ -148,30 +143,6 @@ class PxPhysics */ virtual PxAggregate* createAggregate(PxU32 maxActor, PxU32 maxShape, PxAggregateFilterHint filterHint) = 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. - - \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 - */ - 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. @@ -281,7 +252,7 @@ class PxPhysics \param [in] stream The heightfield mesh stream. \return The new heightfield. - @see PxHeightField PxHeightField.release() PxInputStream PxRegisterHeightFields + @see PxHeightField PxHeightField.release() PxInputStream */ virtual PxHeightField* createHeightField(PxInputStream& stream) = 0; @@ -357,14 +328,6 @@ class PxPhysics */ virtual PxBVH* createBVH(PxInputStream& stream) = 0; - /** - * @deprecated - */ - PX_DEPRECATED PX_FORCE_INLINE PxBVH* createBVHStructure(PxInputStream& stream) - { - return createBVH(stream); - } - /** \brief Return the number of bounding volume hierarchies that currently exist. @@ -374,14 +337,6 @@ class PxPhysics */ virtual PxU32 getNbBVHs() const = 0; - /** - * @deprecated - */ - PX_DEPRECATED PX_FORCE_INLINE PxU32 getNbBVHStructures() const - { - return getNbBVHs(); - } - /** \brief Writes the array of bounding volume hierarchy pointers to a user buffer. @@ -398,14 +353,6 @@ class PxPhysics */ 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 */ @@ -656,7 +603,7 @@ class PxPhysics \return the new articulation - @see PxArticulationReducedCoordinate, PxRegisterArticulationsReducedCoordinate + @see PxArticulationReducedCoordinate */ virtual PxArticulationReducedCoordinate* createArticulationReducedCoordinate() = 0; @@ -731,30 +678,6 @@ class PxPhysics */ 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. @@ -1065,44 +988,7 @@ class PxPhysics @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 */ @@ -1187,70 +1073,6 @@ class PxPhysics } // namespace physx #endif -/** -\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 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_DEPRECATED PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterArticulationsReducedCoordinate(physx::PxPhysics& physics); - -/** -\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 -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 -::PxRegisterHeightFields(), will result in an error. - -@deprecated -*/ -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 -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 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 - 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 - 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, PxOmniPvd - -@deprecated -*/ -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. @@ -1259,10 +1081,6 @@ 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 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 -modules manually. - \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 @@ -1276,30 +1094,19 @@ modules manually. set in the PxOmniPvd object. \return PxPhysics instance on success, NULL if operation failed -@see PxPhysics, PxCreateBasePhysics, PxRegisterArticulationsReducedCoordinate, PxRegisterHeightFields +@see PxPhysics */ -PX_INLINE physx::PxPhysics* PxCreatePhysics(physx::PxU32 version, - physx::PxFoundation& foundation, - const physx::PxTolerancesScale& scale, - bool trackOutstandingAllocations = false, - physx::PxPvd* pvd = NULL, - physx::PxOmniPvd* omniPvd = NULL) -{ - physx::PxPhysics* physics = PxCreateBasePhysics(version, foundation, scale, trackOutstandingAllocations, pvd, omniPvd); - if (!physics) - return NULL; - - PxRegisterArticulationsReducedCoordinate(*physics); - PxRegisterHeightFields(*physics); - - return physics; -} - +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxPhysics* PxCreatePhysics(physx::PxU32 version, + physx::PxFoundation& foundation, + const physx::PxTolerancesScale& scale, + bool trackOutstandingAllocations = false, + physx::PxPvd* pvd = NULL, + physx::PxOmniPvd* omniPvd = NULL); /** \brief Retrieves the Physics SDK after it has been created. -Before using this function the user must call #PxCreatePhysics() or #PxCreateBasePhysics(). +Before using this function the user must call #PxCreatePhysics(). \note The behavior of this method is undefined if the Physics SDK instance has not been created already. */ diff --git a/physx/include/PxPhysicsAPI.h b/physx/include/PxPhysicsAPI.h index d66780805..32c9638b2 100644 --- a/physx/include/PxPhysicsAPI.h +++ b/physx/include/PxPhysicsAPI.h @@ -190,7 +190,6 @@ Alternatively, one can instead directly #include a subset of the below files. #include "PxVisualizationParameter.h" #include "PxPruningStructure.h" #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -#include "PxCustomParticleSystem.h" #include "PxFEMCloth.h" #include "PxFEMClothMaterial.h" #include "PxFLIPParticleSystem.h" diff --git a/physx/include/PxQueryFiltering.h b/physx/include/PxQueryFiltering.h index 1ed8002c9..47fb9314a 100644 --- a/physx/include/PxQueryFiltering.h +++ b/physx/include/PxQueryFiltering.h @@ -184,23 +184,7 @@ class PxQueryFilterCallback \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( - const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) = 0; - - /** - \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. - \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; - } + virtual PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) = 0; /** \brief This filter callback is executed if the exact intersection test returned true and PxQueryFlag::ePOSTFILTER flag was set. @@ -211,12 +195,7 @@ class PxQueryFilterCallback \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, const PxShape* shape, const PxRigidActor* actor) - { - PX_UNUSED(shape); - PX_UNUSED(actor); - return postFilter(filterData, hit); - } + virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit, const PxShape* shape, const PxRigidActor* actor) = 0; /** \brief virtual destructor diff --git a/physx/include/PxRigidBody.h b/physx/include/PxRigidBody.h index 4d0ecafa5..497970472 100644 --- a/physx/include/PxRigidBody.h +++ b/physx/include/PxRigidBody.h @@ -328,7 +328,7 @@ class PxRigidBody : public PxRigidActor Zero represents no damping. The damping coefficient must be nonnegative. - Default: 0.0 + Default: 0.05 for PxArticulationLink, 0.0 for PxRigidDynamic \param[in] linDamp Linear damping coefficient. Range: [0, PX_MAX_F32) @@ -402,14 +402,14 @@ class PxRigidBody : public PxRigidActor \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. + Higher linear velocities are clamped to this value. - Note: The angular velocity is clamped to the set value before the solver, which means that + Note: The linear velocity is clamped to the set value before the solver, which means that the limit may still be momentarily exceeded. - Default: PX_MAX_F32 + Default: 100*PxTolerancesScale::length for PxArticulationLink, 1e^16 for PxRigidDynamic - \param[in] maxLinVel Max allowable linear velocity for actor. Range: [0, PX_MAX_F32) + \param[in] maxLinVel Max allowable linear velocity for actor. Range: [0, 1e^16) @see getMaxAngularVelocity() */ @@ -436,9 +436,11 @@ class PxRigidBody : public PxRigidActor Note: The angular velocity is clamped to the set value before the solver, which means that the limit may still be momentarily exceeded. - Default: 100.0 + Default: 50.0 for PxArticulationLink, 100.0 for PxRigidDynamic + + Range: [0, 1e^16) - \param[in] maxAngVel Max allowable angular velocity for actor. Range: [0, PX_MAX_F32) + \param[in] maxAngVel Max allowable angular velocity for actor. @see getMaxAngularVelocity() */ diff --git a/physx/include/PxScene.h b/physx/include/PxScene.h index a99d5cdf5..838198fd9 100644 --- a/physx/include/PxScene.h +++ b/physx/include/PxScene.h @@ -255,6 +255,29 @@ class PxScene : public PxSceneSQSystem */ virtual PxU32 getTimestamp() const = 0; + /** + \brief Sets a name string for the Scene 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. + + Default: NULL + + @see getName() + */ + virtual void setName(const char* name) = 0; + + /** + \brief Retrieves the name string set with setName(). + + \return Name string associated with the Scene. + + @see setName() + */ + virtual const char* getName() const = 0; + //@} /************************************************************************************************/ @@ -1674,7 +1697,7 @@ class PxScene : public PxSceneSQSystem \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; + virtual void copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyGpuDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent = NULL) = 0; /** @@ -1687,11 +1710,12 @@ class PxScene : public PxSceneSQSystem \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; + virtual void applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyGpuDataFlag::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. + \brief Copy rigid body contact data from the internal GPU buffer to a user-provided device buffer. + \note This function only reports contact data for actor pairs where both actors are either rigid bodies or articulations. \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 @@ -1700,7 +1724,7 @@ class PxScene : public PxSceneSQSystem \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. @@ -1721,6 +1745,22 @@ class PxScene : public PxSceneSQSystem */ virtual void applyActorData(void* data, PxGpuActorPair* index, PxActorCacheFlag::Enum flag, const PxU32 nbUpdatedActors, void* waitEvent = NULL, void* signalEvent = NULL) = 0; + + /** + \brief Evaluate sample point distances on sdf shapes + \param[in] sdfShapeIds The shapes ids in a gpu buffer (must be triangle mesh shapes with SDFs) which specify the shapes from which the sdf information is taken + \param[in] nbShapes The number of shapes + \param[in] localSamplePointsConcatenated User-provided gpu buffer containing the sample point locations for every shape in the shapes local space. The buffer stride is maxPointCount. + \param[in] samplePointCountPerShape Gpu buffer containing the number of sample points for every shape + \param[in] maxPointCount The maximum value in the array samplePointCountPerShape + \param[out] localGradientAndSDFConcatenated The gpu buffer where the evaluated distances and gradients in SDF local space get stored. It has the same structure as localSamplePointsConcatenated. + \param[in] event User-provided event for the user to sync + */ + virtual void evaluateSDFDistances(const PxU32* sdfShapeIds, const PxU32 nbShapes, const PxVec4* localSamplePointsConcatenated, + const PxU32* samplePointCountPerShape, const PxU32 maxPointCount, PxVec4* localGradientAndSDFConcatenated, void* event = NULL) = 0; + + + /** \brief Compute dense Jacobian matrices for specified articulations on the GPU. diff --git a/physx/include/PxSceneDesc.h b/physx/include/PxSceneDesc.h index de8303c85..f0b190fc1 100644 --- a/physx/include/PxSceneDesc.h +++ b/physx/include/PxSceneDesc.h @@ -88,7 +88,7 @@ struct PxSolverType enum Enum { ePGS, //!< Projected Gauss-Seidel iterative solver - eTGS //!< Default Temporal Gauss-Seidel solver + eTGS //!< Temporal Gauss-Seidel solver }; }; @@ -278,18 +278,38 @@ struct PxSceneFlag */ eENABLE_FRICTION_EVERY_ITERATION = (1 << 15), + /* + \brief Enables the direct-GPU API. Raising this flag is only allowed if eENABLE_GPU_DYNAMICS is raised and + PxBroadphaseType::eGPU is used. + + This is useful if your application only needs to communicate to the GPU via GPU buffers. Can be significantly + faster. + + \note Enabling the direct-GPU API will disable the readback of simulation state from GPU to CPU. Simulation outputs + can only be accessed using the direct-GPU API functions in PxScene (PxScene::copyBodyData(), PxScene::copyArticulationData(), + PxScene::copySoftbodyData(), PxScene::copyContactData()), and reading state directly from the actor is not allowed. + + \note This flag is not mutable and must be set in PxSceneDesc at scene creation. + + */ + eENABLE_DIRECT_GPU_API = (1 << 16), + /* \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 + + @deprecated. Use PxSceneFlag::eENABLE_DIRECT_GPU_API instead. */ - eSUPPRESS_READBACK = (1<<16), + eSUPPRESS_READBACK = eENABLE_DIRECT_GPU_API, /* \brief Forces GPU readback of articulation data when user raise eSUPPRESS_READBACK. + + @deprecated. There will be no replacement. */ eFORCE_READBACK = (1 << 17), - eMUTABLE_FLAGS = eENABLE_ACTIVE_ACTORS|eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS|eSUPPRESS_READBACK + eMUTABLE_FLAGS = eENABLE_ACTIVE_ACTORS|eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS }; }; @@ -1021,7 +1041,7 @@ PX_INLINE bool PxSceneDesc::isValid() const if(!gpuDynamicsConfig.isValid()) return false; - if (flags & PxSceneFlag::eSUPPRESS_READBACK) + if (flags & PxSceneFlag::eENABLE_DIRECT_GPU_API) { if(!(flags & PxSceneFlag::eENABLE_GPU_DYNAMICS && broadPhaseType == PxBroadPhaseType::eGPU)) return false; diff --git a/physx/include/PxShape.h b/physx/include/PxShape.h index 48ecf297e..464c099bb 100644 --- a/physx/include/PxShape.h +++ b/physx/include/PxShape.h @@ -181,189 +181,6 @@ class PxShape : public PxRefCounted */ virtual const PxGeometry& 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. - - \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 getBoxGeometry(PxBoxGeometry& geometry) const - { - return getGeometryT(PxGeometryType::eBOX, 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 getSphereGeometry(PxSphereGeometry& geometry) const - { - return getGeometryT(PxGeometryType::eSPHERE, 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 getCapsuleGeometry(PxCapsuleGeometry& geometry) const - { - return getGeometryT(PxGeometryType::eCAPSULE, 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 getPlaneGeometry(PxPlaneGeometry& geometry) const - { - return getGeometryT(PxGeometryType::ePLANE, 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 getConvexMeshGeometry(PxConvexMeshGeometry& geometry) const - { - return getGeometryT(PxGeometryType::eCONVEXMESH, 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 getTriangleMeshGeometry(PxTriangleMeshGeometry& geometry) const - { - return getGeometryT(PxGeometryType::eTRIANGLEMESH, 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 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. @@ -701,6 +518,17 @@ class PxShape : public PxRefCounted */ virtual PxReal getMinTorsionalPatchRadius() const = 0; + /** + \brief Gets internal shape id + + The internal shape id can be used to reference a specific shape when processing data on the gpu. + + \return The shape id + + @see PxScene evaluateSDFDistances() + */ + virtual PxU32 getInternalShapeIndex() const = 0; + /************************************************************************************************/ /** @@ -774,16 +602,6 @@ class PxShape : public PxRefCounted 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/physx/include/PxSmoothing.h b/physx/include/PxSmoothing.h new file mode 100644 index 000000000..12269726b --- /dev/null +++ b/physx/include/PxSmoothing.h @@ -0,0 +1,190 @@ +// 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_SMOOTHING_H +#define PX_SMOOTHING_H +/** \addtogroup extensions + @{ +*/ + + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" +#include "PxParticleSystem.h" + +#include "foundation/PxArray.h" +#include "PxParticleGpu.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + class PxgKernelLauncher; + class PxParticleNeighborhoodProvider; + + /** + \brief Ccomputes smoothed positions for a particle system to improve rendering quality + */ + class PxSmoothedPositionGenerator + { + public: + /** + \brief Schedules the compuation of smoothed positions on the specified cuda stream + + \param[in] gpuParticleSystem A gpu pointer to access particle system data + \param[in] numParticles The number of particles + \param[in] stream The stream on which the cuda call gets scheduled + */ + virtual void generateSmoothedPositions(PxGpuParticleSystem* gpuParticleSystem, PxU32 numParticles, CUstream stream) = 0; + + /** + \brief Schedules the compuation of smoothed positions on the specified cuda stream + + \param[in] particlePositionsGpu A gpu pointer containing the particle positions + \param[in] neighborhoodProvider A neighborhood provider object that supports fast neighborhood queries + \param[in] numParticles The number of particles + \param[in] particleContactOffset The particle contact offset + \param[in] stream The stream on which the cuda call gets scheduled + */ + virtual void generateSmoothedPositions(PxVec4* particlePositionsGpu, PxParticleNeighborhoodProvider& neighborhoodProvider, PxU32 numParticles, PxReal particleContactOffset, CUstream stream) = 0; + + /** + \brief Set a host buffer that holds the smoothed position data after the timestep completed + + \param[in] smoothedPositions A host buffer with memory for all particles already allocated + */ + virtual void setResultBufferHost(PxVec4* smoothedPositions) = 0; + + /** + \brief Set a device buffer that holds the smoothed position data after the timestep completed + + \param[in] smoothedPositions A device buffer with memory for all particles already allocated + */ + virtual void setResultBufferDevice(PxVec4* smoothedPositions) = 0; + + /** + \brief Sets the intensity of the position smoothing effect + + \param[in] smoothingStrenght The strength of the smoothing effect + */ + virtual void setSmoothing(float smoothingStrenght) = 0; + + /** + \brief Gets the maximal number of particles + + \return The maximal number of particles + */ + virtual PxU32 getMaxParticles() const = 0; + + /** + \brief Sets the maximal number of particles + + \param[in] maxParticles The maximal number of particles + */ + virtual void setMaxParticles(PxU32 maxParticles) = 0; + + /** + \brief Gets the device pointer for the smoothed positions. Only available after calling setResultBufferHost or setResultBufferDevice + + \return The device pointer for the smoothed positions + */ + virtual PxVec4* getSmoothedPositionsDevicePointer() const = 0; + + /** + \brief Enables or disables the smoothed position generator + + \param[in] enabled The boolean to set the generator to enabled or disabled + */ + virtual void setEnabled(bool enabled) = 0; + + /** + \brief Allows to query if the smoothed position generator is enabled + + \return True if enabled, false otherwise + */ + virtual bool isEnabled() const = 0; + + /** + \brief Releases the instance and its data + */ + virtual void release() = 0; + + /** + \brief Destructor + */ + virtual ~PxSmoothedPositionGenerator() {} + }; + + /** + \brief Default implementation of a particle system callback to trigger smoothed position calculations. A call to fetchResultsParticleSystem() on the + PxScene will synchronize the work such that the caller knows that the post solve task completed. + */ + class PxSmoothedPositionCallback : public PxParticleSystemCallback + { + public: + /** + \brief Initializes the smoothing callback + + \param[in] smoothedPositionGenerator The smoothed position generator + */ + void initialize(PxSmoothedPositionGenerator* smoothedPositionGenerator) + { + mSmoothedPositionGenerator = smoothedPositionGenerator; + } + + virtual void onPostSolve(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) + { + if (mSmoothedPositionGenerator) + { + mSmoothedPositionGenerator->generateSmoothedPositions(gpuParticleSystem.mDevicePtr, gpuParticleSystem.mHostPtr->mCommonData.mMaxParticles, stream); + } + } + + virtual void onBegin(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + virtual void onAdvance(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + private: + PxSmoothedPositionGenerator* mSmoothedPositionGenerator; + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/physx/include/PxSoftBody.h b/physx/include/PxSoftBody.h index c69ffd119..ce16f5882 100644 --- a/physx/include/PxSoftBody.h +++ b/physx/include/PxSoftBody.h @@ -34,6 +34,7 @@ #include "PxFEMParameter.h" #include "PxActor.h" #include "PxConeLimitedConstraint.h" +#include "PxSoftBodyFlag.h" #if !PX_DOXYGEN namespace physx @@ -46,7 +47,6 @@ namespace physx #endif class PxCudaContextManager; - class PxBuffer; class PxTetrahedronMesh; class PxSoftBodyAuxData; class PxFEMCloth; @@ -57,28 +57,6 @@ namespace physx */ #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 */ @@ -91,7 +69,7 @@ namespace physx 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. + ePARTIALLY_KINEMATIC = 1 << 5 //!< Enables partially kinematic motion of the collision and simulation mesh. }; }; @@ -108,7 +86,7 @@ namespace physx /** \brief Set a single softbody flag - + \param[in] flag The flag to set or clear \param[in] val The new state of the flag */ @@ -133,7 +111,7 @@ namespace physx \param[in] parameters The FEM parameters */ - virtual void setParameter(const PxFEMParameters parameters) = 0; + virtual void setParameter(PxFEMParameters parameters) = 0; /** \brief Get parameter for FEM internal solve @@ -143,80 +121,179 @@ namespace physx virtual PxFEMParameters getParameter() const = 0; /** - \brief Issues a read command to the PxSoftBody. + \brief Get a pointer to a device buffer containing positions and inverse masses of the + collision mesh. - Read operations are scheduled and then flushed in PxScene::simulate(). - Read operations are known to be finished when PxBuffer::map() returns. + This function returns a pointer to device memory for the positions and inverse masses of + the soft body. This buffer is used to both initialize/update the collision mesh vertices + of the soft body and read the simulation results. - PxSoftBodyData::ePOSITION_INVMASS, PxSoftBodyData::eSIM_POSITION_INVMASS and PxSoftBodyData::eSIM_VELOCITY can be read from the PxSoftBody. + \note It is mandatory to call PxSoftBody::markDirty() with PxSoftBodyDataFlag::ePOSITION_INVMASS + when updating data in this buffer. - 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(). + The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary. + The first 3 floats specify the vertex position and the last float contains the inverse mass of the + vertex. The size of the buffer is the number of vertices of the collision mesh * sizeof(PxVec4). + @see PxTetrahedronMesh::getNbVertices(). - \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. + The device memory pointed to by this pointer is allocated when a shape is attached to the + softbody. Calling PxSoftBody::detachShape() will deallocate the memory. - @see writeData(), PxBuffer, PxSoftBodyData + It is not allowed to write to this buffer from the start of the PxScene::simulate() call + until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks + have finished, reading the data during a completion task is explicitly allowed. The + simulation will read and write directly from/into this buffer. + + It is the users' responsibility to initialize this buffer with the initial positions of + the vertices of the collision mesh. See PxSoftBodyExt::allocateAndInitializeHostMirror(), + PxSoftBodyExt::copyToDevice(). + + \return PxVec4* A pointer to a device buffer containing positions and inverse masses of + the collision mesh. */ - virtual void readData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush = false) = 0; + virtual PxVec4* getPositionInvMassBufferD() = 0; /** - \brief Issues a read command to the PxSoftBody. + \brief Get a pointer to a device buffer containing rest positions of the collision mesh vertices. - Read operations are scheduled and then flushed in PxScene::simulate(). - Read operations are known to be finished when PxBuffer::map() returns. + This function returns a pointer to device memory for the rest positions of the softbody collision + mesh. This buffer is used to initialize the rest positions of the collision mesh vertices. - PxSoftBodyData::ePOSITION_INVMASS, PxSoftBodyData::eSIM_POSITION_INVMASS and PxSoftBodyData::eSIM_VELOCITY can be read from the PxSoftBody. + \note It is mandatory to call PxSoftBody::markDirty() with PxSoftBodyDataFlag::eREST_POSITION when + updating data in this buffer. - 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(). + The simulation expects 4 floats per vertex, aligned to a 16B boundary. The first 3 specify the + rest position. The last float is unused. The size of the buffer is the number of vertices in + the collision mesh * sizeof(PxVec4). @see PxTetrahedronMesh::getNbVertices(). - \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. + The device memory pointed to by this pointer is allocated when a shape is attached to the softbody. + Calling PxSoftBody::detachShape() will deallocate the memory. - @see writeData(), PxSoftBodyData - */ - virtual void readData(PxSoftBodyData::Enum flags, bool flush = false) = 0; + It is not allowed to write data into this buffer from the start of PxScene::simulate() until + PxScene::fetchResults() returns. + + It is the users' responsibility to initialize this buffer with the initial rest positions of the + vertices of the collision mesh. See PxSoftBodyExt::allocateAndInitializeHostMirror(), + PxSoftBodyExt::copyToDevice(). + + \return PxVec4* A pointer to a device buffer containing the rest positions of the collision mesh. + */ + virtual PxVec4* getRestPositionBufferD() = 0; /** - \brief Issues a write command to the PxSoftBody. + \brief Get a pointer to a device buffer containing the vertex positions of the simulation mesh. - Write operations are scheduled and then flushed in PxScene::simulate(). - Write operations are known to be finished when PxScene::fetchResult() returns. + This function returns a pointer to device memory for the positions and inverse masses of the softbody + simulation mesh. This buffer is used to both initialize/update the simulation mesh vertices + of the softbody and read the simulation results. - 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. + \note It is mandatory to call PxSoftBody::markDirty() with PxSoftBodyDataFlag::eSIM_POSITION_INVMASS when + updating data in this buffer. - 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. + The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary. The + first 3 floats specify the positions and the last float specifies the inverse mass of the vertex. + The size of the buffer is the number of vertices of the simulation mesh * sizeof(PxVec4). + @see PxTetrahedronMesh::getNbVertices(). - \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. + The device memory pointed to by this pointer is allocated when a simulation mesh is attached to the + softbody. Calling PxSoftBody::detachSimulationMesh() will deallocate the memory. - @see readData(), PxBuffer, PxSoftBodyData, PxSoftBodyExt::commit + It is not allowed to write to this buffer from the start of the PxScene::simulate() call + until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks + have finished, reading the data during a completion task is explicitly allowed. The + simulation will read and write directly from/into this buffer. + + It is the users' responsibility to initialize this buffer with the initial positions of + the vertices of the simulation mesh. See PxSoftBodyExt::allocateAndInitializeHostMirror(), + PxSoftBodyExt::copyToDevice(). + + \return PxVec4* A pointer to a device buffer containing the vertex positions of the simulation mesh. */ - virtual void writeData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush = false) = 0; + virtual PxVec4* getSimPositionInvMassBufferD() = 0; /** - \brief Issues a write command to the PxSoftBody. + \brief Get a pointer to a device buffer containing the vertex velocities of the simulation mesh. - Write operations are scheduled and then flushed in PxScene::simulate(). - Write operations are known to be finished when PxScene::fetchResult() returns. + This function returns a pointer to device memory for the velocities of the softbody simulation mesh + vertices. This buffer is used to both initialize/update the simulation mesh vertex velocities + of the soft body and read the simulation results. - 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. + \note It is mandatory to call PxSoftBody::markDirty() with PxSoftBodyDataFlag::eSIM_VELOCITY when + updating data in this buffer. - 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(). + The simulation expects 4 consecutive floats for each vertex, aligned to a 16B boundary. The + first 3 specify the velocities for each vertex. The final float is unused. The size of the + buffer is the number of vertices of the simulation mesh * sizeof(PxVec4). + @see PxTetrahedronMesh::getNbVertices(). - \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. + The device memory pointed to by this pointer is allocated when a simulation mesh is attached to the + softbody. Calling PxSoftBody::detachSimulationMesh() will deallocate the memory. - @see readData(), PxSoftBodyData + It is not allowed to write to this buffer from the start of the PxScene::simulate() call + until PxScene::fetchResults() returns. Reading the data is allowed once all the PhysX tasks + have finished, reading the data during a completion task is explicitly allowed. The + simulation will read and write directly from/into this buffer. + + It is the users' responsibility to initialize this buffer with the initial velocities of + the vertices of the simulation mesh. See PxSoftBodyExt::allocateAndInitializeHostMirror(), + PxSoftBodyExt::copyToDevice(). + + \return PxVec4* A pointer to a device buffer containing the vertex velocities of the simulation mesh. */ - virtual void writeData(PxSoftBodyData::Enum flags, bool flush = false) = 0; + virtual PxVec4* getSimVelocityBufferD() = 0; + + /** + \brief Marks per-vertex simulation state and configuration buffers dirty to signal to the simulation + that changes have been made. + + Calling this function is mandatory to notify the simulation of changes made in the positionInvMass, + simPositionInvMass, simVelocity and rest position buffers. + + This function can be called multiple times, and dirty flags are accumulated internally until + PxScene::simulate() is called. + + @see getPositionInvMassBufferD, getSimVelocityBufferD, getRestPositionBufferD, getSimPositionInvMassBufferD + + \param flags The buffers that have been updated. + */ + virtual void markDirty(PxSoftBodyDataFlags flags) = 0; + + /** + \brief Set the device buffer containing the kinematic targets for this softbody. + + This function sets the kinematic targets for a softbody to a user-provided device buffer. This buffer is + read by the simulation to obtain the target position for each vertex of the simulation mesh. + + The simulation expects 4 consecutive float for each vertex, aligned to a 16B boundary. The first 3 + floats specify the target positions. The last float determines (together with the flag argument) + if the target is active or not. + For a softbody with the flag PxSoftBodyFlag::eKINEMATIC raised, all target positions are considered + valid. In case a softbody has the PxSoftBodyFlag::ePARTIALLY_KINEMATIC raised, only target + positions whose corresponding last float has been set to 0.f are considered valid target positions. + @see PxConfigureSoftBodyKinematicTarget + + The size of the buffer is the number of vertices of the simulation mesh * sizeof(PxVec4). + @see PxTetrahedronMesh::getNbVertices(). + + It is the users responsibility to manage the memory pointed to by the input to this function, + as well as guaranteeing the integrity of the input data. In particular, this means that it is + not allowed to write this data from from the start of PxScene::simulate() until PxScene::fetchResults() + returns. The memory is not allowed to be deallocated until PxScene::fetchResults() returns. + + Calling this function with a null pointer for the positions will clear the input and resume normal + simulation. This will also clear both the PxSoftBodyFlag::eKINEMATIC and PxSoftBodyFlag::ePARTIALLY_KINEMATIC + flags of the softbody. + + This call is persistent across calls to PxScene::simulate(). Once this function is called, the + simulation will look up the target positions from the same buffer for every call to PxScene::simulate(). + The user is allowed to update the target positions without calling this function again, provided that + the synchronization requirements are adhered to (no changes between start of PxScene::simulate() until + PxScene::fetchResults() returns). + + \param positions A pointer to a device buffer containing the kinematic targets for this softbody. + \param flags Flags specifying the type of kinematic softbody: this function ignores all flags except PxSoftBodyFlag::eKINEMATIC and PxSoftBodyFlag::ePARTIALLY_KINEMATIC. + */ + virtual void setKinematicTargetBufferD(const PxVec4* positions, PxSoftBodyFlags flags) = 0; /** \brief Return the cuda context manager @@ -325,6 +402,9 @@ namespace physx */ virtual PxTetrahedronMesh* getCollisionMesh() = 0; + //! \brief Const version of getCollisionMesh() + virtual const PxTetrahedronMesh* getCollisionMesh() const = 0; + /** \brief Retrieves the simulation mesh pointer. @@ -334,6 +414,9 @@ namespace physx */ virtual PxTetrahedronMesh* getSimulationMesh() = 0; + //! \brief Const version of getSimulationMesh() + virtual const PxTetrahedronMesh* getSimulationMesh() const = 0; + /** \brief Retrieves the simulation state pointer. @@ -344,6 +427,8 @@ namespace physx */ virtual PxSoftBodyAuxData* getSoftBodyAuxData() = 0; + //! \brief const version of getSoftBodyAuxData() + virtual const PxSoftBodyAuxData* getSoftBodyAuxData() const = 0; /** \brief Attaches a shape @@ -563,10 +648,11 @@ namespace physx \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. + \param[in] constraintOffset Offsets the cone and distance limit constraint along its axis, in order to specify the location of the cone tip. \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; + PxConeLimitedConstraint* constraint = NULL, PxReal constraintOffset = 0.0f) = 0; /** \brief Releases an attachment between a soft body and the other soft body. @@ -599,7 +685,6 @@ namespace physx */ 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. @@ -615,10 +700,11 @@ namespace physx \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. + \param[in] constraintOffset Offsets the cone and distance limit constraint along its axis, in order to specify the location of the cone tip. \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; + PxConeLimitedConstraint* constraint = NULL, PxReal constraintOffset = 0.0f) = 0; /** \brief Releases an attachment between a cloth and a soft body. @@ -634,71 +720,6 @@ namespace physx */ 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. @@ -722,13 +743,45 @@ namespace physx 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); } }; + /** + \brief Adjusts a softbody kinematic target such that it is properly set as active or inactive. Inactive targets will not affect vertex position, they are ignored by the solver. + + \param[in] target The kinematic target + \param[in] isActive A boolean indicating if the returned target should be marked as active or not + \return The target with adjusted w component + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4 PxConfigureSoftBodyKinematicTarget(const PxVec4& target, bool isActive) + { + PxVec4 result = target; + if (isActive) + result.w = 0.0f; + else + { + //Any non-zero value will mark the target as inactive + if (result.w == 0.0f) + result.w = 1.0f; + } + return result; + } + + /** + \brief Sets up a softbody kinematic target such that it is properly set as active or inactive. Inactive targets will not affect vertex position, they are ignored by the solver. + + \param[in] target The kinematic target + \param[in] isActive A boolean indicating if the returned target should be marked as active or not + \return The target with configured w component + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4 PxConfigureSoftBodyKinematicTarget(const PxVec3& target, bool isActive) + { + return PxConfigureSoftBodyKinematicTarget(PxVec4(target, 0.0f), isActive); + } + #if PX_VC #pragma warning(pop) #endif diff --git a/physx/include/PxSoftBodyFlag.h b/physx/include/PxSoftBodyFlag.h index ce19e5d67..64f05c428 100644 --- a/physx/include/PxSoftBodyFlag.h +++ b/physx/include/PxSoftBodyFlag.h @@ -37,29 +37,50 @@ namespace physx { #endif - /** - \brief These flags determine what data is read or written to the gpu softbody. +/** +\brief Identifies the buffers of a PxSoftBody. - @see PxScene::copySoftBodyData, PxScene::applySoftBodyData - */ - class PxSoftBodyDataFlag +@see PxSoftBody::markDirty() +*/ +struct PxSoftBodyDataFlag +{ + enum Enum { - 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 - }; + eNONE = 0, + + ePOSITION_INVMASS = 1 << 0, //!< The collision mesh's positions + eSIM_POSITION_INVMASS = 1 << 1, //!< The simulation mesh's positions and inverse masses + eSIM_VELOCITY = 1 << 2, //!< The simulation mesh's velocities + eREST_POSITION_INVMASS = 1 << 3, //!< The collision mesh's rest positions + + eALL = ePOSITION_INVMASS | eSIM_POSITION_INVMASS | eSIM_VELOCITY | eREST_POSITION_INVMASS }; - +}; + +typedef PxFlags PxSoftBodyDataFlags; + +/** +\brief These flags determine what data is read or written when using PxScene::copySoftBodyData() +or PxScene::applySoftBodyData. + +@see PxScene::copySoftBodyData, PxScene::applySoftBodyData +*/ +class PxSoftBodyGpuDataFlag +{ +public: + enum Enum + { + eTET_INDICES = 0, //!< The collision mesh tetrahedron indices (quadruples of int32) + eTET_REST_POSES = 1, //!< The collision mesh tetrahedron rest poses (float 3x3 matrices) + eTET_ROTATIONS = 2, //!< The collision mesh tetrahedron orientations (quaternions, quadruples of float) + eTET_POSITION_INV_MASS = 3, //!< The collision mesh vertex positions and their inverted mass in the 4th component (quadruples of float) + eSIM_TET_INDICES = 4, //!< The simulation mesh tetrahedron indices (quadruples of int32) + eSIM_TET_ROTATIONS = 5, //!< The simulation mesh tetrahedron orientations (quaternions, quadruples of float) + eSIM_VELOCITY_INV_MASS = 6, //!< The simulation mesh vertex velocities and their inverted mass in the 4th component (quadruples of float) + eSIM_POSITION_INV_MASS = 7 //!< The simulation mesh vertex positions and their inverted mass in the 4th component (quadruples of float) + }; +}; + #if !PX_DOXYGEN } #endif diff --git a/physx/include/characterkinematic/PxController.h b/physx/include/characterkinematic/PxController.h index ee64b3d5a..35e21e6b9 100644 --- a/physx/include/characterkinematic/PxController.h +++ b/physx/include/characterkinematic/PxController.h @@ -637,20 +637,6 @@ PX_INLINE bool PxControllerDesc::isValid() const class PxController { public: - //********************************************************************* - // DEPRECATED FUNCTIONS: - // - // PX_DEPRECATED virtual void setInteraction(PxCCTInteractionMode::Enum flag) = 0; - // PX_DEPRECATED virtual PxCCTInteractionMode::Enum getInteraction() const = 0; - // PX_DEPRECATED virtual void setGroupsBitmask(PxU32 bitmask) = 0; - // PX_DEPRECATED virtual PxU32 getGroupsBitmask() const = 0; - // - // => replaced with: - // - // PxControllerFilters::mCCTFilterCallback. Please define a PxControllerFilterCallback object and emulate the old interaction mode there. - // - //********************************************************************* - /** \brief Return the type of controller diff --git a/physx/include/characterkinematic/PxExtended.h b/physx/include/characterkinematic/PxExtended.h index 1bc75ebf9..14bd59898 100644 --- a/physx/include/characterkinematic/PxExtended.h +++ b/physx/include/characterkinematic/PxExtended.h @@ -47,222 +47,35 @@ namespace physx #define PX_BIG_WORLDS #ifdef PX_BIG_WORLDS -typedef double PxExtended; -#define PX_MAX_EXTENDED PX_MAX_F64 -#define PxExtendedAbs(x) fabs(x) + typedef PxVec3d PxExtendedVec3; + typedef double PxExtended; + #define PX_MAX_EXTENDED PX_MAX_F64 -struct PxExtendedVec3 -{ - PX_INLINE PxExtendedVec3() {} - PX_INLINE PxExtendedVec3(PxExtended _x, PxExtended _y, PxExtended _z) : x(_x), y(_y), z(_z) {} - - PX_INLINE bool isZero() const - { - if(x!=0.0 || y!=0.0 || z!=0.0) return false; - return true; - } - - PX_INLINE PxExtended dot(const PxVec3& v) const - { - return x * PxExtended(v.x) + y * PxExtended(v.y) + z * PxExtended(v.z); - } - - PX_INLINE PxExtended distanceSquared(const PxExtendedVec3& v) const - { - PxExtended dx = x - v.x; - PxExtended dy = y - v.y; - PxExtended dz = z - v.z; - return dx * dx + dy * dy + dz * dz; - } - - PX_INLINE PxExtended magnitudeSquared() const - { - return x * x + y * y + z * z; - } - - PX_INLINE PxExtended magnitude() const - { - return PxSqrt(x * x + y * y + z * z); - } - - PX_INLINE PxExtended normalize() - { - PxExtended m = magnitude(); - if (m != 0.0) - { - const PxExtended il = PxExtended(1.0) / m; - x *= il; - y *= il; - z *= il; - } - return m; - } - - PX_INLINE bool isFinite() const - { - return PxIsFinite(x) && PxIsFinite(y) && PxIsFinite(z); - } - - PX_INLINE void maximum(const PxExtendedVec3& v) - { - if (x < v.x) x = v.x; - if (y < v.y) y = v.y; - if (z < v.z) z = v.z; - } - - - PX_INLINE void minimum(const PxExtendedVec3& v) - { - if (x > v.x) x = v.x; - if (y > v.y) y = v.y; - if (z > v.z) z = v.z; - } - - PX_INLINE void set(PxExtended x_, PxExtended y_, PxExtended z_) - { - this->x = x_; - this->y = y_; - this->z = z_; - } - - PX_INLINE void setPlusInfinity() - { - x = y = z = PX_MAX_EXTENDED; - } - - PX_INLINE void setMinusInfinity() - { - x = y = z = -PX_MAX_EXTENDED; - } - - PX_INLINE void cross(const PxExtendedVec3& left, const PxVec3& right) - { - // temps needed in case left or right is this. - PxExtended a = (left.y * PxExtended(right.z)) - (left.z * PxExtended(right.y)); - PxExtended b = (left.z * PxExtended(right.x)) - (left.x * PxExtended(right.z)); - PxExtended c = (left.x * PxExtended(right.y)) - (left.y * PxExtended(right.x)); - - x = a; - y = b; - z = c; - } - - PX_INLINE void cross(const PxExtendedVec3& left, const PxExtendedVec3& right) - { - // temps needed in case left or right is this. - PxExtended a = (left.y * right.z) - (left.z * right.y); - PxExtended b = (left.z * right.x) - (left.x * right.z); - PxExtended c = (left.x * right.y) - (left.y * right.x); - - x = a; - y = b; - z = c; - } - - PX_INLINE PxExtendedVec3 cross(const PxExtendedVec3& v) const - { - PxExtendedVec3 temp; - temp.cross(*this,v); - return temp; - } - - PX_INLINE void cross(const PxVec3& left, const PxExtendedVec3& right) - { - // temps needed in case left or right is this. - PxExtended a = (PxExtended(left.y) * right.z) - (PxExtended(left.z) * right.y); - PxExtended b = (PxExtended(left.z) * right.x) - (PxExtended(left.x) * right.z); - PxExtended c = (PxExtended(left.x) * right.y) - (PxExtended(left.y) * right.x); - - x = a; - y = b; - z = c; - } - - PX_INLINE PxExtendedVec3 operator-() const - { - return PxExtendedVec3(-x, -y, -z); - } - - PX_INLINE PxExtendedVec3& operator+=(const PxExtendedVec3& v) - { - x += v.x; - y += v.y; - z += v.z; - return *this; - } - - PX_INLINE PxExtendedVec3& operator-=(const PxExtendedVec3& v) - { - x -= v.x; - y -= v.y; - z -= v.z; - return *this; - } - - PX_INLINE PxExtendedVec3& operator+=(const PxVec3& v) - { - x += PxExtended(v.x); - y += PxExtended(v.y); - z += PxExtended(v.z); - return *this; - } - - PX_INLINE PxExtendedVec3& operator-=(const PxVec3& v) - { - x -= PxExtended(v.x); - y -= PxExtended(v.y); - z -= PxExtended(v.z); - return *this; - } - - PX_INLINE PxExtendedVec3& operator*=(const PxReal& s) - { - x *= PxExtended(s); - y *= PxExtended(s); - z *= PxExtended(s); - return *this; - } - - PX_INLINE PxExtendedVec3 operator+(const PxExtendedVec3& v) const - { - return PxExtendedVec3(x + v.x, y + v.y, z + v.z); - } - - PX_INLINE PxVec3 operator-(const PxExtendedVec3& v) const + PX_FORCE_INLINE PxVec3 toVec3(const PxExtendedVec3& v) { - return PxVec3(PxReal(x - v.x), PxReal(y - v.y), PxReal(z - v.z)); + return PxVec3(float(v.x), float(v.y), float(v.z)); } - PX_INLINE PxExtended& operator[](int index) + // Computes the single-precision difference between two extended-precision points + PX_INLINE PxVec3 diff(const PxExtendedVec3& p1, const PxExtendedVec3& p0) { - PX_ASSERT(index>=0 && index<=2); - - return reinterpret_cast(this)[index]; + return PxVec3(float(p1.x - p0.x), float(p1.y - p0.y), float(p1.z - p0.z)); } +#else + typedef PxVec3 PxExtendedVec3; + typedef float PxExtended; + #define PX_MAX_EXTENDED PX_MAX_F32 - - PX_INLINE PxExtended operator[](int index) const + PX_FORCE_INLINE PxVec3 toVec3(const PxExtendedVec3& v) { - PX_ASSERT(index>=0 && index<=2); - - return reinterpret_cast(this)[index]; + return v; } - PxExtended x,y,z; -}; - - PX_FORCE_INLINE PxVec3 toVec3(const PxExtendedVec3& v) + // Computes the single-precision difference between two extended-precision points + PX_INLINE PxVec3 diff(const PxExtendedVec3& p1, const PxExtendedVec3& p0) { - return PxVec3(float(v.x), float(v.y), float(v.z)); + return p1 - p0; } - -#else -// Big worlds not defined - -typedef PxVec3 PxExtendedVec3; -typedef PxReal PxExtended; -#define PX_MAX_EXTENDED PX_MAX_F32 -#define PxExtendedAbs(x) fabsf(x) #endif #if !PX_DOXYGEN diff --git a/physx/include/common/PxBase.h b/physx/include/common/PxBase.h index f16cd907a..b21758c5d 100644 --- a/physx/include/common/PxBase.h +++ b/physx/include/common/PxBase.h @@ -71,12 +71,6 @@ All PxBase sub-classes can be serialized. */ class PxBase { -//= 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. -//================================================================================================== public: /** \brief Releases the PxBase instance, please check documentation of release in derived class. diff --git a/physx/include/common/PxCoreUtilityTypes.h b/physx/include/common/PxCoreUtilityTypes.h index bc1ab8089..f0cf8b9d1 100644 --- a/physx/include/common/PxCoreUtilityTypes.h +++ b/physx/include/common/PxCoreUtilityTypes.h @@ -111,12 +111,6 @@ struct PxPadding template class PxFixedSizeLookupTable { -//= 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. -//================================================================================================== public: PxFixedSizeLookupTable() diff --git a/physx/include/common/PxInsertionCallback.h b/physx/include/common/PxInsertionCallback.h index e9f373884..0b9211c14 100644 --- a/physx/include/common/PxInsertionCallback.h +++ b/physx/include/common/PxInsertionCallback.h @@ -71,8 +71,6 @@ namespace physx virtual ~PxInsertionCallback() {} }; - typedef PxInsertionCallback PxPhysicsInsertionCallback; - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/physx/include/common/PxPhysXCommonConfig.h b/physx/include/common/PxPhysXCommonConfig.h index 794da10c3..20b7880be 100644 --- a/physx/include/common/PxPhysXCommonConfig.h +++ b/physx/include/common/PxPhysXCommonConfig.h @@ -34,6 +34,9 @@ #include "foundation/Px.h" +//Fills almost all allocated (host and device memory) with 0xcdcdcdcd (=3452816845) +#define PX_STOMP_ALLOCATED_MEMORY 0 + /*Disable support for VS2017 prior version 15.5.1 for windows platform, because of a compiler bug: https://developercommunity.visualstudio.com/content/problem/66047/possible-compiler-bug.html */ diff --git a/physx/include/common/PxRenderOutput.h b/physx/include/common/PxRenderOutput.h index 2bc16f8c0..25338d6a5 100644 --- a/physx/include/common/PxRenderOutput.h +++ b/physx/include/common/PxRenderOutput.h @@ -46,7 +46,7 @@ namespace physx /** Output stream to fill RenderBuffer */ - class PX_PHYSX_COMMON_API PxRenderOutput + class PxRenderOutput { public: @@ -226,7 +226,7 @@ namespace physx }; PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugCircle& circle) { - const PxF32 step = PxTwoPi / circle.nSegments; + const PxF32 step = PxTwoPi / PxF32(circle.nSegments); PxF32 angle = 0; out << PxRenderOutput::LINESTRIP; for (PxU32 i = 0; i < circle.nSegments; i++, angle += step) @@ -245,7 +245,7 @@ namespace physx }; PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArc& arc) { - const PxF32 step = (arc.maxAngle - arc.minAngle) / arc.nSegments; + const PxF32 step = (arc.maxAngle - arc.minAngle) / PxF32(arc.nSegments); PxF32 angle = arc.minAngle; out << PxRenderOutput::LINESTRIP; for (PxU32 i = 0; i < arc.nSegments; i++, angle += step) diff --git a/physx/include/common/PxSerialFramework.h b/physx/include/common/PxSerialFramework.h index 22bc3c32f..7fe541027 100644 --- a/physx/include/common/PxSerialFramework.h +++ b/physx/include/common/PxSerialFramework.h @@ -350,32 +350,38 @@ class PxSerializationRegistry /** \brief Register a RepX serializer for a concrete type + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + \param type PxConcreteType corresponding to the RepX serializer \param serializer The PxRepXSerializer to be registered @see PxConcreteType, PxRepXSerializer */ - virtual void registerRepXSerializer(PxType type, PxRepXSerializer& serializer) = 0; + PX_DEPRECATED virtual void registerRepXSerializer(PxType type, PxRepXSerializer& serializer) = 0; /** \brief Unregister a RepX serializer for a concrete type, and retrieves the corresponding serializer object. + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + \param type PxConcreteType for which the RepX serializer should be unregistered \return Unregistered PxRepxSerializer corresponding to type, NULL for types for which no RepX serializer has been registered. @see PxConcreteType, PxSerializationRegistry::registerRepXSerializer, PxSerializationRegistry::release */ - virtual PxRepXSerializer* unregisterRepXSerializer(PxType type) = 0; + PX_DEPRECATED virtual PxRepXSerializer* unregisterRepXSerializer(PxType type) = 0; /** \brief Returns RepX serializer given the corresponding type name + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + \param typeName Name of the type \return Registered PxRepXSerializer object corresponding to type name @see PxRepXSerializer, PxTypeInfo, PX_DEFINE_TYPEINFO */ - virtual PxRepXSerializer* getRepXSerializer(const char* typeName) const = 0; + PX_DEPRECATED virtual PxRepXSerializer* getRepXSerializer(const char* typeName) const = 0; //@} /************************************************************************************************/ diff --git a/physx/include/common/PxTolerancesScale.h b/physx/include/common/PxTolerancesScale.h index 43434818a..8aad886c1 100644 --- a/physx/include/common/PxTolerancesScale.h +++ b/physx/include/common/PxTolerancesScale.h @@ -78,7 +78,7 @@ class PxTolerancesScale \param[in] defaultLength Default length \param[in] defaultSpeed Default speed */ - PX_INLINE PxTolerancesScale(float defaultLength=1.0f, float defaultSpeed=10.0f); + PX_INLINE explicit PxTolerancesScale(float defaultLength=1.0f, float defaultSpeed=10.0f); /** \brief Returns true if the descriptor is valid. diff --git a/physx/include/common/PxTypeInfo.h b/physx/include/common/PxTypeInfo.h index 8a84b3cb4..944b511a0 100644 --- a/physx/include/common/PxTypeInfo.h +++ b/physx/include/common/PxTypeInfo.h @@ -71,7 +71,6 @@ struct PxConcreteType ePBD_MATERIAL, eFLIP_MATERIAL, eMPM_MATERIAL, - eCUSTOM_MATERIAL, eCONSTRAINT, eAGGREGATE, eARTICULATION_REDUCED_COORDINATE, @@ -89,7 +88,6 @@ struct PxConcreteType ePBD_PARTICLESYSTEM, eFLIP_PARTICLESYSTEM, eMPM_PARTICLESYSTEM, - eCUSTOM_PARTICLESYSTEM, eFEM_CLOTH, eHAIR_SYSTEM, ePARTICLE_BUFFER, @@ -127,7 +125,6 @@ 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) @@ -150,7 +147,6 @@ PX_DEFINE_TYPEINFO(PxParticleSystem, PxConcreteType::eUND 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) diff --git a/physx/include/cooking/PxBVHDesc.h b/physx/include/cooking/PxBVHDesc.h index 4a0aec9ad..e378c0979 100644 --- a/physx/include/cooking/PxBVHDesc.h +++ b/physx/include/cooking/PxBVHDesc.h @@ -131,11 +131,6 @@ PX_INLINE bool PxBVHDesc::isValid() const return true; } - /** - * @deprecated - */ - typedef PX_DEPRECATED PxBVHDesc PxBVHStructureDesc; - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/physx/include/cooking/PxConvexMeshDesc.h b/physx/include/cooking/PxConvexMeshDesc.h index 390e2636e..3852b813f 100644 --- a/physx/include/cooking/PxConvexMeshDesc.h +++ b/physx/include/cooking/PxConvexMeshDesc.h @@ -119,11 +119,13 @@ struct PxConvexFlag eFAST_INERTIA_COMPUTATION = (1 << 6), /** - \brief Convex hulls are created with respect to GPU simulation limitations. Vertex limit and polygon limit + \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. + + @deprecated since PhysX 5.2. Setting #PxCookingParams::buildGPUData to true always cooks GPU-compatible meshes. */ - eGPU_COMPATIBLE = (1 << 7), + eGPU_COMPATIBLE PX_DEPRECATED = (1 << 7), /** \brief Convex hull input vertices are shifted to be around origin to provide better computation stability. @@ -197,7 +199,6 @@ class PxConvexMeshDesc 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. @@ -207,7 +208,7 @@ class PxConvexMeshDesc Default: 255 */ PxU16 vertexLimit; - + /** \brief Limits the number of polygons of the result convex mesh. Hard maximum limit is 255 and minimum limit is 4. diff --git a/physx/include/cooking/PxCooking.h b/physx/include/cooking/PxCooking.h index 0ed9b93a1..61fdeead1 100644 --- a/physx/include/cooking/PxCooking.h +++ b/physx/include/cooking/PxCooking.h @@ -328,648 +328,487 @@ struct PxCookingParams } }; -/** -\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: - /** - \brief Closes this instance of the interface. - - This function should be called to cleanly shut down the Cooking library before application exit. - - \note This function is required to be called to release foundation usage. - - */ - virtual void release() = 0; - - /** - \brief Sets cooking parameters - - \param[in] params Cooking parameters - - @see getParams() - */ - virtual void setParams(const PxCookingParams& params) = 0; - - /** - \brief Gets cooking parameters - - \return Current cooking parameters. - - @see PxCookingParams setParams() - */ - 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; - - /** - \brief Cooks a triangle mesh. The results are written to the stream. - - To create a triangle 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. - - \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; - - /** - \brief Cooks and creates a triangle mesh without going through a stream. - - \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. - - \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() PxInsertionCallback - */ - 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. - - The following conditions are true for a valid triangle mesh: - 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. - - \return true if all the validity conditions hold, false otherwise. - - @see cookTriangleMesh() - */ - 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 +#if !PX_DOXYGEN +} // namespace physx +#endif - \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 +// Immediate cooking - @see cookConvexMesh() setParams() PxPhysics.createTetrahedronMesh() - */ - virtual bool cookTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxOutputStream& stream) const = 0; +/** +\brief Gets standalone object insertion interface. - /** - \brief Cooks and creates a tetrahedron mesh without going through a stream. +This interface allows the creation of standalone objects that can exist without a PxPhysics or PxScene object. - \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. +@see PxCreateTriangleMesh PxCreateHeightfield PxCreateTetrahedronMesh PxCreateBVH +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxInsertionCallback* PxGetStandaloneInsertionCallback(); - \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() - or PxCooking::getStandaloneInsertionCallback(). +// ==== BVH ==== - \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. +/** +\brief Cooks a bounding volume hierarchy. The results are written to the stream. - @see cookTetrahedronMesh() setParams() PxInsertionCallback - */ - virtual PxTetrahedronMesh* createTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxInsertionCallback& insertionCallback) const = 0; +PxCookBVH() 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 descriptor. +\param[in] stream User stream to output the cooked data. +\return true on success. - /** - \brief Cooks and creates a tetrahedron mesh without going through a stream. Convenience function for standalone objects. +@see PxBVH PxRigidActorExt::getRigidActorShapeLocalBoundsList +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookBVH(const physx::PxBVHDesc& desc, physx::PxOutputStream& 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. +/** +\brief Cooks and creates a bounding volume hierarchy without going through a stream. - \param[in] meshDesc The tetrahedron mesh descriptor to read the mesh from. - \return PxTetrahedronMesh pointer on success. +\note This method does the same as PxCookBVH, 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. - @see cookTetrahedronMesh() PxInsertionCallback - */ - PX_FORCE_INLINE PxTetrahedronMesh* createTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc) const - { - return createTetrahedronMesh(meshDesc, const_cast(*this).getStandaloneInsertionCallback()); - } +\note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() +or PxGetStandaloneInsertionCallback(). - /** - \brief Computes the mapping between collision and simulation mesh +\param[in] desc The BVH descriptor. +\param[in] insertionCallback The insertion interface. +\return PxBVH pointer on success - 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. +@see PxCookBVH() PxInsertionCallback +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxBVH* PxCreateBVH(const physx::PxBVHDesc& desc, physx::PxInsertionCallback& insertionCallback); - \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 +/** +\brief Cooks and creates a bounding volume hierarchy without going through a stream. Convenience function for standalone objects. - @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 +\note This method does the same as PxCookBVH, 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. - Computes data structures to speed up collision detection with tetrahedral meshes. +\param[in] desc The BVH descriptor. +\return PxBVH pointer on success - \param[in] collisionMeshDesc Raw tetrahedral mesh descriptor wich will be used for collision detection - \return PxCollisionTetrahedronMeshData pointer that describes the collision mesh +@see PxCookBVH() PxInsertionCallback +*/ +PX_FORCE_INLINE physx::PxBVH* PxCreateBVH(const physx::PxBVHDesc& desc) +{ + return PxCreateBVH(desc, *PxGetStandaloneInsertionCallback()); +} - */ - virtual PxCollisionTetrahedronMeshData* computeCollisionData(const PxTetrahedronMeshDesc& collisionMeshDesc) const = 0; +// ==== Heightfield ==== - /** - \brief Computes data to accelerate collision detection of tetrahedral meshes +/** +\brief Cooks a heightfield. The results are written to the stream. - Computes data to compute and store a softbody's deformation using FEM. +To create a heightfield object there is an option to precompute some of calculations done while loading the heightfield data. - \param[in] simulationMeshDesc Raw tetrahedral mesh descriptor wich will be used for FEM simulation - \return PxSimulationTetrahedronMeshData pointer that describes the simulation mesh +PxCookHeightField() allows a heightfield description to be cooked into a binary stream +suitable for loading and performing collision detection at runtime. - */ - virtual PxSimulationTetrahedronMeshData* computeSimulationData(const PxTetrahedronMeshDesc& simulationMeshDesc) const = 0; +\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 - /** - \brief Bundles all data required for softbody simulation +@see PxPhysics.createHeightField() +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookHeightField(const physx::PxHeightFieldDesc& desc, physx::PxOutputStream& stream); - Creates a container that provides everything to create a PxSoftBody +/** +\brief Cooks and creates a heightfield mesh and inserts it into PxPhysics. - \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.) +\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 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 +@see PxCookHeightField() PxPhysics.createHeightField() PxInsertionCallback +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxHeightField* PxCreateHeightField(const physx::PxHeightFieldDesc& desc, physx::PxInsertionCallback& insertionCallback); - Creates a container that provides everything to create a PxSoftBody +/** +\brief Cooks and creates a heightfield mesh and inserts it into PxPhysics. Convenience function for standalone objects. - \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.) +\param[in] desc The heightfield descriptor to read the HF from. +\return PxHeightField pointer on success - @see PxSoftBody createSoftBody() - */ - virtual PxSoftBodyMesh* assembleSoftBodyMesh(PxSimulationTetrahedronMeshData& simulationMesh, PxCollisionTetrahedronMeshData& collisionMesh, - PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const = 0; - +@see PxCookHeightField() PxPhysics.createHeightField() PxInsertionCallback +*/ +PX_FORCE_INLINE physx::PxHeightField* PxCreateHeightField(const physx::PxHeightFieldDesc& desc) +{ + return PxCreateHeightField(desc, *PxGetStandaloneInsertionCallback()); +} - /** - \brief Cooks a convex mesh. The results are written to the stream. +// ==== Convex meshes ==== - To create a triangle mesh object it is necessary to first 'cook' the mesh data into - a form which allows the SDK to perform efficient collision detection. +/** +\brief Cooks a convex mesh. The results are written to the stream. - cookConvexMesh() allows a mesh description to be cooked into a binary stream - suitable for loading and performing collision detection at runtime. +To create a triangle mesh object it is necessary to first 'cook' the mesh data into +a form which allows the SDK to perform efficient collision detection. - \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. +PxCookConvexMesh() allows a mesh description to be cooked into a binary stream +suitable for loading and performing collision detection at runtime. - \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. +\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. - @see cookTriangleMesh() setParams() PxConvexMeshCookingResult::Enum - */ - virtual bool cookConvexMesh(const PxConvexMeshDesc& desc, PxOutputStream& stream, PxConvexMeshCookingResult::Enum* condition = NULL) const = 0; +\param[in] params The cooking parameters +\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. - /** - \brief Cooks and creates a convex mesh without going through a stream. +@see PxCookTriangleMesh() PxConvexMeshCookingResult::Enum +*/ +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); - \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. +/** +\brief Cooks and creates a convex mesh without going through a stream. - \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() - or PxCooking::getStandaloneInsertionCallback(). +\note This method does the same as PxCookConvexMesh, 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. - \param[in] insertionCallback The insertion interface from PxPhysics. - \param[out] condition Result from convex mesh cooking. - \return PxConvexMesh pointer on success +\note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() +or PxGetStandaloneInsertionCallback(). - @see cookConvexMesh() setParams() PxInsertionCallback - */ - virtual PxConvexMesh* createConvexMesh(const PxConvexMeshDesc& desc, PxInsertionCallback& insertionCallback, PxConvexMeshCookingResult::Enum* condition = NULL) const = 0; +\param[in] params The cooking parameters +\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 PxCookConvexMesh() PxInsertionCallback +*/ +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); - /** - \brief Cooks and creates a convex mesh without going through a stream. Convenience function for standalone objects. +/** +\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. +\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()); - } +\param[in] params The cooking parameters +\param[in] desc The convex mesh descriptor to read the mesh from. +\return PxConvexMesh pointer on success - /** - \brief Verifies if the convex mesh is valid. Prints an error message for each inconsistency found. - - The convex mesh descriptor must contain an already created convex mesh - the vertices, indices and polygons must be provided. +@see PxCookConvexMesh() PxInsertionCallback +*/ +PX_FORCE_INLINE physx::PxConvexMesh* PxCreateConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc) +{ + return PxCreateConvexMesh(params, desc, *PxGetStandaloneInsertionCallback()); +} - \note This function should be used if PxConvexFlag::eDISABLE_MESH_VALIDATION is planned to be used in release builds. +/** +\brief Verifies if the convex mesh is valid. Prints an error message for each inconsistency found. - \param[in] desc The convex mesh descriptor to read the mesh from. +The convex mesh descriptor must contain an already created convex mesh - the vertices, indices and polygons must be provided. - \return true if all the validity conditions hold, false otherwise. +\note This function should be used if PxConvexFlag::eDISABLE_MESH_VALIDATION is planned to be used in release builds. - @see cookConvexMesh() - */ - virtual bool validateConvexMesh(const PxConvexMeshDesc& desc) const = 0; +\param[in] params The cooking parameters +\param[in] desc The convex mesh descriptor to read the mesh from. - /** - \brief Computed hull polygons from given vertices and triangles. Polygons are needed for PxConvexMeshDesc rather than triangles. +\return true if all the validity conditions hold, false otherwise. - Please note that the resulting polygons may have different number of vertices. Some vertices may be removed. - The output vertices, indices and polygons must be used to construct a hull. +@see PxCookConvexMesh() +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxValidateConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc); - The provided PxAllocatorCallback does allocate the out array's. It is the user responsibility to deallocated those - array's. +/** +\brief Compute hull polygons from given vertices and triangles. Polygons are needed for PxConvexMeshDesc rather than triangles. - \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 +Please note that the resulting polygons may have different number of vertices. Some vertices may be removed. +The output vertices, indices and polygons must be used to construct a hull. - @see cookConvexMesh() PxConvexFlags PxConvexMeshDesc PxSimpleTriangleMesh - */ - virtual bool computeHullPolygons(const PxSimpleTriangleMesh& mesh, PxAllocatorCallback& inCallback, PxU32& nbVerts, PxVec3*& vertices, - PxU32& nbIndices, PxU32*& indices, PxU32& nbPolygons, PxHullPolygon*& hullPolygons) const = 0; +The provided PxAllocatorCallback does allocate the out arrays. It is the user responsibility to deallocated those arrays. - /** - \brief Cooks a heightfield. The results are written to the stream. +\param[in] params The cooking parameters +\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 - To create a heightfield object there is an option to precompute some of calculations done while loading the heightfield data. - - cookHeightField() allows a heightfield description to be cooked into a binary stream - suitable for loading and performing collision detection at runtime. +@see PxCookConvexMesh() PxConvexFlags PxConvexMeshDesc PxSimpleTriangleMesh +*/ +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); - \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 +// ==== Triangle meshes ==== - @see PxPhysics.createHeightField() - */ - virtual bool cookHeightField(const PxHeightFieldDesc& desc, PxOutputStream& stream) const = 0; +/** +\brief Verifies if the triangle mesh is valid. Prints an error message for each inconsistency found. - /** - \brief Cooks and creates a heightfield mesh and inserts it into PxPhysics. +The following conditions are true for a valid triangle mesh: +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 heightfield descriptor to read the HF from. - \param[in] insertionCallback The insertion interface from PxPhysics. - \return PxHeightField pointer on success +\param[in] params The cooking parameters +\param[in] desc The triangle mesh descriptor to read the mesh from. - @see cookConvexMesh() setParams() PxPhysics.createTriangleMesh() PxInsertionCallback - */ - virtual PxHeightField* createHeightField(const PxHeightFieldDesc& desc, PxInsertionCallback& insertionCallback) const = 0; +\return true if all the validity conditions hold, false otherwise. +@see PxCookTriangleMesh() +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxValidateTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc); - /** - \brief Cooks and creates a heightfield mesh and inserts it into PxPhysics. Convenience function for standalone objects. +/** +\brief Cooks a triangle mesh. The results are written to the stream. - \param[in] desc The heightfield descriptor to read the HF from. - \return PxHeightField pointer on success +To create a triangle mesh object it is necessary to first 'cook' the mesh data into +a form which allows the SDK to perform efficient collision detection. - @see cookConvexMesh() PxPhysics.createTriangleMesh() PxInsertionCallback - */ - PX_FORCE_INLINE PxHeightField* createHeightField(const PxHeightFieldDesc& desc) const - { - return createHeightField(desc, const_cast(*this).getStandaloneInsertionCallback()); - } +PxCookTriangleMesh() allows a mesh description to be cooked into a binary stream +suitable for loading and performing collision detection at runtime. - /** - \brief Cooks a bounding volume hierarchy. The results are written to the stream. +\param[in] params The cooking parameters +\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 - cookBVH() allows a BVH description to be cooked into a binary stream - suitable for loading and performing BVH detection at runtime. +@see PxCookConvexMesh() PxPhysics.createTriangleMesh() PxTriangleMeshCookingResult::Enum +*/ +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); - \param[in] desc The BVH descriptor. - \param[in] stream User stream to output the cooked data. - \return true on success. +/** +\brief Cooks and creates a triangle mesh without going through a stream. - @see PxBVH PxRigidActorExt::getRigidActorShapeLocalBoundsList - */ - virtual bool cookBVH(const PxBVHDesc& desc, PxOutputStream& stream) const = 0; +\note This method does the same as PxCookTriangleMesh, 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 PxGetStandaloneInsertionCallback(). - /** - \brief Backward compatibility helper. Cooks a bounding volume hierarchy. The results are written to the stream. +\param[in] params The cooking parameters +\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. - \param[in] desc The BVH descriptor. - \param[in] stream User stream to output the cooked data. - \return true on success. - @deprecated - */ - 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. +@see PxCookTriangleMesh() PxPhysics.createTriangleMesh() PxInsertionCallback +*/ +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); - \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() - or PxCooking::getStandaloneInsertionCallback(). +/** +\brief Cooks and creates a triangle mesh without going through a stream. Convenience function for standalone objects. - \param[in] desc The BVH descriptor. - \param[in] insertionCallback The insertion interface. - \return PxBVH pointer on success +\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. - @see cookBVH() PxInsertionCallback - */ - virtual PxBVH* createBVH(const PxBVHDesc& desc, PxInsertionCallback& insertionCallback) const = 0; +\param[in] params The cooking parameters +\param[in] desc The triangle mesh descriptor to read the mesh from. +@see PxCookTriangleMesh() PxPhysics.createTriangleMesh() PxInsertionCallback +*/ +PX_FORCE_INLINE physx::PxTriangleMesh* PxCreateTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc) +{ + return PxCreateTriangleMesh(params, desc, *PxGetStandaloneInsertionCallback()); +} - /** - \brief Cooks and creates a bounding volume hierarchy without going through a stream. Convenience function for standalone objects. +// ==== Tetrahedron & soft body meshes ==== - \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. +/** +\brief Cooks a tetrahedron mesh. The results are written to the stream. - \param[in] desc The BVH descriptor. - \return PxBVH pointer on success +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. - @see cookBVH() PxInsertionCallback - */ - PX_FORCE_INLINE PxBVH* createBVH(const PxBVHDesc& desc) const - { - return createBVH(desc, const_cast(*this).getStandaloneInsertionCallback()); - } +PxCookTetrahedronMesh() allows a mesh description to be cooked into a binary stream +suitable for loading and performing collision detection at runtime. - /** - \brief Backward compatibility helper. Cooks and creates a bounding volume hierarchy without going through a stream. +\param[in] params The cooking parameters +\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 - \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); - } +@see PxCookConvexMesh() PxPhysics.createTetrahedronMesh() +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc, physx::PxOutputStream& stream); - /** - \brief Gets standalone object insertion interface. +/** +\brief Cooks and creates a tetrahedron mesh without going through a stream. - This interface allows the creation of standalone objects that can exist without a PxPhysics or PxScene object. +\note This method does the same as PxCookTetrahedronMesh, 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. - @see PxCooking::createTriangleMesh PxCooking::createHeightfield PxCooking::createTetrahedronMesh PxCooking::createBVH - */ - virtual PxInsertionCallback& getStandaloneInsertionCallback() = 0; +\note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() +or PxGetStandaloneInsertionCallback(). -protected: - virtual ~PxCooking(){} -}; +\param[in] params The cooking parameters +\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. -#if !PX_DOXYGEN -} // namespace physx -#endif +@see PxCookTetrahedronMesh() PxInsertionCallback +*/ +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxTetrahedronMesh* PxCreateTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc, physx::PxInsertionCallback& insertionCallback); /** -\brief Create an instance of the cooking interface. +\brief Cooks and creates a tetrahedron mesh without going through a stream. Convenience function for standalone objects. -Note that the foundation object is handled as an application-wide singleton in statically linked executables -and a DLL-wide singleton in dynamically linked executables. Therefore, if you are using the runtime SDK in the -same executable as cooking, you should pass the Physics's copy of foundation (acquired with -PxPhysics::getFoundation()) to the cooker. This will also ensure correct handling of memory for objects -passed from the cooker to the SDK. +\note This method does the same as PxCookTetrahedronMesh, 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. -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] params The cooking parameters +\param[in] meshDesc The tetrahedron mesh descriptor to read the mesh from. +\return PxTetrahedronMesh pointer on success. -\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 +@see PxCookTetrahedronMesh() PxInsertionCallback */ -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) +PX_FORCE_INLINE physx::PxTetrahedronMesh* PxCreateTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc) { - return PxCreateBVH(desc, *PxGetStandaloneInsertionCallback()); + return PxCreateTetrahedronMesh(params, meshDesc, *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()); -} +/** +\brief Cooks a softbody mesh. The results are written to the stream. -// 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); +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. -PX_FORCE_INLINE physx::PxConvexMesh* PxCreateConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc) -{ - return PxCreateConvexMesh(params, desc, *PxGetStandaloneInsertionCallback()); -} +PxCookSoftBodyMesh() allows a mesh description to be cooked into a binary stream +suitable for loading and performing collision detection at runtime. -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); +\param[in] params The cooking parameters +\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 -// 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); +@see PxCookConvexMesh() PxPhysics.createTriangleMesh() PxTriangleMeshCookingResult::Enum +*/ +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_FORCE_INLINE physx::PxTriangleMesh* PxCreateTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc) -{ - return PxCreateTriangleMesh(params, desc, *PxGetStandaloneInsertionCallback()); -} +/** +\brief Cooks and creates a softbody mesh without going through a stream. -// 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); +\note This method does the same as PxCookSoftBodyMesh, 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. -PX_FORCE_INLINE physx::PxTetrahedronMesh* PxCreateTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc) -{ - return PxCreateTetrahedronMesh(params, meshDesc, *PxGetStandaloneInsertionCallback()); -} +\note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() +or 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); +\param[in] params The cooking parameters +\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 PxCookTriangleMesh() PxPhysics.createTriangleMesh() PxInsertionCallback +*/ 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); +/** +\brief Cooks and creates a softbody mesh without going through a stream. Convenience function for standalone objects. + +\note This method does the same as PxCookSoftBodyMesh, 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] params The cooking parameters +\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 PxCookTriangleMesh() PxPhysics.createTriangleMesh() PxInsertionCallback +*/ 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()); } +/** +\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] params The cooking parameters +\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 +*/ 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); +/** +\brief Computes data to accelerate collision detection of tetrahedral meshes + +Computes data structures to speed up collision detection with tetrahedral meshes. + +\param[in] params The cooking parameters +\param[in] collisionMeshDesc Raw tetrahedral mesh descriptor wich will be used for collision detection +\return PxCollisionTetrahedronMeshData pointer that describes the collision mesh +*/ PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxCollisionTetrahedronMeshData* PxComputeCollisionData(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& collisionMeshDesc); +/** +\brief Computes data to accelerate collision detection of tetrahedral meshes + +Computes data to compute and store a softbody's deformation using FEM. + +\param[in] params The cooking parameters +\param[in] simulationMeshDesc Raw tetrahedral mesh descriptor wich will be used for FEM simulation +\return PxSimulationTetrahedronMeshData pointer that describes the simulation mesh +*/ PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxSimulationTetrahedronMeshData* PxComputeSimulationData(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& simulationMeshDesc); +/** +\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() +*/ 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); +/** +\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() +*/ PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxSoftBodyMesh* PxAssembleSoftBodyMesh_Sim(physx::PxSimulationTetrahedronMeshData& simulationMesh, physx::PxCollisionTetrahedronMeshData& collisionMesh, physx::PxCollisionMeshMappingData& mappingData, physx::PxInsertionCallback& insertionCallback); diff --git a/physx/include/cooking/PxCookingInternal.h b/physx/include/cooking/PxCookingInternal.h index 73972a87d..c66399c23 100644 --- a/physx/include/cooking/PxCookingInternal.h +++ b/physx/include/cooking/PxCookingInternal.h @@ -48,9 +48,9 @@ namespace physx } // 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::PxTriangleMesh* PX_CALL_CONV PxCreateTriangleMeshInternal(const physx::PxTriangleMeshInternalData& data); - PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxBVH* PX_CALL_CONV PxCreateBVHInternal(const physx::PxBVHInternalData& data, const physx::PxCooking& cooking); + PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxBVH* PX_CALL_CONV PxCreateBVHInternal(const physx::PxBVHInternalData& data); /** @} */ #endif diff --git a/physx/include/cooking/PxSDFDesc.h b/physx/include/cooking/PxSDFDesc.h index 4f37a2ad0..6f6b3abc8 100644 --- a/physx/include/cooking/PxSDFDesc.h +++ b/physx/include/cooking/PxSDFDesc.h @@ -143,6 +143,12 @@ namespace physx */ PxU32 numThreadsForSdfConstruction; + /** + \brief Optional pointer to the geometry of the mesh that is used to compute the SDF. If it is not set, the geometry of the mesh, that this descriptor is passed to during cooking, will be taken. + The mesh data must only be available during cooking. It can be released once cooking completed. + */ + PxSimpleTriangleMesh baseMesh; + /** \brief Constructor */ diff --git a/physx/include/cudamanager/PxCudaContextManager.h b/physx/include/cudamanager/PxCudaContextManager.h index 49aa0dfc2..68e1b7654 100644 --- a/physx/include/cudamanager/PxCudaContextManager.h +++ b/physx/include/cudamanager/PxCudaContextManager.h @@ -44,23 +44,6 @@ namespace physx class PxCudaContext; -/** \brief Possible graphic/CUDA interoperability modes for context */ -struct PxCudaInteropMode -{ - /** - * \brief Possible graphic/CUDA interoperability modes for context - */ - enum Enum - { - NO_INTEROP = 0, - D3D10_INTEROP, - D3D11_INTEROP, - OGL_INTEROP, - - COUNT - }; -}; - struct PxCudaInteropRegisterFlag { enum Enum @@ -156,21 +139,11 @@ class PxCudaContextManagerDesc */ PxDeviceAllocatorCallback* deviceAllocator; - /** - * \brief The CUDA/Graphics interop mode of this context - * - * If ctx is NULL, this value describes the nature of the graphicsDevice - * pointer provided by the user. Else it describes the nature of the - * context provided by the user. - */ - PxCudaInteropMode::Enum interopMode; - PX_INLINE PxCudaContextManagerDesc() : ctx (NULL), graphicsDevice (NULL), appGUID (NULL), - deviceAllocator (NULL), - interopMode (PxCudaInteropMode::NO_INTEROP) + deviceAllocator (NULL) { } }; @@ -409,64 +382,12 @@ class PxCudaContextManager virtual unsigned int getMaxThreadsPerBlock() const = 0; //!< returns the maximum number of threads per block virtual const char *getDeviceName() const = 0; //!< returns device name retrieved from driver virtual CUdevice getDevice() const = 0; //!< returns device handle retrieved from driver - virtual PxCudaInteropMode::Enum getInteropMode() const = 0; //!< interop mode the context was created with virtual void setUsingConcurrentStreams(bool) = 0; //!< turn on/off using concurrent streams for GPU work virtual bool getUsingConcurrentStreams() const = 0; //!< true if GPU work can run in concurrent streams /* End query methods that don't require context to be acquired */ - /** - * \brief Register a rendering resource with CUDA - * - * This function is called to register render resources (allocated - * from OpenGL) with CUDA so that the memory may be shared - * between the two systems. This is only required for render - * resources that are designed for interop use. In APEX, each - * render resource descriptor that could support interop has a - * 'registerInCUDA' boolean variable. - * - * The function must be called again any time your graphics device - * is reset, to re-register the resource. - * - * Returns true if the registration succeeded. A registered - * resource must be unregistered before it can be released. - * - * \param resource [OUT] the handle to the resource that can be used with CUDA - * \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; - - /** - * \brief Register a rendering resource with CUDA - * - * This function is called to register render resources (allocated - * from Direct3D) with CUDA so that the memory may be shared - * between the two systems. This is only required for render - * resources that are designed for interop use. In APEX, each - * render resource descriptor that could support interop has a - * 'registerInCUDA' boolean variable. - * - * The function must be called again any time your graphics device - * is reset, to re-register the resource. - * - * Returns true if the registration succeeded. A registered - * resource must be unregistered before it can be released. - * - * \param resource [OUT] the handle to the resource that can be used with CUDA - * \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; - - /** - * \brief Unregister a rendering resource with CUDA - * - * If a render resource was successfully registered with CUDA using - * the registerResourceInCuda***() methods, this function must be called - * to unregister the resource before the it can be released. - */ - virtual bool unregisterResourceInCuda(CUgraphicsResource resource) = 0; + virtual void getDeviceMemoryInfo(size_t& free, size_t& total) const = 0; //!< get currently available and total memory /** * \brief Determine if the user has configured a dedicated PhysX GPU in the NV Control Panel diff --git a/physx/include/cudamanager/PxCudaTypes.h b/physx/include/cudamanager/PxCudaTypes.h index 97ee47d88..3e9f960e4 100644 --- a/physx/include/cudamanager/PxCudaTypes.h +++ b/physx/include/cudamanager/PxCudaTypes.h @@ -37,9 +37,9 @@ #include "foundation/PxSimpleTypes.h" -#if PX_LINUX && !PX_A64 -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#if PX_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" #endif #if PX_P64_FAMILY @@ -48,8 +48,8 @@ typedef unsigned long long CUdeviceptr; typedef unsigned int CUdeviceptr; #endif -#if PX_LINUX && !PX_A64 -#pragma GCC diagnostic pop +#if PX_CLANG +#pragma clang diagnostic pop #endif typedef int CUdevice; diff --git a/physx/include/extensions/PxContactJoint.h b/physx/include/extensions/PxContactJoint.h index a49ec1aa6..0283165dc 100644 --- a/physx/include/extensions/PxContactJoint.h +++ b/physx/include/extensions/PxContactJoint.h @@ -39,7 +39,7 @@ namespace physx class PxContactJoint; /** - \brief Create a distance Joint. + \brief Create a contact 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 @@ -49,15 +49,9 @@ namespace physx @see PxContactJoint */ - PxContactJoint* PxContactJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); + PX_DEPRECATED PxContactJoint* PxContactJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); - /** - \brief a joint that maintains an upper or lower bound (or both) on the distance between two points on different objects - - @see PxContactJointCreate PxJoint - */ - - struct PxJacobianRow + struct PX_DEPRECATED PxJacobianRow { PxVec3 linear0; PxVec3 linear1; @@ -87,11 +81,12 @@ namespace physx }; /** - \brief a joint that maintains an upper or lower bound (or both) on the distance between two points on different objects + \brief PxContactJoint is best viewed as a helper function for the inverse dynamics of articulations. The expected use case + is to use PxContactJoint::getConstraint() in conjunction with PxArticulationReducedCoordinate::addLoopJoint(). @see PxContactJointCreate PxJoint */ - class PxContactJoint : public PxJoint + PX_DEPRECATED class PxContactJoint : public PxJoint { public: diff --git a/physx/include/extensions/PxD6Joint.h b/physx/include/extensions/PxD6Joint.h index 84eab70f9..f1d4dda52 100644 --- a/physx/include/extensions/PxD6Joint.h +++ b/physx/include/extensions/PxD6Joint.h @@ -143,13 +143,6 @@ PX_FLAGS_OPERATORS(PxD6JointDriveFlag::Enum, PxU32) */ class PxD6JointDrive : public PxSpring { -//= 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. -//================================================================================================== - public: PxReal forceLimit; //!< the force limit of the drive - may be an impulse or a force depending on PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES PxD6JointDriveFlags flags; //!< the joint drive flags @@ -465,75 +458,6 @@ class PxD6Joint : public PxJoint @see setDriveVelocity() */ virtual void getDriveVelocity(PxVec3& linear, PxVec3& angular) const = 0; - - /** - \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION - is set for the joint. - - If the joint separates by more than this distance along its locked degrees of freedom, the solver - will move the bodies to close the distance. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0, PX_MAX_F32)
- Default: 1e10f - - \param[in] tolerance the linear tolerance threshold - - @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; - - /** - \brief Get the linear tolerance threshold for projection. - - \return the linear tolerance threshold - - @see setProjectionLinearTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; - - /** - \brief Set the angular tolerance threshold for projection. Projection is enabled if - PxConstraintFlag::ePROJECTION is set for the joint. - - If the joint deviates by more than this angle around its locked angular degrees of freedom, - the solver will move the bodies to close the angle. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0,Pi]
- Default: Pi - - \param[in] tolerance the angular tolerance threshold in radians - - \note - Angular projection is implemented only for the case of two or three locked angular degrees of freedom. - - @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; - - /** - \brief Get the angular tolerance threshold for projection. - - \return tolerance the angular tolerance threshold in radians - - @see setProjectionAngularTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; /** \brief Returns string name of PxD6Joint, used for serialization diff --git a/physx/include/extensions/PxDefaultAllocator.h b/physx/include/extensions/PxDefaultAllocator.h index 940abd928..d228bbbe6 100644 --- a/physx/include/extensions/PxDefaultAllocator.h +++ b/physx/include/extensions/PxDefaultAllocator.h @@ -34,6 +34,7 @@ #include "foundation/PxAllocatorCallback.h" #include "foundation/PxAssert.h" +#include "foundation/PxMemory.h" #include "common/PxPhysXCommonConfig.h" #include @@ -91,6 +92,12 @@ class PxDefaultAllocator : public PxAllocatorCallback { void* ptr = platformAlignedAlloc(size); PX_ASSERT((size_t(ptr) & 15)==0); +#if PX_STOMP_ALLOCATED_MEMORY + if(ptr != NULL) + { + PxMemSet(ptr, PxI32(0xcd), PxU32(size)); + } +#endif return ptr; } diff --git a/physx/include/extensions/PxDistanceJoint.h b/physx/include/extensions/PxDistanceJoint.h index 5a34b58e5..a4d692cfc 100644 --- a/physx/include/extensions/PxDistanceJoint.h +++ b/physx/include/extensions/PxDistanceJoint.h @@ -203,34 +203,6 @@ class PxDistanceJoint : public PxJoint */ 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/physx/include/extensions/PxExtensionsAPI.h b/physx/include/extensions/PxExtensionsAPI.h index fc30edb88..2b22ca33f 100644 --- a/physx/include/extensions/PxExtensionsAPI.h +++ b/physx/include/extensions/PxExtensionsAPI.h @@ -64,6 +64,9 @@ #include "extensions/PxConvexMeshExt.h" #include "extensions/PxSamplingExt.h" #include "extensions/PxTetrahedronMeshExt.h" +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#include "extensions/PxFEMClothExt.h" +#endif /** \brief Initialize the PhysXExtensions library. diff --git a/physx/include/extensions/PxFixedJoint.h b/physx/include/extensions/PxFixedJoint.h index a2a29397b..e7fbb34a1 100644 --- a/physx/include/extensions/PxFixedJoint.h +++ b/physx/include/extensions/PxFixedJoint.h @@ -65,72 +65,6 @@ class PxFixedJoint : public PxJoint { public: - /** - \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION - is set for the joint. - - If the joint separates by more than this distance along its locked degrees of freedom, the solver - will move the bodies to close the distance. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0, PX_MAX_F32)
- Default: 1e10f - - \param[in] tolerance the linear tolerance threshold - - @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; - - /** - \brief Get the linear tolerance threshold for projection. - - \return the linear tolerance threshold - - @see setProjectionLinearTolerance() PxJoint::setConstraintFlag() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; - - /** - \brief Set the angular tolerance threshold for projection. Projection is enabled if - PxConstraintFlag::ePROJECTION is set for the joint. - - If the joint deviates by more than this angle around its locked angular degrees of freedom, - the solver will move the bodies to close the angle. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0,Pi]
- Default: Pi - - \param[in] tolerance the angular tolerance threshold in radians - - @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; - - /** - \brief Get the angular tolerance threshold for projection. - - \return the angular tolerance threshold in radians - - @see setProjectionAngularTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; - /** \brief Returns string name of PxFixedJoint, used for serialization */ diff --git a/physx/include/extensions/PxGearJoint.h b/physx/include/extensions/PxGearJoint.h index 28f42f83a..763ddd377 100644 --- a/physx/include/extensions/PxGearJoint.h +++ b/physx/include/extensions/PxGearJoint.h @@ -82,6 +82,14 @@ namespace physx */ virtual bool setHinges(const PxBase* hinge0, const PxBase* hinge1) = 0; + /** + \brief Get the hinge/revolute joints connected by the gear joint. + + \param[out] hinge0 The first hinge joint + \param[out] hinge1 The second hinge joint + */ + virtual void getHinges(const PxBase*& hinge0, const PxBase*& hinge1) const = 0; + /** \brief Set the desired gear ratio. diff --git a/physx/include/extensions/PxJoint.h b/physx/include/extensions/PxJoint.h index 0d469c00b..9036823fb 100644 --- a/physx/include/extensions/PxJoint.h +++ b/physx/include/extensions/PxJoint.h @@ -103,12 +103,6 @@ struct PxJointActorIndex class PxJoint : public PxBase { -//= 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. -//================================================================================================== public: /** @@ -383,12 +377,6 @@ class PxJoint : public PxBase class PxSpring { -//= 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. -//================================================================================================== public: PxReal stiffness; //!< the spring strength of the drive: that is, the force proportional to the position error diff --git a/physx/include/extensions/PxJointLimit.h b/physx/include/extensions/PxJointLimit.h index c00cbacb6..6c07c2939 100644 --- a/physx/include/extensions/PxJointLimit.h +++ b/physx/include/extensions/PxJointLimit.h @@ -50,12 +50,6 @@ documentation for specific joint types for details. */ class PxJointLimitParameters { -//= 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. -//================================================================================================== public: /** \brief Controls the amount of bounce when the joint hits a limit. @@ -99,31 +93,11 @@ class PxJointLimitParameters */ 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 - 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, - less than half the distance between the upper and lower bounds. Exceeding this value will result in - the limit being active all the time. - - Making this value too small can result in jitter around the limit. - - Default: depends on the joint - - \note This is deprecated in PhysX 5.1 - - @see PxPhysics::getTolerancesScale() - */ - PxReal contactDistance_deprecated; - PxJointLimitParameters() : restitution (0.0f), bounceThreshold (0.0f), stiffness (0.0f), - damping (0.0f), - contactDistance_deprecated (0.0f) + damping (0.0f) { } @@ -131,8 +105,7 @@ class PxJointLimitParameters restitution (p.restitution), bounceThreshold (p.bounceThreshold), stiffness (p.stiffness), - damping (p.damping), - contactDistance_deprecated (p.contactDistance_deprecated) + damping (p.damping) { } @@ -146,8 +119,7 @@ class PxJointLimitParameters return PxIsFinite(restitution) && restitution >= 0 && restitution <= 1 && PxIsFinite(stiffness) && stiffness >= 0 && PxIsFinite(damping) && damping >= 0 && - PxIsFinite(bounceThreshold) && bounceThreshold >= 0 && - PxIsFinite(contactDistance_deprecated) && contactDistance_deprecated >= 0; + PxIsFinite(bounceThreshold) && bounceThreshold >= 0; } PX_INLINE bool isSoft() const @@ -165,12 +137,6 @@ class PxJointLimitParameters */ class PxJointLinearLimit : public PxJointLimitParameters { -//= 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. -//================================================================================================== public: /** \brief the extent of the limit. @@ -183,16 +149,12 @@ class PxJointLinearLimit : public PxJointLimitParameters /** \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_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. + \param[in] extent The extent of the limit - @see PxJointLimitParameters PxTolerancesScale + @see PxJointLimitParameters */ - PxJointLinearLimit(const PxTolerancesScale& scale, PxReal extent, PxReal contactDist_deprecated = -1.0f) - : value(extent) + PxJointLinearLimit(PxReal extent) : value(extent) { - PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated == -1.0f ? 0.01f*scale.length : contactDist_deprecated; } /** @@ -201,7 +163,7 @@ class PxJointLinearLimit : public PxJointLimitParameters \param[in] extent the extent of the limit \param[in] spring the stiffness and damping parameters for the limit spring - @see PxJointLimitParameters PxTolerancesScale + @see PxJointLimitParameters */ PxJointLinearLimit(PxReal extent, const PxSpring& spring) : value(extent) { @@ -228,12 +190,6 @@ class PxJointLinearLimit : public PxJointLimitParameters */ class PxJointLinearLimitPair : public PxJointLimitParameters { -//= 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. -//================================================================================================== public: /** \brief the range of the limit. The upper limit must be no lower than the @@ -247,18 +203,16 @@ class PxJointLinearLimitPair : public PxJointLimitParameters /** \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_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. + \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 @see PxJointLimitParameters PxTolerancesScale */ - PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit = -PX_MAX_F32/3.0f, PxReal upperLimit = PX_MAX_F32/3.0f, PxReal contactDist_deprecated = -1.0f) : + PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit = -PX_MAX_F32/3.0f, PxReal upperLimit = PX_MAX_F32/3.0f) : upper(upperLimit), lower(lowerLimit) { - 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; } @@ -269,7 +223,7 @@ class PxJointLinearLimitPair : public PxJointLimitParameters \param[in] upperLimit The upper distance of the limit \param[in] spring The stiffness and damping parameters of the limit spring - @see PxJointLimitParameters PxTolerancesScale + @see PxJointLimitParameters */ PxJointLinearLimitPair(PxReal lowerLimit, PxReal upperLimit, const PxSpring& spring) : upper(upperLimit), @@ -295,12 +249,6 @@ class PxJointLinearLimitPair : public PxJointLimitParameters class PxJointAngularLimitPair : public PxJointLimitParameters { -//= 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. -//================================================================================================== public: /** \brief the range of the limit. The upper limit must be no lower than the lower limit. @@ -316,17 +264,15 @@ class PxJointAngularLimitPair : public PxJointLimitParameters 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_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. + \param[in] lowerLimit The lower angle of the limit + \param[in] upperLimit The upper angle of the limit @see PxJointLimitParameters */ - PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, PxReal contactDist_deprecated = -1.0f) : + PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit) : upper(upperLimit), lower(lowerLimit) { - PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated ==-1.0f ? PxMin(0.1f, 0.49f*(upperLimit-lowerLimit)) : contactDist_deprecated; bounceThreshold = 0.5f; } @@ -369,12 +315,6 @@ result in jitter. */ class PxJointLimitCone : public PxJointLimitParameters { -//= 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. -//================================================================================================== public: /** \brief the maximum angle from the Y axis of the constraint frame. @@ -397,17 +337,15 @@ class PxJointLimitCone : public PxJointLimitParameters /** \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_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. + \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 @see PxJointLimitParameters */ - PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, PxReal contactDist_deprecated = -1.0f) : + PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle) : yAngle(yLimitAngle), zAngle(zLimitAngle) { - PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated == -1.0f ? PxMin(0.1f, PxMin(yLimitAngle, zLimitAngle)*0.49f) : contactDist_deprecated; bounceThreshold = 0.5f; } @@ -448,12 +386,6 @@ class PxJointLimitCone : public PxJointLimitParameters */ class PxJointLimitPyramid : public PxJointLimitParameters { -//= 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. -//================================================================================================== public: /** \brief the minimum angle from the Y axis of the constraint frame. @@ -494,31 +426,19 @@ class PxJointLimitPyramid : public PxJointLimitParameters /** \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_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. + \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 @see PxJointLimitParameters */ - PxJointLimitPyramid(PxReal yLimitAngleMin, PxReal yLimitAngleMax, PxReal zLimitAngleMin, PxReal zLimitAngleMax, PxReal contactDist_deprecated = -1.0f) : + PxJointLimitPyramid(PxReal yLimitAngleMin, PxReal yLimitAngleMax, PxReal zLimitAngleMin, PxReal zLimitAngleMax) : yAngleMin(yLimitAngleMin), yAngleMax(yLimitAngleMax), zAngleMin(zLimitAngleMin), zAngleMax(zLimitAngleMax) { - 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_deprecated = contactDist_deprecated == PxMin(contactDistY, contactDistZ); - } - else - { - PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated; - } - bounceThreshold = 0.5f; } diff --git a/physx/include/extensions/PxParticleClothCooker.h b/physx/include/extensions/PxParticleClothCooker.h index 537e86f6c..7b8db2620 100644 --- a/physx/include/extensions/PxParticleClothCooker.h +++ b/physx/include/extensions/PxParticleClothCooker.h @@ -102,12 +102,13 @@ class PxParticleClothCooker \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. +\param[in] bendingConstraintMaxAngle The maximum angle (in radians) 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 + PxU32 constraintTypeFlags = ExtGpu::PxParticleClothConstraint::eTYPE_ALL, + PxVec3 verticalDirection = PxVec3(0.0f, 1.0f, 0.0f), PxReal bendingConstraintMaxAngle = 20.0f*PxTwoPi/360.0f ); diff --git a/physx/include/extensions/PxPrismaticJoint.h b/physx/include/extensions/PxPrismaticJoint.h index d34c190c3..fb47c72a2 100644 --- a/physx/include/extensions/PxPrismaticJoint.h +++ b/physx/include/extensions/PxPrismaticJoint.h @@ -144,71 +144,6 @@ class PxPrismaticJoint : public PxJoint */ virtual PxPrismaticJointFlags getPrismaticJointFlags() const = 0; - /** - \brief Set the linear tolerance threshold for projection. - - If the joint separates by more than this distance along its locked degrees of freedom, the solver - will move the bodies to close the distance. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - This value must be nonnegative. - - Range: [0, PX_MAX_F32)
- Default: 1e10f - - \param[in] tolerance the linear tolerance threshold - - @see getProjectionLinearTolerance() - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; - - /** - \brief Get the linear tolerance threshold for projection. - - \return the linear tolerance threshold in radians - - @see setProjectionLinearTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; - - /** - \brief Set the angular tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION - is set for the joint. - - If the joint separates by more than this distance along its locked degrees of freedom, the solver - will move the bodies to close the distance. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0, PX_MAX_F32)
- Default: Pi - - \param[in] tolerance the linear tolerance threshold - - @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; - - /** - \brief Get the angular tolerance threshold for projection. - - @see getProjectionAngularTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; - /** \brief Returns string name of PxPrismaticJoint, used for serialization */ diff --git a/physx/include/extensions/PxRackAndPinionJoint.h b/physx/include/extensions/PxRackAndPinionJoint.h index 953ff04df..d4a7cdb8a 100644 --- a/physx/include/extensions/PxRackAndPinionJoint.h +++ b/physx/include/extensions/PxRackAndPinionJoint.h @@ -83,6 +83,14 @@ namespace physx */ virtual bool setJoints(const PxBase* hinge, const PxBase* prismatic) = 0; + /** + \brief Get the hinge & prismatic joints connected by the rack & pinion joint. + + \param[out] hinge The hinge joint (pinion) + \param[out] prismatic The prismatic joint (rack) + */ + virtual void getJoints(const PxBase*& hinge, const PxBase*& prismatic) const = 0; + /** \brief Set the desired ratio directly. diff --git a/physx/include/extensions/PxRepXSerializer.h b/physx/include/extensions/PxRepXSerializer.h index 92f8211d0..47c3b2b7c 100644 --- a/physx/include/extensions/PxRepXSerializer.h +++ b/physx/include/extensions/PxRepXSerializer.h @@ -48,6 +48,8 @@ namespace physx /** \brief Serializer interface for RepX (Xml) serialization. + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + In order to serialize a class to RepX both a PxSerializer and a PxRepXSerializer implementation are needed. @@ -63,7 +65,7 @@ namespace physx @see PxSerializer, PX_NEW_REPX_SERIALIZER, PxSerializationRegistry::registerRepXSerializer */ - class PxRepXSerializer + class PX_DEPRECATED PxRepXSerializer { protected: virtual ~PxRepXSerializer(){} @@ -106,17 +108,19 @@ namespace physx /** \brief Inline helper template function to create PxRepXObject from TDataType type supporting PxTypeInfo::name. +\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. */ template -PX_INLINE physx::PxRepXObject PxCreateRepXObject(const TDataType* inType, const physx::PxSerialObjectId inId) +PX_DEPRECATED PX_INLINE physx::PxRepXObject PxCreateRepXObject(const TDataType* inType, const physx::PxSerialObjectId inId) { return physx::PxRepXObject(physx::PxTypeInfo::name(), inType, inId); } /** \brief Inline helper function to create PxRepXObject from a PxBase instance. +\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. */ -PX_INLINE physx::PxRepXObject PxCreateRepXObject(const physx::PxBase* inType, const physx::PxSerialObjectId inId) +PX_DEPRECATED PX_INLINE physx::PxRepXObject PxCreateRepXObject(const physx::PxBase* inType, const physx::PxSerialObjectId inId) { PX_ASSERT(inType); return physx::PxRepXObject(inType->getConcreteTypeName(), inType, inId); @@ -124,21 +128,24 @@ PX_INLINE physx::PxRepXObject PxCreateRepXObject(const physx::PxBase* inType, co /** \brief Inline helper template function to create PxRepXObject form TDataType type using inType pointer as a PxSerialObjectId id. +\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. */ template -PX_INLINE physx::PxRepXObject PxCreateRepXObject(const TDataType* inType) +PX_DEPRECATED PX_INLINE physx::PxRepXObject PxCreateRepXObject(const TDataType* inType) { return PxCreateRepXObject(inType, static_cast(size_t(inType))); } /** \brief Preprocessor macro for RepX serializer creation. +\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. */ #define PX_NEW_REPX_SERIALIZER(T) \ *PX_PLACEMENT_NEW(PxGetAllocatorCallback()->allocate(sizeof(T), "PxRepXSerializer", __FILE__, __LINE__ ), T)(*PxGetAllocatorCallback()) /** \brief Preprocessor Macro to simplify RepX serializer delete. +\deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. */ #define PX_DELETE_REPX_SERIALIZER(x) \ { PxRepXSerializer* s = x; if (s) { PxGetAllocatorCallback()->deallocate(s); } } diff --git a/physx/include/extensions/PxRepXSimpleType.h b/physx/include/extensions/PxRepXSimpleType.h index 0eee59929..e505194e3 100644 --- a/physx/include/extensions/PxRepXSimpleType.h +++ b/physx/include/extensions/PxRepXSimpleType.h @@ -45,8 +45,10 @@ namespace physx /** \brief Helper class containing the mapping of id to object, and type name. + + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. */ - struct PxRepXObject + struct PX_DEPRECATED PxRepXObject { /** \brief Identifies the extension meant to handle this object. @@ -75,16 +77,18 @@ namespace physx /** \brief Arguments required to instantiate a serializable object from RepX. + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + Extra arguments can be added to the object map under special ids. @see PxRepXSerializer::objectToFile, PxRepXSerializer::fileToObject */ - struct PxRepXInstantiationArgs + struct PX_DEPRECATED PxRepXInstantiationArgs { - PxPhysics& physics; - PxCooking* cooker; - PxStringTable* stringTable; - PxRepXInstantiationArgs( PxPhysics& inPhysics, PxCooking* inCooking = NULL , PxStringTable* inStringTable = NULL ) + PxPhysics& physics; + const PxCookingParams* cooker; + PxStringTable* stringTable; + PxRepXInstantiationArgs( PxPhysics& inPhysics, const PxCookingParams* inCooking = NULL , PxStringTable* inStringTable = NULL ) : physics( inPhysics ) , cooker( inCooking ) , stringTable( inStringTable ) diff --git a/physx/include/extensions/PxRevoluteJoint.h b/physx/include/extensions/PxRevoluteJoint.h index 55bed4fc5..dd8d648e7 100644 --- a/physx/include/extensions/PxRevoluteJoint.h +++ b/physx/include/extensions/PxRevoluteJoint.h @@ -236,72 +236,6 @@ class PxRevoluteJoint : public PxJoint */ virtual PxRevoluteJointFlags getRevoluteJointFlags() const = 0; - /** - \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION - is set for the joint. - - If the joint separates by more than this distance along its locked degrees of freedom, the solver - will move the bodies to close the distance. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0, PX_MAX_F32)
- Default: 1e10f - - \param[in] tolerance the linear tolerance threshold - - @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; - - /** - \brief Get the linear tolerance threshold for projection. - - \return the linear tolerance threshold - - @see setProjectionLinearTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; - - /** - \brief Set the angular tolerance threshold for projection. Projection is enabled if - PxConstraintFlag::ePROJECTION is set for the joint. - - If the joint deviates by more than this angle around its locked angular degrees of freedom, - the solver will move the bodies to close the angle. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0,Pi]
- Default: Pi - - \param[in] tolerance the angular tolerance threshold in radians - - @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; - - /** - \brief gets the angular tolerance threshold for projection. - - \return the angular tolerance threshold in radians - - @see setProjectionAngularTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; - /** \brief Returns string name of PxRevoluteJoint, used for serialization */ diff --git a/physx/include/extensions/PxRigidActorExt.h b/physx/include/extensions/PxRigidActorExt.h index cb331cd4b..73209419f 100644 --- a/physx/include/extensions/PxRigidActorExt.h +++ b/physx/include/extensions/PxRigidActorExt.h @@ -42,7 +42,6 @@ namespace physx #endif class PxBVH; -class PxCooking; /** \brief utility functions for use with PxRigidActor and subclasses diff --git a/physx/include/extensions/PxSerialization.h b/physx/include/extensions/PxSerialization.h index fca17512a..b9fd75b18 100644 --- a/physx/include/extensions/PxSerialization.h +++ b/physx/include/extensions/PxSerialization.h @@ -44,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 "0E16D844227B469DB23DA9C42CB4E624" +#define PX_BINARY_SERIAL_VERSION "B82604A420D74E16931478583B38833D" #if !PX_DOXYGEN @@ -65,11 +65,14 @@ class PxSerialization /** \brief Additional PxScene and PxPhysics options stored in XML serialized data. + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + The PxXmlMiscParameter parameter can be serialized and deserialized along with PxCollection instances (XML only). This is for application use only and has no impact on how objects are serialized or deserialized. + @see PxSerialization::createCollectionFromXml, PxSerialization::serializeCollectionToXml */ - struct PxXmlMiscParameter + struct PX_DEPRECATED PxXmlMiscParameter { /** \brief Up vector for the scene reference coordinate system. @@ -154,9 +157,11 @@ class PxSerialization /** \brief Creates a PxCollection from XML data. + + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. \param inputData The input data containing the XML collection. - \param cooking PxCooking instance used for sdk object instantiation. + \param params Cooking parameters used for sdk object instantiation. \param sr PxSerializationRegistry instance with information about registered classes. \param externalRefs PxCollection used to resolve external references. \param stringTable PxStringTable instance used for storing object names. @@ -165,7 +170,7 @@ class PxSerialization @see PxCollection, PxSerializationRegistry, PxInputData, PxStringTable, PxCooking, PxSerialization::PxXmlMiscParameter */ - static PxCollection* createCollectionFromXml(PxInputData& inputData, PxCooking& cooking, PxSerializationRegistry& sr, const PxCollection* externalRefs = NULL, PxStringTable* stringTable = NULL, PxXmlMiscParameter* outArgs = NULL); + PX_DEPRECATED static PxCollection* createCollectionFromXml(PxInputData& inputData, const PxCookingParams& params, PxSerializationRegistry& sr, const PxCollection* externalRefs = NULL, PxStringTable* stringTable = NULL, PxXmlMiscParameter* outArgs = NULL); /** \brief Deserializes a PxCollection from memory. @@ -189,6 +194,8 @@ class PxSerialization /** \brief Serializes a physics collection to an XML output stream. + \deprecated Xml serialization is deprecated. An alternative serialization system is provided through USD Physics. + The collection to be serialized needs to be complete @see PxSerialization.complete. Optionally the XML may contain meshes in binary cooked format for fast loading. It does this when providing a valid non-null PxCooking pointer. @@ -197,14 +204,14 @@ class PxSerialization \param outputStream Stream to save collection to. \param collection PxCollection instance which is serialized. The collection needs to be complete with respect to the externalRefs collection. \param sr PxSerializationRegistry instance with information about registered classes. - \param cooking Optional pointer to cooking instance. If provided, cooked mesh data is cached for fast loading. + \param params Optional pointer to cooking params. If provided, cooked mesh data is cached for fast loading. \param externalRefs Collection containing external references. \param inArgs Optional parameters of physics and scene serialized to XML along with the collection. See #PxSerialization::PxXmlMiscParameter \return true if the collection is successfully serialized. @see PxCollection, PxOutputStream, PxSerializationRegistry, PxCooking, PxSerialization::PxXmlMiscParameter */ - static bool serializeCollectionToXml(PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, PxCooking* cooking = NULL, const PxCollection* externalRefs = NULL, PxXmlMiscParameter* inArgs = NULL); + PX_DEPRECATED static bool serializeCollectionToXml(PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, const PxCookingParams* params = NULL, const PxCollection* externalRefs = NULL, PxXmlMiscParameter* inArgs = NULL); /** \brief Serializes a collection to a binary stream. diff --git a/physx/include/extensions/PxShapeExt.h b/physx/include/extensions/PxShapeExt.h index e0c059d4e..5f15f8dc1 100644 --- a/physx/include/extensions/PxShapeExt.h +++ b/physx/include/extensions/PxShapeExt.h @@ -63,6 +63,7 @@ class PxShapeExt */ static PX_INLINE PxTransform getGlobalPose(const PxShape& shape, const PxRigidActor& actor) { + // PT:: tag: scalar transform*transform return actor.getGlobalPose() * shape.getLocalPose(); } @@ -130,7 +131,6 @@ class PxShapeExt return PxGeometryQuery::sweep(unitDir, distance, otherGeom, otherGeomPose, shape.getGeometry(), getGlobalPose(shape, actor), sweepHit, hitFlags); } - /** \brief Retrieves the axis aligned bounding box enclosing the shape. @@ -144,7 +144,9 @@ class PxShapeExt */ static PX_INLINE PxBounds3 getWorldBounds(const PxShape& shape, const PxRigidActor& actor, float inflation=1.01f) { - return PxGeometryQuery::getWorldBounds(shape.getGeometry(), getGlobalPose(shape, actor), inflation); + PxBounds3 bounds; + PxGeometryQuery::computeGeomBounds(bounds, shape.getGeometry(), getGlobalPose(shape, actor), 0.0f, inflation); + return bounds; } }; diff --git a/physx/include/extensions/PxSoftBodyExt.h b/physx/include/extensions/PxSoftBodyExt.h index ffc1c3093..d3b6e5c5a 100644 --- a/physx/include/extensions/PxSoftBodyExt.h +++ b/physx/include/extensions/PxSoftBodyExt.h @@ -33,7 +33,11 @@ */ #include "foundation/PxTransform.h" +#include "foundation/PxUserAllocated.h" #include "PxSoftBody.h" +#include "PxSoftBodyFlag.h" +#include "cudamanager/PxCudaContextManager.h" +#include "cudamanager/PxCudaTypes.h" #if !PX_DOXYGEN namespace physx @@ -46,7 +50,7 @@ class PxInsertionCallback; class PxSoftBodyMesh; /** -\brief utility functions for use with PxSoftBody and subclasses +\brief Utility functions for use with PxSoftBody and subclasses */ class PxSoftBodyExt { @@ -54,39 +58,39 @@ class PxSoftBodyExt /** \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 buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassBufferD() and getSimVelocityBufferD() - 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. + The inverse mass is stored in the 4th component (the first three components are x, y, z coordinates) of the simulation mesh's position buffer. \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 + \param[in] simPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the simulation mesh. - @see PxSoftBody PxSoftBody::getSimPositionInvMassCPU() PxSoftBody::getSimVelocityInvMassCPU() + @see PxSoftBody PxSoftBody::getSimPositionInvMassBufferD() */ - static void updateMass(PxSoftBody& softBody, const PxReal density, const PxReal maxInvMassRatio); + static void updateMass(PxSoftBody& softBody, const PxReal density, const PxReal maxInvMassRatio, PxVec4* simPositionsPinned); /** \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 buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassBufferD()) and getSimVelocityBufferD() - 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. + The inverse mass is stored in the 4th component (the first three components are x, y, z coordinates) of the simulation mesh's position buffer. \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() + \param[in] simPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the simulation mesh. + + @see PxSoftBody PxSoftBody::getSimPositionInvMassBufferD() */ - static void setMass(PxSoftBody& softBody, const PxReal mass, const PxReal maxInvMassRatio); + static void setMass(PxSoftBody& softBody, const PxReal mass, const PxReal maxInvMassRatio, PxVec4* simPositionsPinned); /** \brief Transforms a SoftBody - The buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassCPU() and getSimVelocityInvMassCPU() + The buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassBufferD() and getSimVelocityBufferD() 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. @@ -95,32 +99,58 @@ class PxSoftBodyExt \param[in] softBody The soft body which is transformed \param[in] transform The transform to apply \param[in] scale A scaling factor + \param[in] simPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the simulation mesh. + \param[in] simVelocitiesPinned A pointer to a pinned host memory buffer containing velocities for each vertex of the simulation mesh. + \param[in] collPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the collision mesh. + \param[in] restPositionsPinned A pointer to a pinned host memory buffer containing rest positions of the collision mesh. - @see PxSoftBody PxSoftBody::getSimPositionInvMassCPU() PxSoftBody::getSimVelocityInvMassCPU() + @see PxSoftBody */ - static void transform(PxSoftBody& softBody, const PxTransform& transform, const PxReal scale); + static void transform(PxSoftBody& softBody, const PxTransform& transform, const PxReal scale, PxVec4* simPositionsPinned, PxVec4* simVelocitiesPinned, PxVec4* collPositionsPinned, PxVec4* restPositionsPinned); /** \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() + The buffer affected by this operation can be obtained from the SoftBody using the method getPositionInvMassBufferD() \param[in] softBody The soft body which will get its collision mesh vertices updated + \param[in] simPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the simulation mesh. + \param[in] collPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the collision mesh. + + @see PxSoftBody + */ + static void updateEmbeddedCollisionMesh(PxSoftBody& softBody, PxVec4* simPositionsPinned, PxVec4* collPositionsPinned); + + /** + \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] simPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the simulation mesh. + \param[in] simVelocitiesPinned A pointer to a pinned host memory buffer containing velocities for each vertex of the simulation mesh. + \param[in] collPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the collision mesh. + \param[in] restPositionsPinned A pointer to a pinned host memory buffer containing rest positions of the collision mesh. + \param[in] stream A cuda stream to perform the copies. - @see PxSoftBody PxSoftBody::getPositionInvMassCPU() + @see PxSoftBody + @deprecated Use copyToDevice() instead. */ - static void updateEmbeddedCollisionMesh(PxSoftBody& softBody); + PX_DEPRECATED static void commit(PxSoftBody& softBody, PxSoftBodyDataFlags flags, PxVec4* simPositionsPinned, PxVec4* simVelocitiesPinned, PxVec4* collPositionsPinned, PxVec4* restPositionsPinned, CUstream stream = CUstream(0)); /** \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 + \param[in] simPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the simulation mesh. + \param[in] simVelocitiesPinned A pointer to a pinned host memory buffer containing velocities for each vertex of the simulation mesh. + \param[in] collPositionsPinned A pointer to a pinned host memory buffer containing positions and inverse masses for each vertex of the collision mesh. + \param[in] restPositionsPinned A pointer to a pinned host memory buffer containing rest positions of the collision mesh. + \param[in] stream A cuda stream to perform the copies. @see PxSoftBody */ - static void commit(PxSoftBody& softBody, PxSoftBodyDataFlags flags, bool flush = false); + static void copyToDevice(PxSoftBody& softBody, PxSoftBodyDataFlags flags, PxVec4* simPositionsPinned, PxVec4* simVelocitiesPinned, PxVec4* collPositionsPinned, PxVec4* restPositionsPinned, CUstream stream = CUstream(0)); /** \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. @@ -187,6 +217,33 @@ class PxSoftBodyExt 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); + + /** + \brief allocates and initializes pinned host memory buffers from an actor with shape. + + \param[in] softBody A PxSoftBody that has a valid shape attached to it. + \param[in] cudaContextManager The PxCudaContextManager of the scene this soft body will be simulated in + \param[in] simPositionInvMassPinned A reference to a pointer for the return value of the simPositionInvMassPinned buffer, will be set by this function. + \param[in] simVelocityPinned A reference to a pointer for the return value of the simVelocityPinned buffer, will be set by this function. + \param[in] collPositionInvMassPinned A reference to a pointer for the return value of the collPositionInvMassPinned buffer, will be set by this function. + \param[in] restPositionPinned A reference to a pointer for the return value of the restPositionPinned buffer, will be set by this function. + + @see PxSoftBody + */ + static void allocateAndInitializeHostMirror(PxSoftBody& softBody, PxCudaContextManager* cudaContextManager, PxVec4*& simPositionInvMassPinned, PxVec4*& simVelocityPinned, PxVec4*& collPositionInvMassPinned, PxVec4*& restPositionPinned); + + /** + \brief Given a set of points and a set of tetrahedra, it finds the equilibrium state of the softbody. Every input point is either fixed or can move freely. + + \param[in] verticesOriginal Mesh vertex positions in undeformed original state. + \param[in] verticesDeformed Mesh vertex positions in new deformed state. Only fixed vertices must have their final location, all other locations will get updated by the method. + \param[in] nbVertices The number of vertices. + \param[in] tetrahedra The tetrahedra. + \param[in] nbTetraheda The number of tetrahedra. + \param[in] vertexIsFixed Optional input that specifies which vertex is fixed and which one can move to relax the tension. If not provided, vertices from verticesOriginal which have a .w value of 0 will be considered fixed. + \param[in] numIterations The number of stress relaxation iterations to run. + */ + static void relaxSoftBodyMesh(const PxVec4* verticesOriginal, PxVec4* verticesDeformed, PxU32 nbVertices, const PxU32* tetrahedra, PxU32 nbTetraheda, const bool* vertexIsFixed = NULL, PxU32 numIterations = 200); }; #if !PX_DOXYGEN diff --git a/physx/include/extensions/PxSphericalJoint.h b/physx/include/extensions/PxSphericalJoint.h index bee05853f..20d410dd7 100644 --- a/physx/include/extensions/PxSphericalJoint.h +++ b/physx/include/extensions/PxSphericalJoint.h @@ -150,39 +150,6 @@ class PxSphericalJoint : public PxJoint */ virtual PxSphericalJointFlags getSphericalJointFlags() const = 0; - /** - \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION - is set for the joint. - - If the joint separates by more than this distance along its locked degrees of freedom, the solver - will move the bodies to close the distance. - - Setting a very small tolerance may result in simulation jitter or other artifacts. - - Sometimes it is not possible to project (for example when the joints form a cycle). - - Range: [0, PX_MAX_F32)
- Default: 1e10f - - \param[in] tolerance the linear tolerance threshold - - @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION - - @deprecated - */ - PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; - - /** - \brief Get the linear tolerance threshold for projection. - - \return the linear tolerance threshold - - @see setProjectionLinearTolerance() - - @deprecated - */ - PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; - /** \brief Returns string name of PxSphericalJoint, used for serialization */ diff --git a/physx/include/extensions/PxTetMakerExt.h b/physx/include/extensions/PxTetMakerExt.h index e5d8dd51b..7ae274a91 100644 --- a/physx/include/extensions/PxTetMakerExt.h +++ b/physx/include/extensions/PxTetMakerExt.h @@ -130,10 +130,14 @@ class PxTetMaker \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. + \param[in] projectSimplifiedPointsOnInputMeshSurface If set to true, the simplified points will lie exactly on the original surface. + \param[out] outputVertexToInputTriangle Optional indices providing the triangle index per resulting vertex. Only available when projectSimplifiedPointsOnInputMeshSurface is set to true + \param[in] removeDisconnectedPatches Enables the optional removal of disconnected triangles in the mesh. Only the largest connected set/patch will be kept */ 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); + PxArray *vertexMap = NULL, PxReal edgeLengthCostWeight = 0.1f, PxReal flatnessDetectionThreshold = 0.01f, + bool projectSimplifiedPointsOnInputMeshSurface = false, PxArray* outputVertexToInputTriangle = NULL, bool removeDisconnectedPatches = false); /** \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. @@ -145,9 +149,23 @@ class PxTetMaker \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); + static void remeshTriangleMesh(const PxArray& inputVertices, const PxArray&inputIndices, PxU32 gridResolution, + PxArray& outputVertices, PxArray& outputIndices, PxArray *vertexMap = NULL); + + /** + \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] nbVertices The number of 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] nbIndices The number of indices of the input triangle mesh (equal to three times the number of triangles) + \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 PxVec3* inputVertices, PxU32 nbVertices, const PxU32* inputIndices, PxU32 nbIndices, PxU32 gridResolution, + PxArray& outputVertices, PxArray& outputIndices, PxArray *vertexMap = NULL); /** \brief Creates a tetrahedral mesh using an octree. @@ -177,6 +195,23 @@ class PxTetMaker PxArray& outputVertices, PxArray& outputIndices, PxI32 resolution, PxI32 numRelaxationIterations = 5, PxF32 relMinTetVolume = 0.05f); + /** + \brief Creates a tetrahedral mesh by relaxing a voxel mesh around the input mesh + + \param[in] triangles The indices of the input triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[in] numTriangles The number of triangles + \param[out] islandIndexPerTriangle Every triangle gets an island index assigned. Triangles with the same island index belong to the same patch of connected triangles. + */ + static void detectTriangleIslands(const PxI32* triangles, PxU32 numTriangles, PxArray& islandIndexPerTriangle); + + /** + \brief Creates a tetrahedral mesh by relaxing a voxel mesh around the input mesh + + \param[in] islandIndexPerTriangle An island marker per triangles. All triangles with the same marker belong to an island. Can becomputed using the method detectTriangleIslands. + \param[in] numTriangles The number of triangles + \return The marker value of the island that contains the most triangles + */ + static PxU32 findLargestIslandId(const PxU32* islandIndexPerTriangle, PxU32 numTriangles); }; #if !PX_DOXYGEN diff --git a/physx/include/extensions/PxTetrahedronMeshExt.h b/physx/include/extensions/PxTetrahedronMeshExt.h index ca24c4415..8aa8cc4ff 100644 --- a/physx/include/extensions/PxTetrahedronMeshExt.h +++ b/physx/include/extensions/PxTetrahedronMeshExt.h @@ -62,11 +62,21 @@ namespace physx \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 + \param[out] 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); + /** Associates points with closest tetrahedra from input tetrahedral mesh + + \param[in] tetMeshVertices The tetrahedral mesh vertices + \param[in] tetMeshIndices The tetraheral mesh indices + \param[in] pointsToEmbed The points for which the embedding should be created + \param[in] barycentricCoordinates The output barycentric coordinates for each input point relative to its closest tetrahedron + \param[in] tetLinks The output indices of the closest tetrahedron for each input point + */ + static void createPointsToTetrahedronMap(const PxArray& tetMeshVertices, const PxArray& tetMeshIndices, const PxArray& pointsToEmbed, PxArray& barycentricCoordinates, PxArray& tetLinks); + /** Extracts the surface triangles of a tetmesh The extracted triangle's vertex indices point to the vertex buffer of the tetmesh. diff --git a/physx/include/foundation/PxAlloca.h b/physx/include/foundation/PxAlloca.h index 088cda195..863b7c62e 100644 --- a/physx/include/foundation/PxAlloca.h +++ b/physx/include/foundation/PxAlloca.h @@ -60,31 +60,31 @@ class PxScopedPointer : private Alloc // Don't use inline for alloca !!! #if PX_WINDOWS_FAMILY -#include -#define PxAlloca(x) _alloca(x) + #include + #define PxAlloca(x) _alloca(x) #elif PX_LINUX -#include -#define PxAlloca(x) alloca(x) + #include + #define PxAlloca(x) alloca(x) #elif PX_APPLE_FAMILY -#include -#define PxAlloca(x) alloca(x) + #include + #define PxAlloca(x) alloca(x) #elif PX_SWITCH -#include -#define PxAlloca(x) alloca(x) + #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)); \ +#define PX_ALLOCA(var, type, count) \ + physx::PxScopedPointer var; \ + { \ + const uint32_t size = sizeof(type) * (count); \ + var.mOwned = size > 1024; \ + if(var.mOwned) \ + var.mPointer = reinterpret_cast(physx::PxTempAllocator().allocate(size, PX_FL)); \ + else \ + var.mPointer = reinterpret_cast(PxAlloca(size)); \ } #endif diff --git a/physx/include/foundation/PxAllocator.h b/physx/include/foundation/PxAllocator.h index 5fb41997d..64ec5d57f 100644 --- a/physx/include/foundation/PxAllocator.h +++ b/physx/include/foundation/PxAllocator.h @@ -57,7 +57,6 @@ #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. @@ -91,7 +90,7 @@ namespace physx { #endif /** - Allocator used to access the global PxAllocatorCallback instance without providing additional information. + \brief Allocator used to access the global PxAllocatorCallback instance without providing additional information. */ class PxAllocator { @@ -110,8 +109,8 @@ namespace physx } }; - /* - * Bootstrap allocator using malloc/free. + /** + * \brief Bootstrap allocator using malloc/free. * Don't use unless your objects get allocated before foundation is initialized. */ class PxRawAllocator @@ -132,7 +131,7 @@ namespace physx } }; - /* + /** \brief Virtual allocator callback used to provide run-time defined allocators to foundation types like Array or Bitmap. This is used by VirtualAllocator */ @@ -146,13 +145,11 @@ namespace physx 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 + 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. + therefore methods are provided to set the callback later. */ class PxVirtualAllocator { @@ -174,6 +171,16 @@ namespace physx mCallback->deallocate(ptr); } + void setCallback(PxVirtualAllocatorCallback* callback) + { + mCallback = callback; + } + + PxVirtualAllocatorCallback* getCallback() + { + return mCallback; + } + private: PxVirtualAllocatorCallback* mCallback; const int mGroup; @@ -181,14 +188,14 @@ namespace physx }; /** - Allocator used to access the global PxAllocatorCallback instance using a static name derived from T. + \brief Allocator used to access the global PxAllocatorCallback instance using a static name derived from T. */ template class PxReflectionAllocator { - static const char* getName() + static const char* getName(bool reportAllocationNames) { - if (!PxGetFoundation().getReportAllocationNames()) + if(!reportAllocationNames) return ""; #if PX_GCC_FAMILY return __PRETTY_FUNCTION__; @@ -206,12 +213,18 @@ namespace physx PX_FORCE_INLINE void* allocate(size_t size, const char* filename, int line) { - return size ? PxGetBroadcastAllocator()->allocate(size, getName(), filename, line) : NULL; + if(!size) + return NULL; + + bool reportAllocationNames; + PxAllocatorCallback* cb = PxGetBroadcastAllocator(&reportAllocationNames); + + return cb->allocate(size, getName(reportAllocationNames), filename, line); } PX_FORCE_INLINE void deallocate(void* ptr) { - if (ptr) + if(ptr) PxGetBroadcastAllocator()->deallocate(ptr); } }; diff --git a/physx/include/foundation/PxAssert.h b/physx/include/foundation/PxAssert.h index f1d4d2688..2ba13b07e 100644 --- a/physx/include/foundation/PxAssert.h +++ b/physx/include/foundation/PxAssert.h @@ -42,28 +42,9 @@ namespace physx #endif /** - * @brief Base class to handle assert failures - * @deprecated + * @brief Built-in assert function */ -class PX_DEPRECATED PxAssertHandler -{ - public: - virtual ~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); - +PX_FOUNDATION_API void PxAssert(const char* exp, const char* file, int line, bool& ignore); #if !PX_ENABLE_ASSERTS #define PX_ASSERT(exp) ((void)0) @@ -71,29 +52,29 @@ PX_FOUNDATION_API PX_DEPRECATED void PxSetAssertHandler(PxAssertHandler& handler #define PX_ASSERT_WITH_MESSAGE(condition, message) ((void)0) #else #if PX_VC - #define PX_CODE_ANALYSIS_ASSUME(exp) \ + #define PX_CODE_ANALYSIS_ASSUME(exp) \ __analysis_assume(!!(exp)) // This macro will be used to get rid of analysis warning messages if a PX_ASSERT is used // to "guard" illegal mem access, for example. #else #define PX_CODE_ANALYSIS_ASSUME(exp) #endif - #define PX_ASSERT(exp) \ - { \ - static bool _ignore = false; \ - ((void)((!!(exp)) || (!_ignore && (physx::PxGetAssertHandler()(#exp, __FILE__, __LINE__, _ignore), false)))); \ - PX_CODE_ANALYSIS_ASSUME(exp); \ + #define PX_ASSERT(exp) \ + { \ + static bool _ignore = false; \ + ((void)((!!(exp)) || (!_ignore && (physx::PxAssert(#exp, PX_FL, _ignore), false)))); \ + PX_CODE_ANALYSIS_ASSUME(exp); \ } - #define PX_ALWAYS_ASSERT_MESSAGE(exp) \ - { \ - static bool _ignore = false; \ - if(!_ignore) \ - physx::PxGetAssertHandler()(exp, __FILE__, __LINE__, _ignore); \ + #define PX_ALWAYS_ASSERT_MESSAGE(exp) \ + { \ + static bool _ignore = false; \ + if(!_ignore) \ + physx::PxAssert(exp, PX_FL, _ignore); \ } - #define PX_ASSERT_WITH_MESSAGE(exp, message) \ - { \ - static bool _ignore = false; \ - ((void)((!!(exp)) || (!_ignore && (physx::PxGetAssertHandler()(message, __FILE__, __LINE__, _ignore), false)))); \ - PX_CODE_ANALYSIS_ASSUME(exp); \ + #define PX_ASSERT_WITH_MESSAGE(exp, message) \ + { \ + static bool _ignore = false; \ + ((void)((!!(exp)) || (!_ignore && (physx::PxAssert(message, PX_FL, _ignore), false)))); \ + PX_CODE_ANALYSIS_ASSUME(exp); \ } #endif // !PX_ENABLE_ASSERTS diff --git a/physx/include/foundation/PxBasicTemplates.h b/physx/include/foundation/PxBasicTemplates.h index 7243e5d8a..5a036650a 100644 --- a/physx/include/foundation/PxBasicTemplates.h +++ b/physx/include/foundation/PxBasicTemplates.h @@ -68,28 +68,26 @@ namespace physx public: F first; S second; - PX_CUDA_CALLABLE PxPair() : first(F()), second(S()) + PX_CUDA_CALLABLE PX_INLINE PxPair() : first(F()), second(S()) { } - PX_CUDA_CALLABLE PxPair(const F& f, const S& s) : first(f), second(s) + PX_CUDA_CALLABLE PX_INLINE PxPair(const F& f, const S& s) : first(f), second(s) { } - PX_CUDA_CALLABLE PxPair(const PxPair& p) : first(p.first), second(p.second) + PX_CUDA_CALLABLE PX_INLINE 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) + PX_CUDA_CALLABLE PX_INLINE PxPair& operator=(const PxPair& p) { first = p.first; second = p.second; return *this; } - PX_CUDA_CALLABLE bool operator==(const PxPair& p) const + PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxPair& p) const { return first == p.first && second == p.second; } - PX_CUDA_CALLABLE bool operator<(const PxPair& p) const + PX_CUDA_CALLABLE PX_INLINE bool operator<(const PxPair& p) const { if (first < p.first) return true; diff --git a/physx/include/foundation/PxBitMap.h b/physx/include/foundation/PxBitMap.h index cb7ce9d17..fa36de508 100644 --- a/physx/include/foundation/PxBitMap.h +++ b/physx/include/foundation/PxBitMap.h @@ -50,13 +50,6 @@ namespace physx 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: @@ -64,7 +57,7 @@ namespace physx // PX_SERIALIZATION /* todo: explicit */ PxBitMapBase(const PxEMPTY) { - if (mMap) + if(mMap) mWordCount |= PX_SIGN_BITMASK; } //~PX_SERIALIZATION @@ -80,12 +73,12 @@ namespace physx PX_INLINE void release() { - if (mMap && !isInUserMemory()) + if(mMap && !isInUserMemory()) mAllocator.deallocate(mMap); mMap = NULL; } - PX_INLINE PxAllocator& getAllocator() { return mAllocator; } + PX_FORCE_INLINE PxAllocator& getAllocator() { return mAllocator; } PX_INLINE void growAndSet(PxU32 index) { @@ -181,8 +174,7 @@ namespace physx void setWords(PxU32* map, PxU32 wordCount) { mMap = map; - mWordCount = wordCount; - mWordCount |= PX_SIGN_BITMASK; + mWordCount = wordCount | PX_SIGN_BITMASK; } // !!! only sets /last/ bit to value @@ -193,23 +185,23 @@ namespace physx extend(newBitCount); } - PxU32 size() const { return getWordCount() * 32; } + PX_FORCE_INLINE 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()) + 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 + // NOTE: we can probably do this faster, since the last steps in PxBitCount 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;) + for(PxU32 i = wordCount; i-- > 0;) { - if (mMap[i]) + if(mMap[i]) return (i << 5) + PxHighestSetBit(mMap[i]); } return PxU32(0); @@ -273,7 +265,6 @@ namespace physx 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: @@ -294,13 +285,20 @@ namespace physx PX_INLINE PxU32 getNext() { - if (mBlock) + if(mBlock) { - PxU32 bitIndex = mIndex << 5 | PxLowestSetBit(mBlock); - mBlock &= mBlock - 1; + PxU32 block = mBlock; + PxU32 index = mIndex; + + const PxU32 bitIndex = index << 5 | PxLowestSetBit(block); + block &= block - 1; PxU32 wordCount = mBitMap.getWordCount(); - while (!mBlock && ++mIndex < wordCount) - mBlock = mBitMap.mMap[mIndex]; + while(!block && ++index < wordCount) + block = mBitMap.mMap[index]; + + mBlock = block; + mIndex = index; + return bitIndex; } return DONE; @@ -308,10 +306,15 @@ namespace physx PX_INLINE void reset() { - mIndex = mBlock = 0; + PxU32 index = 0; + PxU32 block = 0; + PxU32 wordCount = mBitMap.getWordCount(); - while (mIndex < wordCount && ((mBlock = mBitMap.mMap[mIndex]) == 0)) - ++mIndex; + while(index < wordCount && ((block = mBitMap.mMap[index]) == 0)) + ++index; + + mBlock = block; + mIndex = index; } private: PxU32 mBlock, mIndex; @@ -361,35 +364,50 @@ namespace physx PX_INLINE PxCircularIterator(const PxBitMapBase &map, PxU32 index) : mBitMap(map) { - mIndex = mBlock = mStartIndex = 0; + PxU32 localIndex = 0; + PxU32 startIndex = 0; + const PxU32 wordCount = mBitMap.getWordCount(); - if ((index << 5) < wordCount) + if((index << 5) < wordCount) { - mIndex = index << 5; - mStartIndex = mIndex; + localIndex = index << 5; + startIndex = localIndex; } - if (mIndex < wordCount) + PxU32 block = 0; + if(localIndex < wordCount) { - mBlock = mBitMap.mMap[mIndex]; - if (mBlock == 0) + block = mBitMap.mMap[localIndex]; + if(block == 0) { - mIndex = (mIndex + 1) % wordCount; - while (mIndex != mStartIndex && (mBlock = mBitMap.mMap[mIndex]) == 0) - mIndex = (mIndex + 1) % wordCount; + localIndex = (localIndex + 1) % wordCount; + while(localIndex != startIndex && (block = mBitMap.mMap[localIndex]) == 0) + localIndex = (localIndex + 1) % wordCount; } } + + mIndex = localIndex; + mBlock = block; + mStartIndex = startIndex; } PX_INLINE PxU32 getNext() { - if (mBlock) + if(mBlock) { - PxU32 bitIndex = mIndex << 5 | PxLowestSetBit(mBlock); - mBlock &= mBlock - 1; + PxU32 index = mIndex; + PxU32 block = mBlock; + const PxU32 startIndex = mStartIndex; + + PxU32 bitIndex = index << 5 | PxLowestSetBit(block); + block &= block - 1; PxU32 wordCount = mBitMap.getWordCount(); - while (!mBlock && (mIndex = ((mIndex + 1) % wordCount)) != mStartIndex) - mBlock = mBitMap.mMap[mIndex]; + while (!block && (index = ((index + 1) % wordCount)) != startIndex) + block = mBitMap.mMap[index]; + + mIndex = index; + mBlock = block; + return bitIndex; } return DONE; diff --git a/physx/include/foundation/PxFoundation.h b/physx/include/foundation/PxFoundation.h index c103b2d55..a8be3b4e9 100644 --- a/physx/include/foundation/PxFoundation.h +++ b/physx/include/foundation/PxFoundation.h @@ -153,7 +153,7 @@ PX_C_EXPORT PX_FOUNDATION_API void PX_CALL_CONV PxSetFoundationInstance(physx::P \note The behavior of this method is undefined if the foundation instance has not been created already. -@see PxCreateFoundation() +@see PxCreateFoundation(), PxIsFoundationValid() */ #if PX_CLANG #if PX_LINUX @@ -168,6 +168,14 @@ PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation& PX_CALL_CONV PxGetFoundation( #endif // PX_LINUX #endif // PX_CLANG +/** +\brief Similar to PxGetFoundation() except it handles the case if the foundation was not created already. +\return Pointer to the foundation if an instance is currently available, otherwise null. + +@see PxCreateFoundation(), PxGetFoundation() +*/ +PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation* PX_CALL_CONV PxIsFoundationValid(); + #if !PX_DOXYGEN namespace physx { @@ -197,7 +205,7 @@ PX_C_EXPORT PX_FOUNDATION_API physx::PxAllocatorCallback* PX_CALL_CONV PxGetAllo /** \brief Get the broadcasting allocator callback */ -PX_C_EXPORT PX_FOUNDATION_API physx::PxAllocatorCallback* PX_CALL_CONV PxGetBroadcastAllocator(); +PX_C_EXPORT PX_FOUNDATION_API physx::PxAllocatorCallback* PX_CALL_CONV PxGetBroadcastAllocator(bool* reportAllocationNames = NULL); /** \brief Get the error callback diff --git a/physx/include/foundation/PxHashInternals.h b/physx/include/foundation/PxHashInternals.h index 024084da2..285a03bb2 100644 --- a/physx/include/foundation/PxHashInternals.h +++ b/physx/include/foundation/PxHashInternals.h @@ -39,6 +39,7 @@ #pragma warning(push) #pragma warning(disable : 4127) // conditional expression is constant #endif + #if !PX_DOXYGEN namespace physx { @@ -375,7 +376,7 @@ class PxHashBase : private PxAllocator } // initialize new hash table - intrinsics::memSet(newHash, uint32_t(EOL), newHashSize * sizeof(uint32_t)); + intrinsics::memSet(newHash, int32_t(EOL), newHashSize * sizeof(uint32_t)); // iterate over old entries, re-hash and create new entries if(resizeCompact) @@ -789,4 +790,3 @@ class PxHashMapBase #pragma warning(pop) #endif #endif - diff --git a/physx/include/foundation/PxMat33.h b/physx/include/foundation/PxMat33.h index 0f5485827..005b3f563 100644 --- a/physx/include/foundation/PxMat33.h +++ b/physx/include/foundation/PxMat33.h @@ -416,6 +416,93 @@ PX_CUDA_CALLABLE PX_INLINE PxQuatT::PxQuatT(const PxMat33T& m) typedef PxMat33T PxMat33; typedef PxMat33T PxMat33d; + /** + \brief Sets a rotation matrix around the X axis. + \param m [out] output rotation matrix + \param angle [in] desired angle + */ + PX_INLINE void PxSetRotX(PxMat33& m, PxReal angle) + { + m = PxMat33(PxIdentity); + + PxReal sin, cos; + PxSinCos(angle, sin, cos); + + m[1][1] = m[2][2] = cos; + m[1][2] = sin; + m[2][1] = -sin; + } + + /** + \brief Sets a rotation matrix around the Y axis. + \param m [out] output rotation matrix + \param angle [in] desired angle + */ + PX_INLINE void PxSetRotY(PxMat33& m, PxReal angle) + { + m = PxMat33(PxIdentity); + + PxReal sin, cos; + PxSinCos(angle, sin, cos); + + m[0][0] = m[2][2] = cos; + m[0][2] = -sin; + m[2][0] = sin; + } + + /** + \brief Sets a rotation matrix around the Z axis. + \param m [out] output rotation matrix + \param angle [in] desired angle + */ + PX_INLINE void PxSetRotZ(PxMat33& m, PxReal angle) + { + m = PxMat33(PxIdentity); + + PxReal sin, cos; + PxSinCos(angle, sin, cos); + + m[0][0] = m[1][1] = cos; + m[0][1] = sin; + m[1][0] = -sin; + } + + /** + \brief Returns a rotation quaternion around the X axis. + \param angle [in] desired angle + \return Quaternion that rotates around the desired axis + */ + PX_INLINE PxQuat PxGetRotXQuat(float angle) + { + PxMat33 m; + PxSetRotX(m, angle); + return PxQuat(m); + } + + /** + \brief Returns a rotation quaternion around the Y axis. + \param angle [in] desired angle + \return Quaternion that rotates around the desired axis + */ + PX_INLINE PxQuat PxGetRotYQuat(float angle) + { + PxMat33 m; + PxSetRotY(m, angle); + return PxQuat(m); + } + + /** + \brief Returns a rotation quaternion around the Z axis. + \param angle [in] desired angle + \return Quaternion that rotates around the desired axis + */ + PX_INLINE PxQuat PxGetRotZQuat(float angle) + { + PxMat33 m; + PxSetRotZ(m, angle); + return PxQuat(m); + } + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/physx/include/foundation/PxMathUtils.h b/physx/include/foundation/PxMathUtils.h index bfbf3b7be..c757215ad 100644 --- a/physx/include/foundation/PxMathUtils.h +++ b/physx/include/foundation/PxMathUtils.h @@ -100,7 +100,34 @@ PX_INLINE PxPlane PxPlaneEquationFromTransform(const PxTransform& pose) \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); +PX_CUDA_CALLABLE PX_INLINE PxQuat PxSlerp(const PxReal t, const PxQuat& left, const PxQuat& right) +{ + const PxReal quatEpsilon = (PxReal(1.0e-8f)); + + PxReal cosine = left.dot(right); + PxReal sign = PxReal(1); + if (cosine < 0) + { + cosine = -cosine; + sign = PxReal(-1); + } + + PxReal sine = PxReal(1) - cosine * cosine; + + if (sine >= quatEpsilon * quatEpsilon) + { + sine = PxSqrt(sine); + const PxReal angle = PxAtan2(sine, cosine); + const PxReal i_sin_angle = PxReal(1) / sine; + + const PxReal leftw = PxSin(angle * (PxReal(1) - t)) * i_sin_angle; + const PxReal rightw = PxSin(angle * t) * i_sin_angle * sign; + + return left * leftw + right * rightw; + } + + return left; +} /** \brief integrate transform. @@ -268,7 +295,7 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxComputeAngle(const PxVec3& v0, const Px \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) +PX_CUDA_CALLABLE PX_INLINE void PxComputeBasisVectors(const PxVec3& dir, PxVec3& right, PxVec3& up) { // Derive two remaining vectors if (PxAbs(dir.y) <= 0.9999f) diff --git a/physx/include/foundation/PxPhysicsVersion.h b/physx/include/foundation/PxPhysicsVersion.h index bab58af26..406b6d59b 100644 --- a/physx/include/foundation/PxPhysicsVersion.h +++ b/physx/include/foundation/PxPhysicsVersion.h @@ -49,8 +49,8 @@ sometimes they are stored in a byte. */ #define PX_PHYSICS_VERSION_MAJOR 5 -#define PX_PHYSICS_VERSION_MINOR 1 -#define PX_PHYSICS_VERSION_BUGFIX 3 +#define PX_PHYSICS_VERSION_MINOR 2 +#define PX_PHYSICS_VERSION_BUGFIX 1 /** The constant PX_PHYSICS_VERSION is used when creating certain PhysX module objects. diff --git a/physx/include/foundation/PxPreprocessor.h b/physx/include/foundation/PxPreprocessor.h index 43cda0429..df5d4d459 100644 --- a/physx/include/foundation/PxPreprocessor.h +++ b/physx/include/foundation/PxPreprocessor.h @@ -427,9 +427,12 @@ General defines #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)) -// 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! + +#if PX_WINDOWS_FAMILY + // 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! + #endif #endif // make sure PX_CHECKED is defined in all _DEBUG configurations as well diff --git a/physx/include/foundation/PxSIMDHelpers.h b/physx/include/foundation/PxSIMDHelpers.h index 85e065679..753b035af 100644 --- a/physx/include/foundation/PxSIMDHelpers.h +++ b/physx/include/foundation/PxSIMDHelpers.h @@ -31,11 +31,13 @@ #include "foundation/PxMat33.h" #include "foundation/PxVecMath.h" +#include "foundation/PxTransform.h" #if !PX_DOXYGEN namespace physx { #endif + //! A padded version of PxMat33, to safely load its data using SIMD class PxMat33Padded : public PxMat33 { @@ -65,6 +67,66 @@ namespace physx } PxU32 padding; }; + +#if !PX_DOXYGEN +namespace aos +{ +#endif + + PX_FORCE_INLINE void transformKernelVec4( const FloatVArg wa, const Vec4VArg va, const Vec4VArg pa, + const FloatVArg wb, const Vec4VArg vb, const Vec4VArg pb, + FloatV& wo, Vec4V& vo, Vec4V& po) + { + wo = FSub(FMul(wa, wb), V4Dot3(va, vb)); + vo = V4ScaleAdd(va, wb, V4ScaleAdd(vb, wa, V4Cross(va, vb))); + + const Vec4V t1 = V4Scale(pb, FScaleAdd(wa, wa, FLoad(-0.5f))); + const Vec4V t2 = V4ScaleAdd(V4Cross(va, pb), wa, t1); + const Vec4V t3 = V4ScaleAdd(va, V4Dot3(va, pb), t2); + + po = V4ScaleAdd(t3, FLoad(2.0f), pa); + } + + // PT: out = a * b + template + PX_FORCE_INLINE void transformMultiply(PxTransform& out, const PxTransform& a, const PxTransform& b) + { + PX_ASSERT(!alignedInput || (size_t(&a)&15) == 0); + PX_ASSERT(!alignedInput || (size_t(&b)&15) == 0); + + const Vec4V aPos = alignedInput ? V4LoadA(&a.p.x) : V4LoadU(&a.p.x); + const Vec4V aRot = alignedInput ? V4LoadA(&a.q.x) : V4LoadU(&a.q.x); + + const Vec4V bPos = alignedInput ? V4LoadA(&b.p.x) : V4LoadU(&b.p.x); + const Vec4V bRot = alignedInput ? V4LoadA(&b.q.x) : V4LoadU(&b.q.x); + + Vec4V v, p; + FloatV w; + transformKernelVec4(V4GetW(aRot), aRot, aPos, V4GetW(bRot), bRot, bPos, w, v, p); + + if(alignedOutput) + { + PX_ASSERT((size_t(&out)&15) == 0); + V4StoreA(p, &out.p.x); + V4StoreA(V4SetW(v,w), &out.q.x); + } + else + { + V4StoreU(p, &out.p.x); + V4StoreU(V4SetW(v,w), &out.q.x); + } + } + + // PT: out = a * b + PX_FORCE_INLINE void transformMultiply(PxTransform32& out, const PxTransform32& a, const PxTransform32& b) + { + transformMultiply(out, a, b); + } + +#if !PX_DOXYGEN +} // namespace aos +#endif + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/physx/include/foundation/PxTransform.h b/physx/include/foundation/PxTransform.h index bf877a6d6..90296fca4 100644 --- a/physx/include/foundation/PxTransform.h +++ b/physx/include/foundation/PxTransform.h @@ -54,11 +54,11 @@ class PxTransformT { } - PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(const PxVec3T& position) : q(PxIdentity), p(position) + PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(PxIDENTITY) : q(PxIdentity), p(PxZero) { } - PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(PxIDENTITY) : q(PxIdentity), p(PxZero) + PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(const PxVec3T& position) : q(PxIdentity), p(position) { } @@ -67,8 +67,7 @@ class PxTransformT PX_ASSERT(orientation.isSane()); } - 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(Type x, Type y, Type z, PxQuatT aQ = PxQuatT(PxIdentity)) : q(aQ), p(x, y, z) { } @@ -79,13 +78,13 @@ class PxTransformT 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) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT(const PxTransformT& other) { p = other.p; q = other.q; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT(const PxTransformT& other) + PX_CUDA_CALLABLE PX_FORCE_INLINE void operator=(const PxTransformT& other) { p = other.p; q = other.q; @@ -118,6 +117,14 @@ class PxTransformT return PxTransformT(q.rotateInv(-p), q.getConjugate()); } + /** + \brief return a normalized transform (i.e. one in which the quaternion has unit magnitude) + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT getNormalized() const + { + return PxTransformT(p, q.getNormalized()); + } + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T transform(const PxVec3T& input) const { PX_ASSERT(isFinite()); @@ -151,6 +158,16 @@ class PxTransformT return PxTransformT(q.rotate(src.p) + p, q * src.q); } + //! Transform transform from parent (returns compound transform: first src, then this->inverse) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT transformInv(const PxTransformT& src) const + { + PX_ASSERT(src.isSane()); + PX_ASSERT(isFinite()); + // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr] + const PxQuatT qinv = q.getConjugate(); + return PxTransformT(qinv.rotate(src.p - p), qinv * src.q); + } + /** \brief returns true if finite and q is a unit quaternion */ @@ -175,24 +192,6 @@ class PxTransformT { return p.isFinite() && q.isFinite(); } - - //! Transform transform from parent (returns compound transform: first src, then this->inverse) - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT transformInv(const PxTransformT& src) const - { - PX_ASSERT(src.isSane()); - PX_ASSERT(isFinite()); - // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr] - 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 PxTransformT getNormalized() const - { - return PxTransformT(p, q.getNormalized()); - } }; typedef PxTransformT PxTransform; @@ -205,9 +204,48 @@ 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 +struct PX_ALIGN_PREFIX(16) PxTransformPadded : PxTransform { - PxTransform transform; + PX_FORCE_INLINE PxTransformPadded() + { + } + + PX_FORCE_INLINE PxTransformPadded(const PxTransformPadded& other) : PxTransform(other) + { + } + + PX_FORCE_INLINE explicit PxTransformPadded(const PxTransform& other) : PxTransform(other) + { + } + + PX_FORCE_INLINE explicit PxTransformPadded(PxIDENTITY) : PxTransform(PxIdentity) + { + } + + PX_FORCE_INLINE explicit PxTransformPadded(const PxVec3& position) : PxTransform(position) + { + } + + PX_FORCE_INLINE explicit PxTransformPadded(const PxQuat& orientation) : PxTransform(orientation) + { + } + + PX_FORCE_INLINE PxTransformPadded(const PxVec3& p0, const PxQuat& q0) : PxTransform(p0, q0) + { + } + + PX_FORCE_INLINE void operator=(const PxTransformPadded& other) + { + p = other.p; + q = other.q; + } + + PX_FORCE_INLINE void operator=(const PxTransform& other) + { + p = other.p; + q = other.q; + } + PxU32 padding; } PX_ALIGN_SUFFIX(16); diff --git a/physx/include/foundation/PxVecQuat.h b/physx/include/foundation/PxVecQuat.h index 017048292..074026478 100644 --- a/physx/include/foundation/PxVecQuat.h +++ b/physx/include/foundation/PxVecQuat.h @@ -225,7 +225,6 @@ PX_FORCE_INLINE Vec3V QuatTransform(const QuatV q, const Vec3V p, const Vec3V v) 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; @@ -244,18 +243,18 @@ PX_FORCE_INLINE Vec3V QuatRotateInv(const QuatV q, const Vec3V v) 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 Vec4V imagA = a; + const Vec4V imagB = 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); + const FloatV real = FSub(FMul(rA, rB), V4Dot3(imagA, imagB)); + const Vec4V v0 = V4Scale(imagA, rB); + const Vec4V v1 = V4Scale(imagB, rA); + const Vec4V v2 = V4Cross(imagA, imagB); + const Vec4V imag = V4Add(V4Add(v0, v1), v2); - return V4SetW(Vec4V_From_Vec3V(imag), real); + return V4SetW(imag, real); } PX_FORCE_INLINE QuatV QuatAdd(const QuatV a, const QuatV b) diff --git a/physx/include/foundation/PxVecTransform.h b/physx/include/foundation/PxVecTransform.h index 433c2fcaa..6092ab509 100644 --- a/physx/include/foundation/PxVecTransform.h +++ b/physx/include/foundation/PxVecTransform.h @@ -78,7 +78,7 @@ class PxTransformV q = QuatIdentity(); } - PX_FORCE_INLINE void Invalidate() + PX_FORCE_INLINE void invalidate() { p = V3Splat(FMax()); q = QuatIdentity(); diff --git a/physx/include/foundation/unix/PxUnixIntrinsics.h b/physx/include/foundation/unix/PxUnixIntrinsics.h index 4d3808989..5f76373ad 100644 --- a/physx/include/foundation/unix/PxUnixIntrinsics.h +++ b/physx/include/foundation/unix/PxUnixIntrinsics.h @@ -82,7 +82,11 @@ Prefetch aligned 64B x86, 32b ARM around \c ptr+offset. */ PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0) { +#ifdef __CUDACC__ + __builtin_prefetch(reinterpret_cast(ptr) + offset, 0, 3); +#else __builtin_prefetch(reinterpret_cast(ptr) + offset, 0, 3); +#endif } /*! diff --git a/physx/include/foundation/unix/sse2/PxUnixSse2AoS.h b/physx/include/foundation/unix/sse2/PxUnixSse2AoS.h index d7761a150..995fc5d54 100644 --- a/physx/include/foundation/unix/sse2/PxUnixSse2AoS.h +++ b/physx/include/foundation/unix/sse2/PxUnixSse2AoS.h @@ -70,7 +70,7 @@ typedef union UnionM128 return m128; } - operator const __m128() const + operator __m128() const { return m128; } diff --git a/physx/include/foundation/unix/sse2/PxUnixSse2InlineAoS.h b/physx/include/foundation/unix/sse2/PxUnixSse2InlineAoS.h index ac776942a..1b92fe380 100644 --- a/physx/include/foundation/unix/sse2/PxUnixSse2InlineAoS.h +++ b/physx/include/foundation/unix/sse2/PxUnixSse2InlineAoS.h @@ -924,7 +924,7 @@ PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV min, const FloatV m { ASSERT_ISVALIDFLOATV(a); ASSERT_ISVALIDFLOATV(min); - ASSERT_ISVALIDFLOATV(max) + ASSERT_ISVALIDFLOATV(max); const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); return BAllEqTTTT(c); } @@ -997,7 +997,7 @@ PX_FORCE_INLINE FloatV V3GetX(const Vec3V f) PX_FORCE_INLINE FloatV V3GetY(const Vec3V f) { - ASSERT_ISVALIDVEC3V(f) + ASSERT_ISVALIDVEC3V(f); return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); } @@ -1041,7 +1041,7 @@ PX_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) { ASSERT_ISVALIDVEC3V(a); ASSERT_ISVALIDVEC3V(b); - ASSERT_ISVALIDVEC3V(c) + ASSERT_ISVALIDVEC3V(c); Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); return V3SetY(r, V3GetY(b)); } @@ -1635,7 +1635,7 @@ PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V bounds) { ASSERT_ISVALIDVEC3V(a); - ASSERT_ISVALIDVEC3V(bounds) + ASSERT_ISVALIDVEC3V(bounds); return V3InBounds(a, V3Neg(bounds), bounds); } diff --git a/physx/include/foundation/windows/PxWindowsInclude.h b/physx/include/foundation/windows/PxWindowsInclude.h index 992a5a6ef..1c7f42323 100644 --- a/physx/include/foundation/windows/PxWindowsInclude.h +++ b/physx/include/foundation/windows/PxWindowsInclude.h @@ -37,9 +37,9 @@ #error "Only include windows.h through this file!!" #endif -// We only support >= Windows XP, and we need this for critical section and +// We only support >= Windows 7, 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 +#define _WIN32_WINNT 0x0601 // turn off as much as we can for windows. All we really need is the thread functions(critical sections/Interlocked* // etc) diff --git a/physx/include/geometry/PxBVH.h b/physx/include/geometry/PxBVH.h index 70d40e5c5..a179f024d 100644 --- a/physx/include/geometry/PxBVH.h +++ b/physx/include/geometry/PxBVH.h @@ -63,43 +63,6 @@ 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() {} @@ -314,13 +277,6 @@ class PxBVH : public PxBase */ 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 diff --git a/physx/include/geometry/PxGeometryQuery.h b/physx/include/geometry/PxGeometryQuery.h index 1cb4a615b..882bda718 100644 --- a/physx/include/geometry/PxGeometryQuery.h +++ b/physx/include/geometry/PxGeometryQuery.h @@ -85,22 +85,9 @@ class PxGeometryQuery 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, + PxU32 maxHits, PxGeomRaycastHit* PX_RESTRICT rayHits, PxU32 stride = sizeof(PxGeomRaycastHit), 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. @@ -230,19 +217,6 @@ class PxGeometryQuery */ 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. - \return The bounds of the object - - @see PxGeometry PxTransform - @deprecated - */ - 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 diff --git a/physx/include/geometry/PxHeightFieldSample.h b/physx/include/geometry/PxHeightFieldSample.h index 82df7fdf1..8ab7d5dfe 100644 --- a/physx/include/geometry/PxHeightFieldSample.h +++ b/physx/include/geometry/PxHeightFieldSample.h @@ -65,13 +65,6 @@ triangles are specified. */ struct PxHeightFieldSample { -//= 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. -//================================================================================================== - /** \brief The height of the heightfield sample diff --git a/physx/include/geometry/PxMeshScale.h b/physx/include/geometry/PxMeshScale.h index 813435664..14dd3c8db 100644 --- a/physx/include/geometry/PxMeshScale.h +++ b/physx/include/geometry/PxMeshScale.h @@ -67,12 +67,6 @@ the coordinates of vertex v from the mesh-local frame to the scaling-axes frame. */ class PxMeshScale { -//= 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. -//================================================================================================== public: /** \brief Constructor initializes to identity scale. diff --git a/physx/include/geometry/PxTetrahedronMesh.h b/physx/include/geometry/PxTetrahedronMesh.h index 147a64390..6ed36452b 100644 --- a/physx/include/geometry/PxTetrahedronMesh.h +++ b/physx/include/geometry/PxTetrahedronMesh.h @@ -76,6 +76,13 @@ namespace physx */ virtual void release() = 0; + /** + \brief Get the inverse mass of each vertex of the tetrahedron mesh. + + \return PxReal* A pointer to an array of inverse mass for each vertex of the tetrahedron mesh. Size: number of vertices * sizeof(PxReal). + */ + virtual PxReal* getGridModelInvMass() = 0; + protected: PX_INLINE PxSoftBodyAuxData(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} PX_INLINE PxSoftBodyAuxData(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} diff --git a/physx/include/gpu/PxGpu.h b/physx/include/gpu/PxGpu.h index 4b0f34b38..1a37894e5 100644 --- a/physx/include/gpu/PxGpu.h +++ b/physx/include/gpu/PxGpu.h @@ -129,6 +129,14 @@ PX_C_EXPORT PX_PHYSX_CORE_API physx::PxKernelIndex* PX_CALL_CONV PxGetCudaFuncti PX_C_EXPORT PX_PHYSX_CORE_API physx::PxU32 PX_CALL_CONV PxGetCudaFunctionTableSize(); +namespace physx +{ + class PxPhysicsGpu; +} + +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxPhysicsGpu* PX_CALL_CONV PxGetPhysicsGpu(); + + #endif // PX_SUPPORT_GPU_PHYSX #endif diff --git a/physx/include/gpu/PxPhysicsGpu.h b/physx/include/gpu/PxPhysicsGpu.h new file mode 100644 index 000000000..fd25f4770 --- /dev/null +++ b/physx/include/gpu/PxPhysicsGpu.h @@ -0,0 +1,174 @@ +// 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_GPU_H +#define PX_PHYSICS_GPU_H +/** \addtogroup extensions + @{ +*/ + + +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" +#include "PxParticleSystem.h" + +#include "foundation/PxArray.h" +#include "PxParticleGpu.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_SUPPORT_GPU_PHYSX + + class PxSceneDesc; + + class PxIsosurfaceExtractor; + class PxSparseGridIsosurfaceExtractor; + class PxAnisotropyGenerator; + class PxSmoothedPositionGenerator; + class PxParticleNeighborhoodProvider; + + class PxArrayConverter; + class PxLineStripSkinning; + class PxSoftBodyEmbedding; + + struct PxIsosurfaceParams; + struct PxSparseGridParams; + + class PxPhysicsGpu + { + public: + /** + \brief Creates an isosurface extractor operating on a dense grid + + \param[in] cudaContextManager A cuda context manager + \param[in] worldBounds The bounds of the internally used dense grid. The isosurface can only be generated inside those bounds. + \param[in] cellSize The size of a single grid cell + \param[in] isosurfaceParams The isosurface parameters to control the isolevel etc. + \param[in] maxNumParticles The maximal number of particles that can be processed + \param[in] maxNumVertices The maximal number of vertices the output buffer can hold + \param[in] maxNumTriangles The maximal number of triangles the output buffer can hold + */ + virtual PxIsosurfaceExtractor* createDenseGridIsosurfaceExtractor(PxCudaContextManager* cudaContextManager, const PxBounds3& worldBounds, + PxReal cellSize, const PxIsosurfaceParams& isosurfaceParams, PxU32 maxNumParticles, PxU32 maxNumVertices = 512 * 1024, PxU32 maxNumTriangles = 1024 * 1024) = 0; + + /** + \brief Creates an isosurface extractor operating on a sparse grid + + \param[in] cudaContextManager A cuda context manager + \param[in] sparseGridParams The sparse grid parameters defining the cell size etc. + \param[in] isosurfaceParams The isosurface parameters to control the isolevel etc. + \param[in] maxNumParticles The maximal number of particles that can be processed + \param[in] maxNumVertices The maximal number of vertices the output buffer can hold + \param[in] maxNumTriangles The maximal number of triangles the output buffer can hold + */ + virtual PxSparseGridIsosurfaceExtractor* createSparseGridIsosurfaceExtractor(PxCudaContextManager* cudaContextManager, const PxSparseGridParams& sparseGridParams, + const PxIsosurfaceParams& isosurfaceParams, PxU32 maxNumParticles, PxU32 maxNumVertices = 512 * 1024, PxU32 maxNumTriangles = 1024 * 1024) = 0; + + + /** + \brief Creates an anisotropy generator + + \param[in] cudaContextManager A cuda context manager + \param[in] maxNumParticles The number of particles + \param[in] anisotropyScale A uniform scaling factor to increase or decrease anisotropy + \param[in] minAnisotropy The minimum scaling factor in any dimension that anisotropy can have + \param[in] maxAnisotropy The maximum scaling factor in any dimension that anisotropy can have + */ + virtual PxAnisotropyGenerator* createAnisotropyGenerator(PxCudaContextManager* cudaContextManager, PxU32 maxNumParticles, + PxReal anisotropyScale = 1.0f, PxReal minAnisotropy = 0.1f, PxReal maxAnisotropy = 2.0f) = 0; + + /** + \brief Creates a smoothed position generator + + \param[in] cudaContextManager A cuda context manager + \param[in] maxNumParticles The number of particles + \param[in] smoothingStrength Controls the strength of the smoothing effect + */ + virtual PxSmoothedPositionGenerator* createSmoothedPositionGenerator(PxCudaContextManager* cudaContextManager, PxU32 maxNumParticles, PxReal smoothingStrength = 0.5f) = 0; + + + /** + \brief Creates a neighborhood provider + + \param[in] cudaContextManager A cuda context manager + \param[in] maxNumParticles The number of particles + \param[in] cellSize The grid cell size. Should be equal to 2*contactOffset for PBD particle systems. + \param[in] maxNumSparseGridCells The maximal number of cells the internally used sparse grid can provide + */ + virtual PxParticleNeighborhoodProvider* createParticleNeighborhoodProvider(PxCudaContextManager* cudaContextManager, const PxU32 maxNumParticles, + const PxReal cellSize, const PxU32 maxNumSparseGridCells = 262144) = 0; + + /** + \brief Creates an array converter. If not used anymore, the caller needs to delete the returned pointer. + + \param[in] cudaContextManager A cuda context manager + */ + virtual PxArrayConverter* createArrayConverter(PxCudaContextManager* cudaContextManager) = 0; + + /** + \brief Creates an line strip embedding helper. If not used anymore, the caller needs to delete the returned pointer. + + \param[in] cudaContextManager A cuda context manager + + \return Pointer to a new instance of a PxLineStripSkinning + */ + virtual PxLineStripSkinning* createLineStripSkinning(PxCudaContextManager* cudaContextManager) = 0; + + /** + \brief Estimates the amount of GPU memory needed to create a scene for the given descriptor. + + \param[in] sceneDesc a valid scene desriptor + + \note While this is a conservative estimate, scene allocation may still fail even though there is + enough memory - this function does not contain the potential overhead coming from the CUDA allocator. + Additionally, there may be fragmentation issues. Generally, this is not an issue for + scene allocation sizes < 500Mb, but may become problematic for larger scenes. + + \return A conservative estimate for the amount of GPU memory needed to create a scene for the given descriptor. + */ + virtual PxU64 estimateSceneCreationGpuMemoryRequirements(const PxSceneDesc& sceneDesc) = 0; + + virtual void release() = 0; + + virtual ~PxPhysicsGpu() {} + }; + +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/physx/include/solver/PxSolverDefs.h b/physx/include/solver/PxSolverDefs.h index 1e67f88ab..105f584df 100644 --- a/physx/include/solver/PxSolverDefs.h +++ b/physx/include/solver/PxSolverDefs.h @@ -295,7 +295,7 @@ struct PxArticulationFlag 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. + eCOMPUTE_JOINT_FORCES = (1<<3) //!< @deprecated Enable in order to be able to query joint solver (i.e. constraint) forces using PxArticulationCache::jointSolverForces. }; }; diff --git a/physx/include/task/PxTaskManager.h b/physx/include/task/PxTaskManager.h index 33af75478..4f18089b8 100644 --- a/physx/include/task/PxTaskManager.h +++ b/physx/include/task/PxTaskManager.h @@ -57,10 +57,7 @@ struct PxTaskType { 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 + eCOMPLETED //!< PxTask execution has been completed }; }; diff --git a/physx/include/vehicle/PxVehicleDrive.h b/physx/include/vehicle/PxVehicleDrive.h index 57be28f50..02ab0abee 100644 --- a/physx/include/vehicle/PxVehicleDrive.h +++ b/physx/include/vehicle/PxVehicleDrive.h @@ -51,12 +51,6 @@ class PxRigidDynamic; */ class PX_DEPRECATED PxVehicleDriveSimData { -//= 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. -//================================================================================================== public: friend class PxVehicleDriveTank; @@ -491,12 +485,6 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveDynData) & 15)); */ class PX_DEPRECATED PxVehicleDrive : public PxVehicleWheels { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/include/vehicle/PxVehicleDrive4W.h b/physx/include/vehicle/PxVehicleDrive4W.h index e2212df48..ba8295a34 100644 --- a/physx/include/vehicle/PxVehicleDrive4W.h +++ b/physx/include/vehicle/PxVehicleDrive4W.h @@ -54,12 +54,6 @@ The drive model incorporates engine, clutch, gears, autobox, differential, and A */ class PX_DEPRECATED PxVehicleDriveSimData4W : public PxVehicleDriveSimData { -//= 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. -//================================================================================================== public: friend class PxVehicleDrive4W; @@ -171,12 +165,6 @@ struct PX_DEPRECATED PxVehicleDrive4WControl */ class PX_DEPRECATED PxVehicleDrive4W : public PxVehicleDrive { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/include/vehicle/PxVehicleDriveNW.h b/physx/include/vehicle/PxVehicleDriveNW.h index 23c984bee..478167414 100644 --- a/physx/include/vehicle/PxVehicleDriveNW.h +++ b/physx/include/vehicle/PxVehicleDriveNW.h @@ -53,12 +53,6 @@ engine, clutch, gears, autobox, differential. */ class PX_DEPRECATED PxVehicleDriveSimDataNW : public PxVehicleDriveSimData { -//= 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. -//================================================================================================== public: friend class PxVehicleDriveNW; @@ -129,12 +123,6 @@ struct PX_DEPRECATED PxVehicleDriveNWControl */ class PX_DEPRECATED PxVehicleDriveNW : public PxVehicleDrive { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/include/vehicle/PxVehicleDriveTank.h b/physx/include/vehicle/PxVehicleDriveTank.h index 420161217..f0e625951 100644 --- a/physx/include/vehicle/PxVehicleDriveTank.h +++ b/physx/include/vehicle/PxVehicleDriveTank.h @@ -145,12 +145,6 @@ struct PX_DEPRECATED PxVehicleDriveTankControlModel */ class PX_DEPRECATED PxVehicleDriveTank : public PxVehicleDrive { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/include/vehicle/PxVehicleNoDrive.h b/physx/include/vehicle/PxVehicleNoDrive.h index f8d8cc74d..7c03bad30 100644 --- a/physx/include/vehicle/PxVehicleNoDrive.h +++ b/physx/include/vehicle/PxVehicleNoDrive.h @@ -51,12 +51,6 @@ class PxRigidDynamic; */ class PX_DEPRECATED PxVehicleNoDrive : public PxVehicleWheels { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/include/vehicle/PxVehicleWheels.h b/physx/include/vehicle/PxVehicleWheels.h index 4a000d82c..8abafdcda 100644 --- a/physx/include/vehicle/PxVehicleWheels.h +++ b/physx/include/vehicle/PxVehicleWheels.h @@ -127,12 +127,6 @@ PX_FLAGS_OPERATORS(PxVehicleWheelsSimFlag::Enum, PxU32) class PX_DEPRECATED PxVehicleWheelsSimData { -//= 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. -//================================================================================================== public: friend class PxVehicleWheels; @@ -639,12 +633,6 @@ struct PX_DEPRECATED PxTireContactIntersectionMethod */ class PX_DEPRECATED PxVehicleWheelsDynData { -//= 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. -//================================================================================================== public: friend class PxVehicleWheels; @@ -825,12 +813,6 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsDynData) & 15)); */ class PX_DEPRECATED PxVehicleWheels : public PxBase { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/include/vehicle2/physxActor/PxVehiclePhysXActorComponents.h b/physx/include/vehicle2/physxActor/PxVehiclePhysXActorComponents.h index f97c8f5b7..f0b9d1576 100644 --- a/physx/include/vehicle2/physxActor/PxVehiclePhysXActorComponents.h +++ b/physx/include/vehicle2/physxActor/PxVehiclePhysXActorComponents.h @@ -172,6 +172,9 @@ class PxVehiclePhysXActorEndComponent : public PxVehicleComponent \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] throttle The throttle command state (see #PxVehicleCommandState). + Can be set to NULL if the vehicle is not controlled through + PxVehicleCommandState. \param[out] physxActor is the PxRigidBody instance associated with the vehicle. */ virtual void getDataForPhysXActorEndComponent( @@ -182,6 +185,7 @@ class PxVehiclePhysXActorEndComponent : public PxVehicleComponent PxVehicleArrayData& wheelRigidBody1dStates, PxVehicleArrayData& wheelLocalPoses, const PxVehicleGearboxState*& gearState, + const PxReal*& throttle, PxVehiclePhysXActor*& physxActor) = 0; virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) @@ -197,10 +201,11 @@ class PxVehiclePhysXActorEndComponent : public PxVehicleComponent PxVehicleArrayData wheelRigidBody1dStates; PxVehicleArrayData wheelLocalPoses; const PxVehicleGearboxState* gearState; + const PxReal* throttle; PxVehiclePhysXActor* physxActor; getDataForPhysXActorEndComponent(axleDescription, rigidBodyState, - wheelParams, wheelShapeLocalPoses, wheelRigidBody1dStates, wheelLocalPoses, gearState, + wheelParams, wheelShapeLocalPoses, wheelRigidBody1dStates, wheelLocalPoses, gearState, throttle, physxActor); for (PxU32 i = 0; i < axleDescription->nbWheels; i++) @@ -218,7 +223,7 @@ class PxVehiclePhysXActorEndComponent : public PxVehicleComponent PxVehicleWriteRigidBodyStateToPhysXActor(physxContext.physxActorUpdateMode, *rigidBodyState, dt, *physxActor->rigidBody); PxVehiclePhysxActorKeepAwakeCheck(*axleDescription, wheelParams, wheelRigidBody1dStates, - physxContext.physxActorWakeCounterThreshold, physxContext.physxActorWakeCounterResetValue, gearState, + physxContext.physxActorWakeCounterThreshold, physxContext.physxActorWakeCounterResetValue, gearState, throttle, *physxActor->rigidBody); } else diff --git a/physx/include/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h b/physx/include/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h index cd7072ef6..b637ac448 100644 --- a/physx/include/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h +++ b/physx/include/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h @@ -122,9 +122,9 @@ bool PxVehiclePhysxActorSleepCheck 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. +threshold or if a gear change is pending or if throttle is applied. +This method will reset the wake counter of the physx actor to a specified value, +if any of the mentioned criteria are met. \note The physx actor's sleep threshold will be used as threshold to test against for the energy criteria. @@ -139,6 +139,9 @@ criterias are met. 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] throttle The throttle command state (see #PxVehicleCommandState). + Can be set to NULL if the vehicle is not controlled through + PxVehicleCommandState or if the mentioned behavior is not desired. \param[in] physxActor is the PxRigidBody instance associated with the vehicle. */ void PxVehiclePhysxActorKeepAwakeCheck @@ -148,6 +151,7 @@ void PxVehiclePhysxActorKeepAwakeCheck const PxReal wakeCounterThreshold, const PxReal wakeCounterResetValue, const PxVehicleGearboxState* gearState, + const PxReal* throttle, PxRigidBody& physxActor); diff --git a/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h b/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h index b422aea85..0552bfcb7 100644 --- a/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h +++ b/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h @@ -112,9 +112,12 @@ class PxVehiclePhysXRoadGeometrySceneQueryComponent : public PxVehicleComponent { const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + const PxQueryFilterData* fdPtr = roadGeomParams->filterDataEntries ? (roadGeomParams->filterDataEntries + wheelId) : &roadGeomParams->defaultFilterData; + PxVehiclePhysXRoadGeometryQueryUpdate( wheelParams[wheelId], suspensionParams[wheelId], - *roadGeomParams, materialFrictionParams[wheelId], + roadGeomParams->roadGeometryQueryType, roadGeomParams->filterCallback, *fdPtr, + materialFrictionParams[wheelId], steerResponseStates[wheelId], *rigidBodyState, *physxContext.physxScene, physxContext.physxUnitCylinderSweepMesh, context.frame, roadGeometryStates[wheelId], diff --git a/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h b/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h index 20ddaf685..39785a29d 100644 --- a/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h +++ b/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h @@ -34,6 +34,8 @@ #include "foundation/PxSimpleTypes.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h" + #if !PX_DOXYGEN namespace physx { @@ -46,9 +48,7 @@ namespace vehicle2 struct PxVehicleWheelParams; struct PxVehicleSuspensionParams; -struct PxVehiclePhysXRoadGeometryQueryParams; struct PxVehiclePhysXRoadGeometryQueryState; -struct PxVehiclePhysXMaterialFrictionParams; struct PxVehicleRigidBodyState; struct PxVehicleFrame; struct PxVehicleRoadGeometryState; @@ -57,7 +57,10 @@ 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] queryType describes what type of PhysX scene query to use (see #PxVehiclePhysXRoadGeometryQueryType). + If PxVehiclePhysXRoadGeometryQueryType::eNONE is used, no work will be done. +\param[in] filterCallback describes the filter callback to use for the PhysX scene query. NULL is a valid input. +\param[in] filterData describes the filter data to use for 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. @@ -75,7 +78,9 @@ 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 PxVehiclePhysXRoadGeometryQueryType::Enum queryType, + PxQueryFilterCallback* filterCallback, const PxQueryFilterData& filterData, + const PxVehiclePhysXMaterialFrictionParams& materialFrictionParams, const PxReal wheelYawAngle, const PxVehicleRigidBodyState& rigidBodyState, const PxScene& scene, const PxConvexMesh* unitCylinderSweepMesh, const PxVehicleFrame& frame, diff --git a/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h b/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h index 896204c5d..4830e5396 100644 --- a/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h +++ b/physx/include/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h @@ -69,18 +69,25 @@ struct PxVehiclePhysXRoadGeometryQueryType struct PxVehiclePhysXRoadGeometryQueryParams { /** - \brief A description of the type of physx scene query to employ. + \brief The default filter data to use for the physx scene query. + + If per wheel filter data is provided in #filterDataEntries, then this member + will be ignored. + @see PxSceneQuerySystemBase::raycast @see PxSceneQuerySystemBase::sweep */ - PxVehiclePhysXRoadGeometryQueryType::Enum roadGeometryQueryType; + PxQueryFilterData defaultFilterData; /** - \brief The filter data to use for the physx scene query. + \brief Array of filter data entries (one per wheel) to use for the physx scene query. + + A null pointer is allowed in which case #defaultFilterData will be used for all wheels. + @see PxSceneQuerySystemBase::raycast @see PxSceneQuerySystemBase::sweep */ - PxQueryFilterData filterData; + PxQueryFilterData* filterDataEntries; /** \brief A filter callback to be used by the physx scene query @@ -90,6 +97,13 @@ struct PxVehiclePhysXRoadGeometryQueryParams */ PxQueryFilterCallback* filterCallback; + /** + \brief A description of the type of physx scene query to employ. + @see PxSceneQuerySystemBase::raycast + @see PxSceneQuerySystemBase::sweep + */ + PxVehiclePhysXRoadGeometryQueryType::Enum roadGeometryQueryType; + PX_FORCE_INLINE PxVehiclePhysXRoadGeometryQueryParams transformAndScale( const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const { diff --git a/physx/include/vehicle2/pvd/PxVehiclePvdComponents.h b/physx/include/vehicle2/pvd/PxVehiclePvdComponents.h index 676ff738f..5990b274c 100644 --- a/physx/include/vehicle2/pvd/PxVehiclePvdComponents.h +++ b/physx/include/vehicle2/pvd/PxVehiclePvdComponents.h @@ -115,7 +115,9 @@ class PxVehiclePVDComponent : public PxVehicleComponent PX_UNUSED(dt); PX_UNUSED(context); - if(!context.pvdContext.attributeHandles || !context.pvdContext.writer) + OmniPvdWriter* pvdWriter = context.pvdContext.writer; + + if(!context.pvdContext.attributeHandles || !pvdWriter) return true; const PxVehicleAxleDescription* axleDesc = NULL; @@ -206,16 +208,16 @@ class PxVehiclePVDComponent : public PxVehicleComponent { PxVehiclePvdRigidBodyRegister( rbodyParams, rbodyState, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdSuspensionStateCalculationParamsRegister( suspStateCalcParams, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdCommandResponseRegister( brakeResponseParams, steerResponseParams, brakeResponseStates, steerResponseStates, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdWheelAttachmentsRegister( *axleDesc, @@ -226,48 +228,53 @@ class PxVehiclePVDComponent : public PxVehicleComponent tireForceParams, tireDirectionStates, tireSpeedStates, tireSlipStates, tireStickyStates, tireGripStates, tireCamberStates, tireForces, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdAntiRollsRegister( antiRollParams, antiRollTorque, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); - - PxVehiclePvdDirectDrivetrainRegister( - commandState, directDriveTransmissionState, - directDriveThrottleResponseParams, - directDrivethrottleResponseState, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); - PxVehiclePvdEngineDrivetrainRegister( - commandState, engineDriveTransmissionCommandState, - clutchResponseParams, clutchParams, engineParams, gearboxParams, autoboxParams, multiWheelDiffParams, fourWheelDiffParams, - clutchResponseState, throttleResponseState, engineState, gearboxState, autoboxState, diffState, clutchSlipState, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + if (engineParams) + { + PxVehiclePvdEngineDrivetrainRegister( + commandState, engineDriveTransmissionCommandState, + clutchResponseParams, clutchParams, engineParams, gearboxParams, autoboxParams, multiWheelDiffParams, fourWheelDiffParams, + clutchResponseState, throttleResponseState, engineState, gearboxState, autoboxState, diffState, clutchSlipState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); + } + else + { + PxVehiclePvdDirectDrivetrainRegister( + commandState, directDriveTransmissionState, + directDriveThrottleResponseParams, + directDrivethrottleResponseState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); + } PxVehiclePvdPhysXWheelAttachmentRegister( *axleDesc, physxConstraintParams, physxMaterialFrictionParams, physxActor, physxRoadGeomQryParams, physxRoadGeomStates, physxConstraintStates, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdPhysXRigidActorRegister( physxActor, - *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); firstTime = false; } PxVehiclePvdRigidBodyWrite( rbodyParams, rbodyState, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdSuspensionStateCalculationParamsWrite( suspStateCalcParams, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdCommandResponseWrite( *axleDesc, brakeResponseParams, steerResponseParams, brakeResponseStates, steerResponseStates, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdWheelAttachmentsWrite( *axleDesc, @@ -278,34 +285,39 @@ class PxVehiclePVDComponent : public PxVehicleComponent tireForceParams, tireDirectionStates, tireSpeedStates, tireSlipStates, tireStickyStates, tireGripStates, tireCamberStates, tireForces, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdAntiRollsWrite( antiRollParams, antiRollTorque, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); - 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); + if (engineParams) + { + PxVehiclePvdEngineDrivetrainWrite( + commandState, engineDriveTransmissionCommandState, + clutchResponseParams, clutchParams, engineParams, gearboxParams, autoboxParams, multiWheelDiffParams, fourWheelDiffParams, + clutchResponseState, throttleResponseState, engineState, gearboxState, autoboxState, diffState, clutchSlipState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); + } + else + { + PxVehiclePvdDirectDrivetrainWrite( + *axleDesc, + commandState, directDriveTransmissionState, + directDriveThrottleResponseParams, + directDrivethrottleResponseState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); + } PxVehiclePvdPhysXWheelAttachmentWrite( *axleDesc, physxConstraintParams, physxMaterialFrictionParams, physxActor, physxRoadGeomQryParams, physxRoadGeomStates, physxConstraintStates, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); PxVehiclePvdPhysXRigidActorWrite( physxActor, - *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, *pvdWriter); return true; } diff --git a/physx/include/vehicle2/pvd/PxVehiclePvdFunctions.h b/physx/include/vehicle2/pvd/PxVehiclePvdFunctions.h index 9bff4dbb3..4df0391af 100644 --- a/physx/include/vehicle2/pvd/PxVehiclePvdFunctions.h +++ b/physx/include/vehicle2/pvd/PxVehiclePvdFunctions.h @@ -79,8 +79,6 @@ Handles to the created object instances will be stored in a PxVehiclePvdObjectHa \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 @@ -89,7 +87,7 @@ Handles to the created object instances will be stored in a PxVehiclePvdObjectHa void PxVehiclePvdRigidBodyRegister (const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write the parameters and state of the rigid body of a vehicle instance to omnipvd. @@ -100,7 +98,7 @@ void PxVehiclePvdRigidBodyRegister \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(). +\note omniWriter must be the same instance used in PxVehiclePvdRigidBodyRegister(). @see PxVehiclePvdAttributesCreate @see PxVehiclePvdObjectCreate @see PxVehiclePvdRigidBodyRegister @@ -108,7 +106,7 @@ void PxVehiclePvdRigidBodyRegister void PxVehiclePvdRigidBodyWrite (const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + 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. @@ -117,8 +115,6 @@ void PxVehiclePvdRigidBodyWrite \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 @@ -126,7 +122,7 @@ void PxVehiclePvdRigidBodyWrite void PxVehiclePvdSuspensionStateCalculationParamsRegister (const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write the parameters and state of the rigid body of a vehicle instance to omnipvd. @@ -136,7 +132,7 @@ void PxVehiclePvdSuspensionStateCalculationParamsRegister \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(). +\note omniWriter must be the same instance used in PxVehiclePvdSuspensionStateCalculationParamsRegister(). @see PxVehiclePvdAttributesCreate @see PxVehiclePvdObjectCreate @see PxVehiclePvdSuspensionStateCalculationParamsRegister @@ -144,7 +140,7 @@ the suspension state calculation parameters will not be updated in omnipvd. void PxVehiclePvdSuspensionStateCalculationParamsWrite (const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + 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. @@ -159,8 +155,6 @@ void PxVehiclePvdSuspensionStateCalculationParamsWrite \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 @@ -171,7 +165,7 @@ void PxVehiclePvdCommandResponseRegister const PxVehicleArrayData& brakeResponseStates, const PxVehicleArrayData& steerResponseStates, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write brake and steer command response parameters to omnipvd. @@ -191,7 +185,7 @@ the steer command parameters will not be updated in omnipvd. 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(). +\note omniWriter must be the same instance used in PxVehiclePvdCommandResponseRegister(). @see PxVehiclePvdAttributesCreate @see PxVehiclePvdObjectCreate @see PxVehiclePvdCommandResponseRegister @@ -203,7 +197,7 @@ void PxVehiclePvdCommandResponseWrite const PxVehicleArrayData& brakeResponseStates, const PxVehicleArrayData& steerResponseStates, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + 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. @@ -232,8 +226,6 @@ void PxVehiclePvdCommandResponseWrite \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 @@ -260,7 +252,7 @@ void PxVehiclePvdWheelAttachmentsRegister const PxVehicleArrayData& tireCamberStates, const PxVehicleArrayData& tireForces, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write wheel attachment data such as tire, suspension and wheel data to omnipvd. @@ -289,7 +281,6 @@ void PxVehiclePvdWheelAttachmentsRegister \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 @@ -316,7 +307,7 @@ void PxVehiclePvdWheelAttachmentsWrite const PxVehicleArrayData& tireCamberStates, const PxVehicleArrayData& tireForces, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Register object instances in omnipvd that will be used to reflect the antiroll bars of a vehicle instance. @@ -327,8 +318,6 @@ void PxVehiclePvdWheelAttachmentsWrite \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 @@ -336,7 +325,7 @@ void PxVehiclePvdWheelAttachmentsWrite void PxVehiclePvdAntiRollsRegister (const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write antiroll data to omnipvd. @@ -347,7 +336,6 @@ void PxVehiclePvdAntiRollsRegister \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 @@ -355,7 +343,7 @@ void PxVehiclePvdAntiRollsRegister void PxVehiclePvdAntiRollsWrite (const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Register object instances in omnipvd that will be used to reflect the direct drivetrain of a vehicle instance. @@ -370,8 +358,6 @@ void PxVehiclePvdAntiRollsWrite \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 @@ -381,7 +367,7 @@ void PxVehiclePvdDirectDrivetrainRegister const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, const PxVehicleArrayData& directDriveThrottleResponseState, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write direct drivetrain data to omnipvd. @@ -397,7 +383,6 @@ void PxVehiclePvdDirectDrivetrainRegister \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 @@ -408,7 +393,7 @@ void PxVehiclePvdDirectDrivetrainWrite const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, const PxVehicleArrayData& directDriveThrottleResponseState, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Register object instances in omnipvd that will be used to reflect the engine drivetrain of a vehicle instance. @@ -432,8 +417,6 @@ void PxVehiclePvdDirectDrivetrainWrite \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 @@ -455,7 +438,7 @@ void PxVehiclePvdEngineDrivetrainRegister const PxVehicleDifferentialState* diffState, const PxVehicleClutchSlipState* clutchSlipState, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write engine drivetrain data of a vehicle instance to omnipvd. @@ -479,7 +462,6 @@ void PxVehiclePvdEngineDrivetrainRegister \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 @@ -501,7 +483,7 @@ void PxVehiclePvdEngineDrivetrainWrite const PxVehicleDifferentialState* diffState, const PxVehicleClutchSlipState* clutchSlipState, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Register per wheel attachment data that involves the vehicle's integration with a PhysX scene. @@ -519,8 +501,6 @@ void PxVehiclePvdEngineDrivetrainWrite \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 @@ -533,7 +513,7 @@ void PxVehiclePvdPhysXWheelAttachmentRegister const PxVehicleArrayData& physxRoadGeomState, const PxVehicleArrayData& physxConstraintStates, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write to omnipvd the per wheel attachment data that involves the vehicle's integration with a PhysX scene. @@ -551,7 +531,6 @@ void PxVehiclePvdPhysXWheelAttachmentRegister \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 @@ -564,7 +543,7 @@ void PxVehiclePvdPhysXWheelAttachmentWrite const PxVehicleArrayData& physxRoadGeomState, const PxVehicleArrayData& physxConstraintStates, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Register the PxRigidActor instance that represents the vehicle's rigid body in a PhysX scene. @@ -573,8 +552,6 @@ void PxVehiclePvdPhysXWheelAttachmentWrite \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 @@ -582,7 +559,7 @@ void PxVehiclePvdPhysXWheelAttachmentWrite void PxVehiclePvdPhysXRigidActorRegister (const PxVehiclePhysXActor* physxActor, const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); /** \brief Write the PxRigidActor instance to omnipvd. @@ -591,8 +568,6 @@ void PxVehiclePvdPhysXRigidActorRegister \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 @@ -600,7 +575,7 @@ void PxVehiclePvdPhysXRigidActorRegister void PxVehiclePvdPhysXRigidActorWrite (const PxVehiclePhysXActor* physxActor, const PxVehiclePvdAttributeHandles& attributeHandles, - const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter); #if !PX_DOXYGEN } // namespace vehicle2 diff --git a/physx/include/vehicle2/pvd/PxVehiclePvdHelpers.h b/physx/include/vehicle2/pvd/PxVehiclePvdHelpers.h index 1151dee8d..39d9f9042 100644 --- a/physx/include/vehicle2/pvd/PxVehiclePvdHelpers.h +++ b/physx/include/vehicle2/pvd/PxVehiclePvdHelpers.h @@ -56,23 +56,21 @@ namespace vehicle2 \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); +(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); +(PxAllocatorCallback& allocator, PxVehiclePvdAttributeHandles& attributeHandles); /** \brief Create omnipvd objects that will be used to reflect an individual veicle in omnipvd. @@ -80,8 +78,6 @@ void PxVehiclePvdAttributesRelease \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 @@ -92,19 +88,16 @@ void PxVehiclePvdAttributesRelease */ PxVehiclePvdObjectHandles* PxVehiclePvdObjectCreate (const PxU32 nbWheels, const PxU32 nbAntirolls, const PxU32 maxNbPhysxMaterialFrictions, - const PxU64 contextHandle, const PxVehiclePvdAttributeHandles& attributeHandles, - OmniPvdWriter* omniWriter, PxAllocatorCallback& allocator); + const PxU64 contextHandle, 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); +(OmniPvdWriter& omniWriter, PxAllocatorCallback& allocator, PxVehiclePvdObjectHandles& objectHandles); #if !PX_DOXYGEN } // namespace vehicle2 diff --git a/physx/include/vehicle2/tire/PxVehicleTireComponents.h b/physx/include/vehicle2/tire/PxVehicleTireComponents.h index 32b1f1f74..608ef6d34 100644 --- a/physx/include/vehicle2/tire/PxVehicleTireComponents.h +++ b/physx/include/vehicle2/tire/PxVehicleTireComponents.h @@ -128,7 +128,7 @@ class PxVehicleTireComponent : public PxVehicleComponent PxVehicleTireSlipSpeedsUpdate( wheelParams[wheelId], suspensionParams[wheelId], steerResponseStates[wheelId], suspensionStates[wheelId], tireDirectionStates[wheelId], - *rigidBodyState, roadGeomStates[i], + *rigidBodyState, roadGeomStates[wheelId], context.frame, tireSpeedStates[wheelId]); diff --git a/physx/pvdruntime/compiler/cmake/CMakeLists.txt b/physx/pvdruntime/compiler/cmake/CMakeLists.txt index 620bbc6a9..a83ce7c98 100644 --- a/physx/pvdruntime/compiler/cmake/CMakeLists.txt +++ b/physx/pvdruntime/compiler/cmake/CMakeLists.txt @@ -30,20 +30,6 @@ project(PVDRuntime C CXX) set(PVDRuntimeBuilt 1 CACHE INTERNAL "PVDRuntimeBuilt") -IF(NOT DEFINED CMAKEMODULES_VERSION) - SET(CMAKEMODULES_PATH $ENV{PM_CMakeModules_PATH} CACHE INTERNAL "Path to CMakeModules") - SET(CMAKEMODULES_NAME $ENV{PM_CMakeModules_NAME} CACHE INTERNAL "CMakeModules name") - SET(CMAKEMODULES_VERSION $ENV{PM_CMakeModules_VERSION} CACHE INTERNAL "CMakeModules version from generation batch") - - #TODO: More elegance - IF(NOT EXISTS ${CMAKEMODULES_PATH}) - MESSAGE(FATAL_ERROR "Could not find ${CMAKEMODULES_PATH}") - ENDIF() - -ENDIF() - -SET(CMAKE_MODULE_PATH ${CMAKEMODULES_PATH}) - # This is required to be defined by external callers! IF(NOT DEFINED PHYSX_ROOT_DIR) MESSAGE(FATAL_ERROR "PHYSX_ROOT_DIR variable wasn't set.") diff --git a/physx/pvdruntime/compiler/cmake/PVDRuntime.cmake b/physx/pvdruntime/compiler/cmake/PVDRuntime.cmake index 63f1b23af..dbf31d53c 100644 --- a/physx/pvdruntime/compiler/cmake/PVDRuntime.cmake +++ b/physx/pvdruntime/compiler/cmake/PVDRuntime.cmake @@ -42,6 +42,8 @@ SET(PVDRUNTIME_HEADERS ${PHYSX_ROOT_DIR}/pvdruntime/include/OmniPvdFileReadStream.h ${PHYSX_ROOT_DIR}/pvdruntime/include/OmniPvdFileWriteStream.h ${PHYSX_ROOT_DIR}/pvdruntime/include/OmniPvdMemoryStream.h + ${PHYSX_ROOT_DIR}/pvdruntime/include/OmniPvdLibraryHelpers.h + ${PHYSX_ROOT_DIR}/pvdruntime/include/OmniPvdLoader.h ) SOURCE_GROUP(include FILES ${PVDRUNTIME_HEADERS}) @@ -52,6 +54,9 @@ SET(PVDRUNTIME_HEADERS_USER INSTALL(FILES ${PVDRUNTIME_HEADERS} ${PVDRUNTIME_HEADERS_USER} DESTINATION pvdruntime/include) SET(PVDRUNTIME_SOURCES + ${PHYSX_ROOT_DIR}/pvdruntime/src/OmniPvdDefinesInternal.h + ${PHYSX_ROOT_DIR}/pvdruntime/src/OmniPvdHelpers.h + ${PHYSX_ROOT_DIR}/pvdruntime/src/OmniPvdHelpers.cpp ${PHYSX_ROOT_DIR}/pvdruntime/src/OmniPvdLibraryFunctionsImpl.cpp ${PHYSX_ROOT_DIR}/pvdruntime/src/OmniPvdLog.h ${PHYSX_ROOT_DIR}/pvdruntime/src/OmniPvdLog.cpp diff --git a/physx/pvdruntime/include/OmniPvdCommands.h b/physx/pvdruntime/include/OmniPvdCommands.h index 514e54efd..6dd1a5a6e 100644 --- a/physx/pvdruntime/include/OmniPvdCommands.h +++ b/physx/pvdruntime/include/OmniPvdCommands.h @@ -29,23 +29,23 @@ #ifndef OMNI_PVD_COMMANDS_H #define OMNI_PVD_COMMANDS_H -struct OmniPvdCommandEnum +struct OmniPvdCommand { enum Enum { - eOmniPvdInvalid, - eOmniPvdRegisterClass, - eOmniPvdRegisterEnum, - eOmniPvdRegisterAttribute, - eOmniPvdRegisterClassAttribute, - eOmniPvdRegisterSetAttribute, - eOmniPvdSetAttribute, - eOmniPvdAddToSetAttribute, - eOmniPvdRemoveFromSetAttribute, - eOmniPvdCreateObject, - eOmniPvdDestroyObject, - eOmniPvdStartFrame, - eOmniPvdStopFrame + eINVALID, + eREGISTER_CLASS, + eREGISTER_ENUM, + eREGISTER_ATTRIBUTE, + eREGISTER_CLASS_ATTRIBUTE, + eREGISTER_UNIQUE_LIST_ATTRIBUTE, + eSET_ATTRIBUTE, + eADD_TO_UNIQUE_LIST_ATTRIBUTE, + eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE, + eCREATE_OBJECT, + eDESTROY_OBJECT, + eSTART_FRAME, + eSTOP_FRAME }; }; diff --git a/physx/pvdruntime/include/OmniPvdDefines.h b/physx/pvdruntime/include/OmniPvdDefines.h index dfcd5b0d1..d97d07c8f 100644 --- a/physx/pvdruntime/include/OmniPvdDefines.h +++ b/physx/pvdruntime/include/OmniPvdDefines.h @@ -69,12 +69,11 @@ typedef uint64_t OmniPvdObjectHandle; typedef uint64_t OmniPvdContextHandle; typedef uint32_t OmniPvdClassHandle; typedef uint32_t OmniPvdAttributeHandle; -typedef uint16_t OmniPvdAttributeDataType; typedef uint32_t OmniPvdVersionType; typedef void (OMNI_PVD_CALL *OmniPvdLogFunction)(char *logLine); -struct OmniPvdDataTypeEnum +struct OmniPvdDataType { enum Enum { diff --git a/physx/pvdruntime/include/OmniPvdLibraryFunctions.h b/physx/pvdruntime/include/OmniPvdLibraryFunctions.h index e292d224e..7c28f3c57 100644 --- a/physx/pvdruntime/include/OmniPvdLibraryFunctions.h +++ b/physx/pvdruntime/include/OmniPvdLibraryFunctions.h @@ -37,18 +37,18 @@ class OmniPvdFileWriteStream; class OmniPvdMemoryStream; typedef OmniPvdReader* (OMNI_PVD_CALL *createOmniPvdReaderFp)(); -typedef void (OMNI_PVD_CALL *destroyOmniPvdReaderFp)(OmniPvdReader *reader); +typedef void (OMNI_PVD_CALL *destroyOmniPvdReaderFp)(OmniPvdReader& reader); typedef OmniPvdWriter* (OMNI_PVD_CALL *createOmniPvdWriterFp)(); -typedef void (OMNI_PVD_CALL *destroyOmniPvdWriterFp)(OmniPvdWriter *writer); +typedef void (OMNI_PVD_CALL *destroyOmniPvdWriterFp)(OmniPvdWriter& writer); typedef OmniPvdFileReadStream* (OMNI_PVD_CALL *createOmniPvdFileReadStreamFp)(); -typedef void (OMNI_PVD_CALL *destroyOmniPvdFileReadStreamFp)(OmniPvdFileReadStream *fileReadStream); +typedef void (OMNI_PVD_CALL *destroyOmniPvdFileReadStreamFp)(OmniPvdFileReadStream& fileReadStream); typedef OmniPvdFileWriteStream* (OMNI_PVD_CALL *createOmniPvdFileWriteStreamFp)(); -typedef void (OMNI_PVD_CALL *destroyOmniPvdFileWriteStreamFp)(OmniPvdFileWriteStream *fileWriteStream); +typedef void (OMNI_PVD_CALL *destroyOmniPvdFileWriteStreamFp)(OmniPvdFileWriteStream& fileWriteStream); typedef OmniPvdMemoryStream* (OMNI_PVD_CALL *createOmniPvdMemoryStreamFp)(); -typedef void (OMNI_PVD_CALL *destroyOmniPvdMemoryStreamFp)(OmniPvdMemoryStream *memoryStream); +typedef void (OMNI_PVD_CALL *destroyOmniPvdMemoryStreamFp)(OmniPvdMemoryStream& memoryStream); #endif diff --git a/physx/pvdruntime/include/OmniPvdLoader.h b/physx/pvdruntime/include/OmniPvdLoader.h index a15c0bc42..ace2880f4 100644 --- a/physx/pvdruntime/include/OmniPvdLoader.h +++ b/physx/pvdruntime/include/OmniPvdLoader.h @@ -34,7 +34,9 @@ #include #ifdef OMNI_PVD_WIN - #include + #ifndef _WINDOWS_ // windows already included otherwise + #include + #endif #elif defined(__linux__) #include #endif diff --git a/physx/pvdruntime/include/OmniPvdReadStream.h b/physx/pvdruntime/include/OmniPvdReadStream.h index d089d705c..36a50b2fa 100644 --- a/physx/pvdruntime/include/OmniPvdReadStream.h +++ b/physx/pvdruntime/include/OmniPvdReadStream.h @@ -50,7 +50,7 @@ class OmniPvdReadStream * @param nbrBytes The requested number of bytes to read * @return The actual number of bytes read */ - virtual uint64_t OMNI_PVD_CALL readBytes(uint8_t* bytes, const uint64_t nbrBytes) = 0; + virtual uint64_t OMNI_PVD_CALL readBytes(uint8_t* bytes, uint64_t nbrBytes) = 0; /** * @brief Skip n bytes from the shared memory buffer @@ -58,7 +58,7 @@ class OmniPvdReadStream * @param nbrBytes The requested number of bytes to skip * @return The actual number of bytes skipped */ - virtual uint64_t OMNI_PVD_CALL skipBytes(const uint64_t nbrBytes) = 0; + virtual uint64_t OMNI_PVD_CALL skipBytes(uint64_t nbrBytes) = 0; /** * @brief Opens the read stream diff --git a/physx/pvdruntime/include/OmniPvdReader.h b/physx/pvdruntime/include/OmniPvdReader.h index f8d1a31ba..825a7a697 100644 --- a/physx/pvdruntime/include/OmniPvdReader.h +++ b/physx/pvdruntime/include/OmniPvdReader.h @@ -38,7 +38,7 @@ * * Using the getNextCommand function in a while loop for example one can traverse the stream one command after another. Given the command, different functions below will be available. * - * Using the OmniPvdCommandEnum one can determine the type of command and like that use the appropriate get functions to extract the payload from the command. + * Using the OmniPvdCommand::Enum one can determine the type of command and like that use the appropriate get functions to extract the payload from the command. */ class OmniPvdReader @@ -60,31 +60,24 @@ class OmniPvdReader * * @param stream The OmniPvdReadStream that holds the stream of API calls/notifications */ - virtual void OMNI_PVD_CALL setReadStream(OmniPvdReadStream* stream) = 0; + virtual void OMNI_PVD_CALL setReadStream(OmniPvdReadStream& stream) = 0; /** - * @brief Extracts the versions from the binary file ro read and tests if the file is older or equal to that of the reader. + * @brief Extracts the versions from the binary file to read and tests if the file is older or equal to that of the reader. * * @param majorVersion The major versions of the stream * @param minorVersion The minor versions of the stream * @param patch The patch number of the stream * @return If the reading was possible to start or not */ - virtual bool OMNI_PVD_CALL startReading(OmniPvdVersionType* majorVersion, OmniPvdVersionType* minorVersion, OmniPvdVersionType* patch) = 0; + virtual bool OMNI_PVD_CALL startReading(OmniPvdVersionType& majorVersion, OmniPvdVersionType& minorVersion, OmniPvdVersionType& patch) = 0; /** - * @brief The heartbeat function of the reader class. As long as the command that is returned is not equal to OmniPvdCommandEnum::eOmniPvdInvalid, then one can safely extract the data fields from the command. + * @brief The heartbeat function of the reader class. As long as the command that is returned is not equal to OmniPvdCommand::eINVALID, then one can safely extract the data fields from the command. * * @return The command enum type */ - virtual OmniPvdCommandEnum::Enum OMNI_PVD_CALL getNextCommand() = 0; - - /** - * @brief Returns the command type as an enumerator of the latest command - * - * @return The latest command enum type - */ - virtual OmniPvdCommandEnum::Enum OMNI_PVD_CALL getCommandType() = 0; + virtual OmniPvdCommand::Enum OMNI_PVD_CALL getNextCommand() = 0; /** * @brief Returns the major version of the stream @@ -147,35 +140,35 @@ class OmniPvdReader * * @return The string containing the class name */ - virtual char* OMNI_PVD_CALL getClassName() = 0; + virtual const char* OMNI_PVD_CALL getClassName() = 0; /** * @brief Returns the attribute name of the latest commmnd, if it had one, else a null terminated string of length 0 * * @return The string containing the attribute name */ - virtual char* OMNI_PVD_CALL getAttributeName() = 0; + virtual const char* OMNI_PVD_CALL getAttributeName() = 0; /** * @brief Returns the object name of the latest commmnd, if it had one, else a null terminated string of length 0 * * @return The string containing the object name */ - virtual char* OMNI_PVD_CALL getObjectName() = 0; + virtual const char* OMNI_PVD_CALL getObjectName() = 0; /** * @brief Returns the attribute data pointer, the data is undefined if the last command did not contain attribute data * * @return The array containing the attribute data */ - virtual uint8_t* OMNI_PVD_CALL getAttributeDataPointer() = 0; + virtual const uint8_t* OMNI_PVD_CALL getAttributeDataPointer() = 0; /** * @brief Returns the attribute data type, the data is undefined if the last command did not contain attribute data * * @return The attribute data type */ - virtual OmniPvdAttributeDataType OMNI_PVD_CALL getAttributeDataType() = 0; + virtual OmniPvdDataType::Enum OMNI_PVD_CALL getAttributeDataType() = 0; /** * @brief Returns the attribute data length, the data length of the last command diff --git a/physx/pvdruntime/include/OmniPvdWriteStream.h b/physx/pvdruntime/include/OmniPvdWriteStream.h index d636a5a17..a640d3d49 100644 --- a/physx/pvdruntime/include/OmniPvdWriteStream.h +++ b/physx/pvdruntime/include/OmniPvdWriteStream.h @@ -50,7 +50,7 @@ class OmniPvdWriteStream * @param nbrBytes The requested number of bytes to write * @return The actual number of bytes written */ - virtual uint64_t OMNI_PVD_CALL writeBytes(const uint8_t* bytes, const uint64_t nbrBytes) = 0; + virtual uint64_t OMNI_PVD_CALL writeBytes(const uint8_t* bytes, uint64_t nbrBytes) = 0; /** * @brief Flushes the writes diff --git a/physx/pvdruntime/include/OmniPvdWriter.h b/physx/pvdruntime/include/OmniPvdWriter.h index 1528d7d84..2f8c7dec3 100644 --- a/physx/pvdruntime/include/OmniPvdWriter.h +++ b/physx/pvdruntime/include/OmniPvdWriter.h @@ -62,7 +62,7 @@ class OmniPvdWriter * * @param writeStream The OmniPvdWriteStream to receive the stream of API calls/notifications */ - virtual void OMNI_PVD_CALL setWriteStream(const OmniPvdWriteStream* writeStream) = 0; + virtual void OMNI_PVD_CALL setWriteStream(OmniPvdWriteStream& writeStream) = 0; /** * @brief Gets the pointer to the write stream @@ -84,7 +84,7 @@ class OmniPvdWriter * @see OmniPvdWriter::registerEnumValue() * @see OmniPvdWriter::registerFlagsAttribute() * @see OmniPvdWriter::registerClassAttribute() - * @see OmniPvdWriter::registerSetAttribute() + * @see OmniPvdWriter::registerUniqueListAttribute() * @see OmniPvdWriter::createObject() */ virtual OmniPvdClassHandle OMNI_PVD_CALL registerClass(const char* className, OmniPvdClassHandle baseClassHandle = 0) = 0; @@ -103,23 +103,23 @@ class OmniPvdWriter * * @see OmniPvdWriter::registerClass() */ - virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerEnumValue(const OmniPvdClassHandle classHandle, const char* attributeName, const uint32_t value) = 0; + virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerEnumValue(OmniPvdClassHandle classHandle, const char* attributeName, uint32_t value) = 0; /** * @brief Registers an attribute. * - * The class handle is obtained from a previous call to registerClass(). After registering an attribute, one gets an attribute handle which can be used to set data values of an attribute with setAttribute(). All attributes are treated as arrays, even if the attribute has only a single data item. Set nbrFields to 0 to indicate that the array has a variable length. + * The class handle is obtained from a previous call to registerClass(). After registering an attribute, one gets an attribute handle which can be used to set data values of an attribute with setAttribute(). All attributes are treated as arrays, even if the attribute has only a single data item. Set nbElements to 0 to indicate that the array has a variable length. * * @param classHandle The handle from the registerClass() call * @param attributeName The attribute name - * @param attributeDataType The attribute data type // TODO: Change to type OmniPvdDataTypeEnum - * @param nbrFields The number of fields. Set this to 0 to indicate a variable length array + * @param attributeDataType The attribute data type + * @param nbElements The number of elements in the array. Set this to 0 to indicate a variable length array * @return A unique attribute handle for the registered attribute * * @see OmniPvdWriter::registerClass() * @see OmniPvdWriter::setAttribute() */ - virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdAttributeDataType attributeDataType, const uint32_t nbrFields) = 0; + virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdDataType::Enum attributeDataType, uint32_t nbElements) = 0; /** * @brief Registers an attribute which is a flag. @@ -129,14 +129,14 @@ class OmniPvdWriter * The returned attribute handle can be used in setAttribute() to set an object's flags. * * @param classHandle The handle from the registerClass() call of the class - * @param enumClassHandle The handle from the registerClass() call of the enum * @param attributeName The attribute name + * @param enumClassHandle The handle from the registerClass() call of the enum * @return A unique attribute handle for the registered flags attribute * * @see OmniPvdWriter::registerClass() * @see OmniPvdWriter::setAttribute() */ - virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerFlagsAttribute(const OmniPvdClassHandle classHandle, const OmniPvdClassHandle enumClassHandle, const char* attributeName) = 0; + virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerFlagsAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle enumClassHandle) = 0; /** * @brief Registers an attribute which is a class. @@ -153,42 +153,47 @@ class OmniPvdWriter * @see OmniPvdWriter::registerClass() * @see OmniPvdWriter::setAttribute() */ - virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerClassAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdClassHandle classAttributeHandle) = 0; + virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerClassAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle classAttributeHandle) = 0; /** - * @brief Registers an attribute which is a set. - * - * A set is a collection of unique items and has a variable size. + * @brief Registers an attribute which can hold a list of unique items. * - * The returned attribute handle can be used in calls to addToSetAttribute() and removeFromSetAttribute(), to add an item to and remove it from a set, respectively. + * The returned attribute handle can be used in calls to addToUniqueListAttribute() and removeFromUniqueListAttribute(), to add an item to and remove it from the list, respectively. * * @param classHandle The handle from the registerClass() call of the class * @param attributeName The attribute name - * @param attributeDataType The data type of items in the set attribute - * @return A unique handle for the registered set attribute + * @param attributeDataType The data type of the items which will get added to the list attribute + * @return A unique handle for the registered list attribute * * @see OmniPvdWriter::registerClass() - * @see OmniPvdWriter::addToSetAttribute() - * @see OmniPvdWriter::removeFromSetAttribute() + * @see OmniPvdWriter::addToUniqueListAttribute() + * @see OmniPvdWriter::removeFromUniqueListAttribute() */ - virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerSetAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdAttributeDataType attributeDataType) = 0; + virtual OmniPvdAttributeHandle OMNI_PVD_CALL registerUniqueListAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdDataType::Enum attributeDataType) = 0; /** * @brief Sets an attribute value. * + * Since an attribute can be part of a nested construct of class attributes, the method + * expects an array of attribute handles as input to uniquely identify the attribute. + * * @param contextHandle The user-defined context handle for grouping objects * @param objectHandle The user-defined unique handle of the object. E.g. its physical memory address - * @param handleDepth The number of nested attribute handles requiref to identify the attribute - * @param attributeHandles The nested attribute handles needed to identify the attribute + * @param attributeHandles The attribute handles containing all class attribute handles of a nested class + * construct. The last one has to be the handle from the registerUniqueListAttribute() call. + * @param nbAttributeHandles The number of attribute handles provided in attributeHandles * @param data The pointer to the data of the element(s) to remove from the set * @param nbrBytes The number of bytes to be written + * + * @see OmniPvdWriter::registerAttribute() */ - virtual void OMNI_PVD_CALL setAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t *data, const uint32_t nbrBytes) = 0; + virtual void OMNI_PVD_CALL setAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t *data, uint32_t nbrBytes) = 0; /** * @brief Sets an attribute value. * - * Use the attribute handle from the registerAttribute() call to set the value of an attribute of an existing object. + * See other setAttribute method for details. This special version covers the case where the + * attribute is not part of a class attribute construct. * * @param contextHandle The user-defined context handle for grouping objects * @param objectHandle The user-defined unique handle of the object. E.g. its physical memory address @@ -198,73 +203,88 @@ class OmniPvdWriter * * @see OmniPvdWriter::registerAttribute() */ - virtual void OMNI_PVD_CALL setAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t *data, const uint32_t nbrBytes) = 0; + inline void OMNI_PVD_CALL setAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, OmniPvdAttributeHandle attributeHandle, const uint8_t *data, uint32_t nbrBytes) + { + setAttribute(contextHandle, objectHandle, &attributeHandle, 1, data, nbrBytes); + } /** - * @brief Adds an item to a set attribute. + * @brief Adds an item to a unique list attribute. * - * Use the attribute handle(s) from the registerSetAttribute() call to add an item to a set attribute. + * A unique list attribute is defined like a set in mathematics, where each element must be unique. * - * An array of nested attribute handles is required to uniquely identify the attribute. + * Since an attribute can be part of a nested construct of class attributes, the method + * expects an array of attribute handles as input to uniquely identify the attribute. * * @param contextHandle The user-defined context handle for grouping objects * @param objectHandle The user-defined unique handle of the object. E.g. its physical memory address - * @param handleDepth The number of nested attribute handles requiref to identify the attribute - * @param attributeHandles The nested attribute handles needed to identify the attribute - * @param data The pointer to the data of the element(s) to remove from the set + * @param attributeHandles The attribute handles containing all class attribute handles of a nested class + * construct. The last one has to be the handle from the registerUniqueListAttribute() call. + * @param nbAttributeHandles The number of attribute handles provided in attributeHandles + * @param data The pointer to the data of the item to add to the list * @param nbrBytes The number of bytes to be written + * + * @see OmniPvdWriter::registerUniqueListAttribute() */ - virtual void OMNI_PVD_CALL addToSetAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes) = 0; + virtual void OMNI_PVD_CALL addToUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes) = 0; /** - * @brief Adds an item to a set attribute. + * @brief Adds an item to a unique list attribute. * - * Use the attribute handle from the registerSetAttribute() call to add an item to a set attribute. - * - * A set attribute is defined like a set in mathematics, where each element must be unique. - * - * The Shallow part of the function indicates that an array of nested attribute handles is not required to uniquely identify the attribute. + * See other addToUniqueListAttribute method for details. This special version covers the case where the + * attribute is not part of a class attribute construct. * * @param contextHandle The user-defined context handle for grouping objects * @param objectHandle The user-defined unique handle of the object. E.g. its physical memory address - * @param attributeHandle The handle from the registerSetAttribute() call - * @param data The pointer to the data of the added set item + * @param attributeHandle The handle from the registerUniqueListAttribute() call + * @param data The pointer to the data of the item to add to the list * @param nbrBytes The number of bytes to be written * - * @see OmniPvdWriter::registerSetAttribute() + * @see OmniPvdWriter::registerUniqueListAttribute() */ - virtual void OMNI_PVD_CALL addToSetAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t* data, const uint32_t nbrBytes) = 0; + inline void OMNI_PVD_CALL addToUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, OmniPvdAttributeHandle attributeHandle, const uint8_t* data, uint32_t nbrBytes) + { + addToUniqueListAttribute(contextHandle, objectHandle, &attributeHandle, 1, data, nbrBytes); + } /** - * @brief Removes an item from a set attribute, where the attribute is allowed to be nested + * @brief Removes an item from a uniqe list attribute * - * A set attribute is defined like a set in mathematics, where each element must be unique. + * A uniqe list attribute is defined like a set in mathematics, where each element must be unique. * - * An array of nested attribute handles is required to uniquely identify the attribute. + * Since an attribute can be part of a nested construct of class attributes, the method + * expects an array of attribute handles as input to uniquely identify the attribute. * * @param contextHandle The user-defined context handle for grouping objects * @param objectHandle The user-defined unique handle of the object. E.g. its physical memory address - * @param handleDepth The number of nested attribute handles require to identify the attribute - * @param attributeHandles The attribute handles needed to identify the attribute - * @param data The pointer to the data of the element(s) to remove from the set + * @param attributeHandles The attribute handles containing all class attribute handles of a nested class + * construct. The last one has to be the handle from the registerUniqueListAttribute() call. + * @param nbAttributeHandles The number of attribute handles provided in attributeHandles + * @param data The pointer to the data of the item to remove from the list * @param nbrBytes The number of bytes to be written + * + * @see OmniPvdWriter::registerUniqueListAttribute() */ - virtual void OMNI_PVD_CALL removeFromSetAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes) = 0; + virtual void OMNI_PVD_CALL removeFromUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes) = 0; /** - * @brief Removes an item from a set attribute - * - * A set attribute is defined like a set in mathematics, where each element must be unique. + * @brief Removes an item from a uniqe list attribute * - * The Shallow part of the function indicates that an array of nested attribute handles is not required to uniquely identify the attribute. + * See other removeFromUniqueListAttribute method for details. This special version covers the case where the + * attribute is not part of a class attribute construct. * * @param contextHandle The user-defined context handle for grouping objects * @param objectHandle The user-defined unique handle of the object. E.g. its physical memory address - * @param attributeHandle The handle from the registerSetAttribute() call - * @param data The pointer to the data of the removed set element(s) + * @param attributeHandle The handle from the registerUniqueListAttribute() call + * @param data The pointer to the data of the item to remove from the list * @param nbrBytes The number of bytes to be written + * + * @see OmniPvdWriter::registerUniqueListAttribute() */ - virtual void OMNI_PVD_CALL removeFromSetAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t* data, const uint32_t nbrBytes) = 0; + inline void OMNI_PVD_CALL removeFromUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, OmniPvdAttributeHandle attributeHandle, const uint8_t* data, uint32_t nbrBytes) + { + removeFromUniqueListAttribute(contextHandle, objectHandle, &attributeHandle, 1, data, nbrBytes); + } /** * @brief Creates an object creation event @@ -285,7 +305,7 @@ class OmniPvdWriter * @see OmniPvdWriter::registerClass() * @see OmniPvdWriter::destroyObject() */ - virtual void OMNI_PVD_CALL createObject(const OmniPvdContextHandle contextHandle, const OmniPvdClassHandle classHandle, const OmniPvdObjectHandle objectHandle, const char* objectName) = 0; + virtual void OMNI_PVD_CALL createObject(OmniPvdContextHandle contextHandle, OmniPvdClassHandle classHandle, OmniPvdObjectHandle objectHandle, const char* objectName) = 0; /** * @brief Creates an object destruction event @@ -298,7 +318,7 @@ class OmniPvdWriter * @see OmniPvdWriter::registerClass() * @see OmniPvdWriter::createObject() */ - virtual void OMNI_PVD_CALL destroyObject(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle) = 0; + virtual void OMNI_PVD_CALL destroyObject(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle) = 0; /** * @brief Creates a frame start event @@ -308,7 +328,7 @@ class OmniPvdWriter * @param contextHandle The user-defined context handle for grouping objects * @param timeStamp The timestamp of the frame start event */ - virtual void OMNI_PVD_CALL startFrame(const OmniPvdContextHandle contextHandle, const uint64_t timeStamp) = 0; + virtual void OMNI_PVD_CALL startFrame(OmniPvdContextHandle contextHandle, uint64_t timeStamp) = 0; /** * @brief Creates a stop frame event @@ -318,7 +338,7 @@ class OmniPvdWriter * @param contextHandle The user-defined context handle for grouping objects * @param timeStamp The timestamp of the frame stop event */ - virtual void OMNI_PVD_CALL stopFrame(const OmniPvdContextHandle contextHandle, const uint64_t timeStamp) = 0; + virtual void OMNI_PVD_CALL stopFrame(OmniPvdContextHandle contextHandle, uint64_t timeStamp) = 0; }; diff --git a/physx/source/lowlevel/software/include/PxsDefaultMemoryManager.h b/physx/pvdruntime/src/OmniPvdDefinesInternal.h similarity index 87% rename from physx/source/lowlevel/software/include/PxsDefaultMemoryManager.h rename to physx/pvdruntime/src/OmniPvdDefinesInternal.h index 6655ad8fe..2d13c819c 100644 --- a/physx/source/lowlevel/software/include/PxsDefaultMemoryManager.h +++ b/physx/pvdruntime/src/OmniPvdDefinesInternal.h @@ -26,7 +26,15 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXS_DEFAULT_MEMORY_MANAGER_H -#define PXS_DEFAULT_MEMORY_MANAGER_H +#ifndef OMNI_PVD_DEFINES_INTERNAL_H +#define OMNI_PVD_DEFINES_INTERNAL_H + +#include + + +// types used to store certain properties in the PVD data stream +typedef uint8_t OmniPvdCommandStorageType; +typedef uint16_t OmniPvdDataTypeStorageType; + #endif diff --git a/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.cpp b/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.cpp index 520b6a49f..74ea73956 100644 --- a/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.cpp @@ -115,7 +115,7 @@ uint64_t OMNI_PVD_CALL OmniPvdFileReadStreamImpl::readBytes(uint8_t* bytes, uint } } -uint64_t OMNI_PVD_CALL OmniPvdFileReadStreamImpl::skipBytes(const uint64_t nbrBytes) +uint64_t OMNI_PVD_CALL OmniPvdFileReadStreamImpl::skipBytes(uint64_t nbrBytes) { if (mFileWasOpened) { diff --git a/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.h b/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.h index 445431dd3..c510bfd26 100644 --- a/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.h +++ b/physx/pvdruntime/src/OmniPvdFileReadStreamImpl.h @@ -42,8 +42,8 @@ class OmniPvdFileReadStreamImpl : public OmniPvdFileReadStream void OMNI_PVD_CALL setFileName(const char *fileName); bool OMNI_PVD_CALL openFile(); bool OMNI_PVD_CALL closeFile(); - uint64_t OMNI_PVD_CALL readBytes(uint8_t* bytes, const uint64_t nbrBytes); - uint64_t OMNI_PVD_CALL skipBytes(const uint64_t nbrBytes); + uint64_t OMNI_PVD_CALL readBytes(uint8_t* bytes, uint64_t nbrBytes); + uint64_t OMNI_PVD_CALL skipBytes(uint64_t nbrBytes); bool OMNI_PVD_CALL openStream(); bool OMNI_PVD_CALL closeStream(); diff --git a/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.cpp b/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.cpp index a8bd6ce0c..3ee098648 100644 --- a/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.cpp @@ -91,7 +91,7 @@ bool OMNI_PVD_CALL OmniPvdFileWriteStreamImpl::closeFile() return true; } -uint64_t OMNI_PVD_CALL OmniPvdFileWriteStreamImpl::writeBytes(const uint8_t *bytes, const uint64_t nbrBytes) +uint64_t OMNI_PVD_CALL OmniPvdFileWriteStreamImpl::writeBytes(const uint8_t *bytes, uint64_t nbrBytes) { size_t result = 0; if (mFileWasOpened) diff --git a/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.h b/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.h index 71f8d1ef3..97aa8639e 100644 --- a/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.h +++ b/physx/pvdruntime/src/OmniPvdFileWriteStreamImpl.h @@ -41,7 +41,7 @@ class OmniPvdFileWriteStreamImpl : public OmniPvdFileWriteStream { void OMNI_PVD_CALL setFileName(const char *fileName); bool OMNI_PVD_CALL openFile(); bool OMNI_PVD_CALL closeFile(); - uint64_t OMNI_PVD_CALL writeBytes(const uint8_t* bytes, const uint64_t nbrBytes); + uint64_t OMNI_PVD_CALL writeBytes(const uint8_t* bytes, uint64_t nbrBytes); bool OMNI_PVD_CALL flush(); bool OMNI_PVD_CALL openStream(); bool OMNI_PVD_CALL closeStream(); diff --git a/physx/pvdruntime/src/OmniPvdHelpers.cpp b/physx/pvdruntime/src/OmniPvdHelpers.cpp index 93a2b1f4f..e644c4467 100644 --- a/physx/pvdruntime/src/OmniPvdHelpers.cpp +++ b/physx/pvdruntime/src/OmniPvdHelpers.cpp @@ -33,7 +33,7 @@ uint8_t OmniPvdCompressInt(uint64_t handle, uint8_t *bytes) { uint8_t shiftBits = 0; for (int i = 0; i < 8; i++) { if ((handle >> shiftBits) & 0x7f) { - lastBitGroupIndex = i; + lastBitGroupIndex = static_cast(i); } shiftBits += 7; } @@ -46,6 +46,8 @@ uint8_t OmniPvdCompressInt(uint64_t handle, uint8_t *bytes) { bytes[i] = currentBitGroup; shiftBits += 7; } + + return lastBitGroupIndex; } uint64_t OmniPvdDeCompressInt(uint8_t *bytes, uint8_t maxBytes) { diff --git a/physx/pvdruntime/src/OmniPvdLibraryFunctionsImpl.cpp b/physx/pvdruntime/src/OmniPvdLibraryFunctionsImpl.cpp index 6ce68efbd..1383afc19 100644 --- a/physx/pvdruntime/src/OmniPvdLibraryFunctionsImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdLibraryFunctionsImpl.cpp @@ -38,9 +38,9 @@ OMNI_PVD_EXPORT OmniPvdReader* OMNI_PVD_CALL createOmniPvdReader() return new OmniPvdReaderImpl(); } -OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdReader(OmniPvdReader *reader) +OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdReader(OmniPvdReader& reader) { - OmniPvdReaderImpl *impl = (OmniPvdReaderImpl*)reader; + OmniPvdReaderImpl* impl = (OmniPvdReaderImpl*)(&reader); delete impl; } @@ -49,9 +49,9 @@ OMNI_PVD_EXPORT OmniPvdWriter* OMNI_PVD_CALL createOmniPvdWriter() return new OmniPvdWriterImpl(); } -OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdWriter(OmniPvdWriter *writer) +OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdWriter(OmniPvdWriter& writer) { - OmniPvdWriterImpl *impl = (OmniPvdWriterImpl*)writer; + OmniPvdWriterImpl* impl = (OmniPvdWriterImpl*)(&writer); delete impl; } @@ -60,9 +60,9 @@ OMNI_PVD_EXPORT OmniPvdFileReadStream* OMNI_PVD_CALL createOmniPvdFileReadStream return new OmniPvdFileReadStreamImpl(); } -OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdFileReadStream(OmniPvdFileReadStream *readStream) +OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdFileReadStream(OmniPvdFileReadStream& readStream) { - OmniPvdFileReadStreamImpl *impl = (OmniPvdFileReadStreamImpl*)readStream; + OmniPvdFileReadStreamImpl* impl = (OmniPvdFileReadStreamImpl*)(&readStream); delete impl; } @@ -71,9 +71,9 @@ OMNI_PVD_EXPORT OmniPvdFileWriteStream* OMNI_PVD_CALL createOmniPvdFileWriteStre return new OmniPvdFileWriteStreamImpl(); } -OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdFileWriteStream(OmniPvdFileWriteStream *writeStream) +OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdFileWriteStream(OmniPvdFileWriteStream& writeStream) { - OmniPvdFileWriteStreamImpl *impl = (OmniPvdFileWriteStreamImpl*)writeStream; + OmniPvdFileWriteStreamImpl* impl = (OmniPvdFileWriteStreamImpl*)(&writeStream); delete impl; } @@ -82,8 +82,8 @@ OMNI_PVD_EXPORT OmniPvdMemoryStream* OMNI_PVD_CALL createOmniPvdMemoryStream() return new OmniPvdMemoryStreamImpl(); } -OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdMemoryStream(OmniPvdMemoryStream *memoryStream) +OMNI_PVD_EXPORT void OMNI_PVD_CALL destroyOmniPvdMemoryStream(OmniPvdMemoryStream& memoryStream) { - OmniPvdMemoryStreamImpl *impl = (OmniPvdMemoryStreamImpl*)memoryStream; + OmniPvdMemoryStreamImpl* impl = (OmniPvdMemoryStreamImpl*)(&memoryStream); delete impl; } diff --git a/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.cpp b/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.cpp index f907b5db0..2ac8fda74 100644 --- a/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.cpp @@ -42,7 +42,7 @@ uint64_t OMNI_PVD_CALL OmniPvdMemoryReadStreamImpl::readBytes(uint8_t* destinati return mMemoryStream->readBytes(destination, nbrBytes); } -uint64_t OMNI_PVD_CALL OmniPvdMemoryReadStreamImpl::skipBytes(const uint64_t nbrBytes) +uint64_t OMNI_PVD_CALL OmniPvdMemoryReadStreamImpl::skipBytes(uint64_t nbrBytes) { return mMemoryStream->skipBytes(nbrBytes); } diff --git a/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.h b/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.h index 49d6cf6a5..92809a56c 100644 --- a/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.h +++ b/physx/pvdruntime/src/OmniPvdMemoryReadStreamImpl.h @@ -39,8 +39,8 @@ class OmniPvdMemoryReadStreamImpl : public OmniPvdReadStream OmniPvdMemoryReadStreamImpl(); ~OmniPvdMemoryReadStreamImpl(); - uint64_t OMNI_PVD_CALL readBytes(uint8_t* destination, const uint64_t nbrBytes); - uint64_t OMNI_PVD_CALL skipBytes(const uint64_t nbrBytes); + uint64_t OMNI_PVD_CALL readBytes(uint8_t* destination, uint64_t nbrBytes); + uint64_t OMNI_PVD_CALL skipBytes(uint64_t nbrBytes); bool OMNI_PVD_CALL openStream(); bool OMNI_PVD_CALL closeStream(); diff --git a/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.cpp b/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.cpp index a58345af4..f27461642 100644 --- a/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.cpp @@ -136,12 +136,12 @@ uint64_t OMNI_PVD_CALL OmniPvdMemoryStreamImpl::readBytes(uint8_t* destination, return requestedReadBytes; } -uint64_t OmniPvdMemoryStreamImpl::skipBytes(const uint64_t nbrBytes) +uint64_t OmniPvdMemoryStreamImpl::skipBytes(uint64_t nbrBytes) { return readBytes(0, nbrBytes); } -uint64_t OmniPvdMemoryStreamImpl::writeBytes(const uint8_t* source, const uint64_t nbrBytes) +uint64_t OmniPvdMemoryStreamImpl::writeBytes(const uint8_t* source, uint64_t nbrBytes) { if (mWrittenBytes >= mBufferLength) { diff --git a/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.h b/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.h index 7b5ce9e6e..0cd94e899 100644 --- a/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.h +++ b/physx/pvdruntime/src/OmniPvdMemoryStreamImpl.h @@ -48,12 +48,12 @@ class OmniPvdMemoryStreamImpl : public OmniPvdMemoryStream // Read part //////////////////////////////////////////////////////////////////////////////// uint64_t readBytes(uint8_t* destination, uint64_t nbrBytes); - uint64_t skipBytes(const uint64_t nbrBytes); + uint64_t skipBytes(uint64_t nbrBytes); //////////////////////////////////////////////////////////////////////////////// // Write part //////////////////////////////////////////////////////////////////////////////// - uint64_t writeBytes(const uint8_t* source, const uint64_t nbrBytes); + uint64_t writeBytes(const uint8_t* source, uint64_t nbrBytes); bool flush(); //////////////////////////////////////////////////////////////////////////////// diff --git a/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.cpp b/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.cpp index 262cca3a5..c6ef6d8df 100644 --- a/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.cpp @@ -37,7 +37,7 @@ OmniPvdMemoryWriteStreamImpl::~OmniPvdMemoryWriteStreamImpl() { } -uint64_t OMNI_PVD_CALL OmniPvdMemoryWriteStreamImpl::writeBytes(const uint8_t* source, const uint64_t nbrBytes) +uint64_t OMNI_PVD_CALL OmniPvdMemoryWriteStreamImpl::writeBytes(const uint8_t* source, uint64_t nbrBytes) { return mMemoryStream->writeBytes(source, nbrBytes); } diff --git a/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.h b/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.h index 11c25600b..92ce043d1 100644 --- a/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.h +++ b/physx/pvdruntime/src/OmniPvdMemoryWriteStreamImpl.h @@ -38,7 +38,7 @@ class OmniPvdMemoryWriteStreamImpl : public OmniPvdWriteStream public: OmniPvdMemoryWriteStreamImpl(); ~OmniPvdMemoryWriteStreamImpl(); - uint64_t OMNI_PVD_CALL writeBytes(const uint8_t* source, const uint64_t nbrBytes); + uint64_t OMNI_PVD_CALL writeBytes(const uint8_t* source, uint64_t nbrBytes); bool OMNI_PVD_CALL flush(); bool OMNI_PVD_CALL openStream(); bool OMNI_PVD_CALL closeStream(); diff --git a/physx/pvdruntime/src/OmniPvdReaderImpl.cpp b/physx/pvdruntime/src/OmniPvdReaderImpl.cpp index 395148645..9e08d6ea2 100644 --- a/physx/pvdruntime/src/OmniPvdReaderImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdReaderImpl.cpp @@ -26,6 +26,7 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. +#include "OmniPvdDefinesInternal.h" #include "OmniPvdReaderImpl.h" #include @@ -35,7 +36,6 @@ OmniPvdReaderImpl::OmniPvdReaderImpl() mMajorVersion = OMNI_PVD_VERSION_MAJOR; mMinorVersion = OMNI_PVD_VERSION_MINOR; mPatch = OMNI_PVD_VERSION_PATCH; - mCmdType = OmniPvdCommandEnum::eOmniPvdInvalid; mDataBuffer = 0; mDataBuffAllocatedLen = 0; mCmdAttributeDataPtr = 0; @@ -56,13 +56,13 @@ void OMNI_PVD_CALL OmniPvdReaderImpl::setLogFunction(OmniPvdLogFunction logFunct mLog.setLogFunction(logFunction); } -void OMNI_PVD_CALL OmniPvdReaderImpl::setReadStream(OmniPvdReadStream* stream) +void OMNI_PVD_CALL OmniPvdReaderImpl::setReadStream(OmniPvdReadStream& stream) { - mStream = stream; + mStream = &stream; mStream->openStream(); } -bool OMNI_PVD_CALL OmniPvdReaderImpl::startReading(OmniPvdVersionType* majorVersion, OmniPvdVersionType* minorVersion, OmniPvdVersionType* patch) +bool OMNI_PVD_CALL OmniPvdReaderImpl::startReading(OmniPvdVersionType& majorVersion, OmniPvdVersionType& minorVersion, OmniPvdVersionType& patch) { if (mIsReadingStarted) { @@ -70,13 +70,13 @@ bool OMNI_PVD_CALL OmniPvdReaderImpl::startReading(OmniPvdVersionType* majorVers } if (mStream) { - mStream->readBytes((uint8_t*)majorVersion, sizeof(OmniPvdVersionType)); - mStream->readBytes((uint8_t*)minorVersion, sizeof(OmniPvdVersionType)); - mStream->readBytes((uint8_t*)patch, sizeof(OmniPvdVersionType)); + mStream->readBytes((uint8_t*)&majorVersion, sizeof(OmniPvdVersionType)); + mStream->readBytes((uint8_t*)&minorVersion, sizeof(OmniPvdVersionType)); + mStream->readBytes((uint8_t*)&patch, sizeof(OmniPvdVersionType)); - mCmdMajorVersion = *majorVersion; - mCmdMinorVersion = *minorVersion; - mCmdPatch = *patch; + mCmdMajorVersion = majorVersion; + mCmdMinorVersion = minorVersion; + mCmdPatch = patch; if ((mCmdMajorVersion == 0) && (mCmdMinorVersion < 3)) { @@ -89,22 +89,22 @@ bool OMNI_PVD_CALL OmniPvdReaderImpl::startReading(OmniPvdVersionType* majorVers mReadBaseClassHandle = 1; } - mLog.outputLine("OmniPvdRuntimeReaderImpl::startReading majorVersion(%lu), minorVersion(%lu), patch(%lu)", static_cast(*majorVersion), static_cast(*minorVersion), static_cast(*patch)); - if ((*majorVersion) > mMajorVersion) + mLog.outputLine("OmniPvdRuntimeReaderImpl::startReading majorVersion(%lu), minorVersion(%lu), patch(%lu)", static_cast(majorVersion), static_cast(minorVersion), static_cast(patch)); + if (majorVersion > mMajorVersion) { mLog.outputLine("[parser] major version too new\n"); return false; } - else if ((*majorVersion) == mMajorVersion) + else if (majorVersion == mMajorVersion) { - if ((*minorVersion) > mMinorVersion) + if (minorVersion > mMinorVersion) { mLog.outputLine("[parser] minor version too new\n"); return false; } - else if ((*minorVersion) == mMinorVersion) + else if (minorVersion == mMinorVersion) { - if ((*patch) > mPatch) + if (patch > mPatch) { mLog.outputLine("[parser] patch too new\n"); return false; @@ -120,170 +120,179 @@ bool OMNI_PVD_CALL OmniPvdReaderImpl::startReading(OmniPvdVersionType* majorVers } -OmniPvdCommandEnum::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getNextCommand() +static OmniPvdDataType::Enum readDataType(OmniPvdReadStream& stream) { + OmniPvdDataTypeStorageType dataType; + stream.readBytes((uint8_t*)&dataType, sizeof(OmniPvdDataTypeStorageType)); + return static_cast(dataType); +} + +OmniPvdCommand::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getNextCommand() +{ + OmniPvdCommand::Enum cmdType = OmniPvdCommand::eINVALID; + if (!mIsReadingStarted) { - if (!startReading(&mCmdMajorVersion, &mCmdMinorVersion, &mCmdPatch)) + if (!startReading(mCmdMajorVersion, mCmdMinorVersion, mCmdPatch)) { - return OmniPvdCommandEnum::eOmniPvdInvalid; + return cmdType; } } - mCmdType = OmniPvdCommandEnum::eOmniPvdInvalid; + if (mStream) { - unsigned char command; - if (mStream->readBytes(&command, 1)) + OmniPvdCommandStorageType command; + if (mStream->readBytes(&command, sizeof(OmniPvdCommandStorageType))) { switch (command) { - case OmniPvdCommandEnum::eOmniPvdRegisterClass: + case OmniPvdCommand::eREGISTER_CLASS: { - mCmdType = OmniPvdCommandEnum::eOmniPvdRegisterClass; - mStream->readBytes((unsigned char*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); + cmdType = OmniPvdCommand::eREGISTER_CLASS; + mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); //////////////////////////////////////////////////////////////////////////////// // Skip reading the base class if the stream is older or equal to (0,2,x) //////////////////////////////////////////////////////////////////////////////// if (mReadBaseClassHandle) { - mStream->readBytes((unsigned char*)&mCmdBaseClassHandle, sizeof(OmniPvdClassHandle)); + mStream->readBytes((uint8_t*)&mCmdBaseClassHandle, sizeof(OmniPvdClassHandle)); } - mStream->readBytes((unsigned char*)&mCmdClassNameLen, sizeof(uint16_t)); - mStream->readBytes((unsigned char*)mCmdClassName, mCmdClassNameLen); + mStream->readBytes((uint8_t*)&mCmdClassNameLen, sizeof(uint16_t)); + mStream->readBytes((uint8_t*)mCmdClassName, mCmdClassNameLen); mCmdClassName[mCmdClassNameLen] = 0; // trailing zero mLog.outputLine("[parser] register class (handle: %llu, name: %s)\n", static_cast(mCmdClassHandle), mCmdClassName); } break; - case OmniPvdCommandEnum::eOmniPvdRegisterAttribute: + case OmniPvdCommand::eREGISTER_ATTRIBUTE: { - mCmdType = OmniPvdCommandEnum::eOmniPvdRegisterAttribute; - mStream->readBytes((unsigned char*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeDataType, sizeof(OmniPvdAttributeDataType)); - if (mCmdAttributeDataType == OmniPvdDataTypeEnum::eENUM_VALUE) + cmdType = OmniPvdCommand::eREGISTER_ATTRIBUTE; + mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mCmdAttributeDataType = readDataType(*mStream); + if (mCmdAttributeDataType == OmniPvdDataType::eENUM_VALUE) { - mStream->readBytes((unsigned char*)&mCmdEnumValue, sizeof(uint32_t)); + mStream->readBytes((uint8_t*)&mCmdEnumValue, sizeof(uint32_t)); } - else if (mCmdAttributeDataType == OmniPvdDataTypeEnum::eFLAGS_WORD) + else if (mCmdAttributeDataType == OmniPvdDataType::eFLAGS_WORD) { - mStream->readBytes((unsigned char*)&mCmdEnumClassHandle, sizeof(uint32_t)); + mStream->readBytes((uint8_t*)&mCmdEnumClassHandle, sizeof(uint32_t)); } else { mCmdEnumValue = 0; - mStream->readBytes((unsigned char*)&mCmdAttributeNbrFields, sizeof(uint32_t)); + mStream->readBytes((uint8_t*)&mCmdAttributeNbElements, sizeof(uint32_t)); } - mStream->readBytes((unsigned char*)&mCmdAttributeNameLen, sizeof(uint16_t)); - mStream->readBytes((unsigned char*)mCmdAttributeName, mCmdAttributeNameLen); + mStream->readBytes((uint8_t*)&mCmdAttributeNameLen, sizeof(uint16_t)); + mStream->readBytes((uint8_t*)mCmdAttributeName, mCmdAttributeNameLen); mCmdAttributeName[mCmdAttributeNameLen] = 0; // trailing zero - mLog.outputLine("[parser] register attribute (classHandle: %llu, handle: %llu, dataType: %llu, nrFields: %llu, name: %s)\n", static_cast(mCmdClassHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeDataType), static_cast(mCmdAttributeNbrFields), mCmdAttributeName); + mLog.outputLine("[parser] register attribute (classHandle: %llu, handle: %llu, dataType: %llu, nrFields: %llu, name: %s)\n", static_cast(mCmdClassHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeDataType), static_cast(mCmdAttributeNbElements), mCmdAttributeName); } break; - case OmniPvdCommandEnum::eOmniPvdRegisterClassAttribute: + case OmniPvdCommand::eREGISTER_CLASS_ATTRIBUTE: { - mCmdType = OmniPvdCommandEnum::eOmniPvdRegisterClassAttribute; - mStream->readBytes((unsigned char*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeClassHandle, sizeof(OmniPvdClassHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeNameLen, sizeof(uint16_t)); - mStream->readBytes((unsigned char*)mCmdAttributeName, mCmdAttributeNameLen); + cmdType = OmniPvdCommand::eREGISTER_CLASS_ATTRIBUTE; + mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeClassHandle, sizeof(OmniPvdClassHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeNameLen, sizeof(uint16_t)); + mStream->readBytes((uint8_t*)mCmdAttributeName, mCmdAttributeNameLen); mCmdAttributeName[mCmdAttributeNameLen] = 0; // trailing zero mLog.outputLine("[parser] register class attribute (classHandle: %llu, handle: %llu, classAttributeHandle: %llu, name: %s)\n", static_cast(mCmdClassHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeClassHandle), mCmdAttributeName); } break; - case OmniPvdCommandEnum::eOmniPvdRegisterSetAttribute: + case OmniPvdCommand::eREGISTER_UNIQUE_LIST_ATTRIBUTE: { - mCmdType = OmniPvdCommandEnum::eOmniPvdRegisterSetAttribute; - mStream->readBytes((unsigned char*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeDataType, sizeof(OmniPvdAttributeDataType)); - mStream->readBytes((unsigned char*)&mCmdAttributeNameLen, sizeof(uint16_t)); - mStream->readBytes((unsigned char*)mCmdAttributeName, mCmdAttributeNameLen); + cmdType = OmniPvdCommand::eREGISTER_UNIQUE_LIST_ATTRIBUTE; + mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mCmdAttributeDataType = readDataType(*mStream); + mStream->readBytes((uint8_t*)&mCmdAttributeNameLen, sizeof(uint16_t)); + mStream->readBytes((uint8_t*)mCmdAttributeName, mCmdAttributeNameLen); mCmdAttributeName[mCmdAttributeNameLen] = 0; // trailing zero mLog.outputLine("[parser] register attributeSet (classHandle: %llu, handle: %llu, dataType: %llu, name: %s)\n", static_cast(mCmdClassHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeDataType), mCmdAttributeName); } break; - case OmniPvdCommandEnum::eOmniPvdSetAttribute: + case OmniPvdCommand::eSET_ATTRIBUTE: { - mCmdType = OmniPvdCommandEnum::eOmniPvdSetAttribute; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); + cmdType = OmniPvdCommand::eSET_ATTRIBUTE; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); uint32_t* attributeHandleStack = mCmdAttributeHandleStack; for (int i = 0; i < mCmdAttributeHandleDepth; i++) { - mStream->readBytes((unsigned char*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); attributeHandleStack++; } - mStream->readBytes((unsigned char*)&mCmdAttributeDataLen, sizeof(uint32_t)); + mStream->readBytes((uint8_t*)&mCmdAttributeDataLen, sizeof(uint32_t)); readLongDataFromStream(mCmdAttributeDataLen); mLog.outputLine("[parser] set attribute (contextHandle:%llu, objectHandle: %llu, handle: %llu, dataLen: %llu)\n", static_cast(mCmdContextHandle), static_cast(mCmdObjectHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeDataLen)); } break; - case OmniPvdCommandEnum::eOmniPvdAddToSetAttribute: + case OmniPvdCommand::eADD_TO_UNIQUE_LIST_ATTRIBUTE: { - mCmdType = OmniPvdCommandEnum::eOmniPvdAddToSetAttribute; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); + cmdType = OmniPvdCommand::eADD_TO_UNIQUE_LIST_ATTRIBUTE; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); uint32_t* attributeHandleStack = mCmdAttributeHandleStack; for (int i = 0; i < mCmdAttributeHandleDepth; i++) { - mStream->readBytes((unsigned char*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); attributeHandleStack++; } - mStream->readBytes((unsigned char*)&mCmdAttributeDataLen, sizeof(uint32_t)); + mStream->readBytes((uint8_t*)&mCmdAttributeDataLen, sizeof(uint32_t)); readLongDataFromStream(mCmdAttributeDataLen); mLog.outputLine("[parser] add to attributeSet (contextHandle:%llu, objectHandle: %llu, attributeHandle: %llu, dataLen: %llu)\n", static_cast(mCmdContextHandle), static_cast(mCmdObjectHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeDataLen)); } break; - case OmniPvdCommandEnum::eOmniPvdRemoveFromSetAttribute: + case OmniPvdCommand::eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE: { - mCmdType = OmniPvdCommandEnum::eOmniPvdRemoveFromSetAttribute; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); - mStream->readBytes((unsigned char*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); + cmdType = OmniPvdCommand::eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); uint32_t* attributeHandleStack = mCmdAttributeHandleStack; for (int i = 0; i < mCmdAttributeHandleDepth; i++) { - mStream->readBytes((unsigned char*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); attributeHandleStack++; } - mStream->readBytes((unsigned char*)&mCmdAttributeDataLen, sizeof(uint32_t)); + mStream->readBytes((uint8_t*)&mCmdAttributeDataLen, sizeof(uint32_t)); readLongDataFromStream(mCmdAttributeDataLen); mLog.outputLine("[parser] remove from attributeSet (contextHandle:%llu, objectHandle: %llu, handle: %llu, dataLen: %llu)\n", static_cast(mCmdContextHandle), static_cast(mCmdObjectHandle), static_cast(mCmdAttributeHandle), static_cast(mCmdAttributeDataLen)); } break; - case OmniPvdCommandEnum::eOmniPvdCreateObject: + case OmniPvdCommand::eCREATE_OBJECT: { - mCmdType = OmniPvdCommandEnum::eOmniPvdCreateObject; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); - mStream->readBytes((unsigned char*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); - mStream->readBytes((unsigned char*)&mCmdObjectNameLen, sizeof(uint16_t)); + cmdType = OmniPvdCommand::eCREATE_OBJECT; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); + mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); + mStream->readBytes((uint8_t*)&mCmdObjectNameLen, sizeof(uint16_t)); if (mCmdObjectNameLen) { - mStream->readBytes((unsigned char*)mCmdObjectName, mCmdObjectNameLen); + mStream->readBytes((uint8_t*)mCmdObjectName, mCmdObjectNameLen); } mCmdObjectName[mCmdObjectNameLen] = 0; // trailing zero mLog.outputLine("[parser] create object (contextHandle: %llu, classHandle: %llu, objectHandle: %llu, name: %s)\n", static_cast(mCmdContextHandle), static_cast(mCmdClassHandle), static_cast(mCmdObjectHandle), mCmdObjectName); } break; - case OmniPvdCommandEnum::eOmniPvdDestroyObject: + case OmniPvdCommand::eDESTROY_OBJECT: { - mCmdType = OmniPvdCommandEnum::eOmniPvdDestroyObject; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); + cmdType = OmniPvdCommand::eDESTROY_OBJECT; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); mLog.outputLine("[parser] destroy object (contextHandle: %llu, objectHandle: %llu)\n", static_cast(mCmdContextHandle), static_cast(mCmdObjectHandle)); } break; - case OmniPvdCommandEnum::eOmniPvdStartFrame: + case OmniPvdCommand::eSTART_FRAME: { - mCmdType = OmniPvdCommandEnum::eOmniPvdStartFrame; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdFrameTimeStart, sizeof(uint64_t)); + cmdType = OmniPvdCommand::eSTART_FRAME; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdFrameTimeStart, sizeof(uint64_t)); mLog.outputLine("[parser] start frame (contextHandle: %llu, timeStamp: %llu)\n", static_cast(mCmdContextHandle), static_cast(mCmdFrameTimeStart)); } break; - case OmniPvdCommandEnum::eOmniPvdStopFrame: + case OmniPvdCommand::eSTOP_FRAME: { - mCmdType = OmniPvdCommandEnum::eOmniPvdStopFrame; - mStream->readBytes((unsigned char*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); - mStream->readBytes((unsigned char*)&mCmdFrameTimeStop, sizeof(uint64_t)); + cmdType = OmniPvdCommand::eSTOP_FRAME; + mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); + mStream->readBytes((uint8_t*)&mCmdFrameTimeStop, sizeof(uint64_t)); mLog.outputLine("[parser] stop frame (contextHandle: %llu, timeStamp: %llu)\n", static_cast(mCmdContextHandle), static_cast(mCmdFrameTimeStop)); } break; @@ -292,22 +301,17 @@ OmniPvdCommandEnum::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getNextCommand() } break; } - return mCmdType; + return cmdType; } else { - return mCmdType; + return cmdType; } } else { - return mCmdType; + return cmdType; } } -OmniPvdCommandEnum::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getCommandType() -{ - return mCmdType; -} - uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getMajorVersion() { return mCmdMajorVersion; @@ -346,23 +350,23 @@ uint64_t OMNI_PVD_CALL OmniPvdReaderImpl::getObjectHandle() { return mCmdObjectHandle; } -char* OMNI_PVD_CALL OmniPvdReaderImpl::getClassName() { +const char* OMNI_PVD_CALL OmniPvdReaderImpl::getClassName() { return mCmdClassName; } -char* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeName() { +const char* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeName() { return mCmdAttributeName; } -char* OMNI_PVD_CALL OmniPvdReaderImpl::getObjectName() { +const char* OMNI_PVD_CALL OmniPvdReaderImpl::getObjectName() { return mCmdObjectName; } -uint8_t* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataPointer() { +const uint8_t* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataPointer() { return mCmdAttributeDataPtr; } -uint16_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataType() { +OmniPvdDataType::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataType() { return mCmdAttributeDataType; } @@ -371,7 +375,7 @@ uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataLength() { } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeNumberElements() { - return mCmdAttributeNbrFields; + return mCmdAttributeNbElements; } OmniPvdClassHandle OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeClassHandle() { diff --git a/physx/pvdruntime/src/OmniPvdReaderImpl.h b/physx/pvdruntime/src/OmniPvdReaderImpl.h index ebeb85ac3..2fa65c2f8 100644 --- a/physx/pvdruntime/src/OmniPvdReaderImpl.h +++ b/physx/pvdruntime/src/OmniPvdReaderImpl.h @@ -38,10 +38,9 @@ class OmniPvdReaderImpl : public OmniPvdReader { ~OmniPvdReaderImpl(); void OMNI_PVD_CALL setLogFunction(OmniPvdLogFunction logFunction); - void OMNI_PVD_CALL setReadStream(OmniPvdReadStream* stream); - bool OMNI_PVD_CALL startReading(OmniPvdVersionType* majorVersion, OmniPvdVersionType* minorVersion, OmniPvdVersionType* patch); - OmniPvdCommandEnum::Enum OMNI_PVD_CALL getNextCommand(); - OmniPvdCommandEnum::Enum OMNI_PVD_CALL getCommandType(); + void OMNI_PVD_CALL setReadStream(OmniPvdReadStream& stream); + bool OMNI_PVD_CALL startReading(OmniPvdVersionType& majorVersion, OmniPvdVersionType& minorVersion, OmniPvdVersionType& patch); + OmniPvdCommand::Enum OMNI_PVD_CALL getNextCommand(); OmniPvdVersionType OMNI_PVD_CALL getMajorVersion(); OmniPvdVersionType OMNI_PVD_CALL getMinorVersion(); @@ -54,12 +53,12 @@ class OmniPvdReaderImpl : public OmniPvdReader { OmniPvdClassHandle OMNI_PVD_CALL getBaseClassHandle(); OmniPvdAttributeHandle OMNI_PVD_CALL getAttributeHandle(); - char* OMNI_PVD_CALL getClassName(); - char* OMNI_PVD_CALL getAttributeName(); - char* OMNI_PVD_CALL getObjectName(); + const char* OMNI_PVD_CALL getClassName(); + const char* OMNI_PVD_CALL getAttributeName(); + const char* OMNI_PVD_CALL getObjectName(); - uint8_t* OMNI_PVD_CALL getAttributeDataPointer(); - OmniPvdAttributeDataType OMNI_PVD_CALL getAttributeDataType(); + const uint8_t* OMNI_PVD_CALL getAttributeDataPointer(); + OmniPvdDataType::Enum OMNI_PVD_CALL getAttributeDataType(); uint32_t OMNI_PVD_CALL getAttributeDataLength(); uint32_t OMNI_PVD_CALL getAttributeNumberElements(); OmniPvdClassHandle OMNI_PVD_CALL getAttributeClassHandle(); @@ -84,8 +83,6 @@ class OmniPvdReaderImpl : public OmniPvdReader { OmniPvdVersionType mMinorVersion; OmniPvdVersionType mPatch; - OmniPvdCommandEnum::Enum mCmdType; - OmniPvdVersionType mCmdMajorVersion; OmniPvdVersionType mCmdMinorVersion; OmniPvdVersionType mCmdPatch; @@ -109,9 +106,9 @@ class OmniPvdReaderImpl : public OmniPvdReader { uint16_t mCmdObjectNameLen; uint8_t* mCmdAttributeDataPtr; - OmniPvdAttributeDataType mCmdAttributeDataType; + OmniPvdDataType::Enum mCmdAttributeDataType; uint32_t mCmdAttributeDataLen; - uint32_t mCmdAttributeNbrFields; + uint32_t mCmdAttributeNbElements; uint32_t mCmdEnumValue; OmniPvdClassHandle mCmdEnumClassHandle; OmniPvdClassHandle mCmdAttributeClassHandle; diff --git a/physx/pvdruntime/src/OmniPvdWriterImpl.cpp b/physx/pvdruntime/src/OmniPvdWriterImpl.cpp index 4a5aa5776..330ca0a84 100644 --- a/physx/pvdruntime/src/OmniPvdWriterImpl.cpp +++ b/physx/pvdruntime/src/OmniPvdWriterImpl.cpp @@ -26,6 +26,7 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. +#include "OmniPvdDefinesInternal.h" #include "OmniPvdWriterImpl.h" #include "OmniPvdCommands.h" #include @@ -58,7 +59,7 @@ void OmniPvdWriterImpl::setVersionHelper() } } -void OmniPvdWriterImpl::setVersion(const OmniPvdVersionType majorVersion, const OmniPvdVersionType minorVersion, const OmniPvdVersionType patch) +void OmniPvdWriterImpl::setVersion(OmniPvdVersionType majorVersion, OmniPvdVersionType minorVersion, OmniPvdVersionType patch) { if (mStream && mIsFirstWrite) { @@ -66,9 +67,9 @@ void OmniPvdWriterImpl::setVersion(const OmniPvdVersionType majorVersion, const { return; } - mStream->writeBytes((unsigned char*)&majorVersion, sizeof(OmniPvdVersionType)); - mStream->writeBytes((unsigned char*)&minorVersion, sizeof(OmniPvdVersionType)); - mStream->writeBytes((unsigned char*)&patch, sizeof(OmniPvdVersionType)); + mStream->writeBytes((const uint8_t*)&majorVersion, sizeof(OmniPvdVersionType)); + mStream->writeBytes((const uint8_t*)&minorVersion, sizeof(OmniPvdVersionType)); + mStream->writeBytes((const uint8_t*)&patch, sizeof(OmniPvdVersionType)); mLog.outputLine("OmniPvdRuntimeWriterImpl::setVersion majorVersion(%lu), minorVersion(%lu), patch(%lu)", static_cast(majorVersion), static_cast(minorVersion), static_cast(patch)); @@ -76,10 +77,10 @@ void OmniPvdWriterImpl::setVersion(const OmniPvdVersionType majorVersion, const } } -void OMNI_PVD_CALL OmniPvdWriterImpl::setWriteStream(const OmniPvdWriteStream* stream) +void OMNI_PVD_CALL OmniPvdWriterImpl::setWriteStream(OmniPvdWriteStream& stream) { mLog.outputLine("OmniPvdRuntimeWriterImpl::setWriteStream"); - mStream = (OmniPvdWriteStream*)stream; + mStream = &stream; } OmniPvdWriteStream* OMNI_PVD_CALL OmniPvdWriterImpl::getWriteStream() @@ -87,6 +88,12 @@ OmniPvdWriteStream* OMNI_PVD_CALL OmniPvdWriterImpl::getWriteStream() return mStream; } +static void writeCommand(OmniPvdWriteStream& stream, OmniPvdCommand::Enum command) +{ + const OmniPvdCommandStorageType commandTmp = static_cast(command); + stream.writeBytes((const uint8_t*)&commandTmp, sizeof(OmniPvdCommandStorageType)); +} + OmniPvdClassHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerClass(const char* className, OmniPvdClassHandle baseClass) { setVersionHelper(); @@ -95,36 +102,40 @@ OmniPvdClassHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerClass(const char* cl mLog.outputLine("OmniPvdWriterImpl::registerClass className(%s)", className); int classNameLen = (int)strlen(className); - unsigned char command = OmniPvdCommandEnum::eOmniPvdRegisterClass; - mStream->writeBytes(&command, sizeof(uint8_t)); + writeCommand(*mStream, OmniPvdCommand::eREGISTER_CLASS); mLastClassHandle++; - mStream->writeBytes((unsigned char*)&mLastClassHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&baseClass, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&classNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)className, classNameLen); + mStream->writeBytes((const uint8_t*)&mLastClassHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&baseClass, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&classNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)className, classNameLen); return mLastClassHandle; } else { return 0; } } -OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdAttributeDataType attributeDataType, const uint32_t nbrFields) +static void writeDataType(OmniPvdWriteStream& stream, OmniPvdDataType::Enum attributeDataType) +{ + const OmniPvdDataTypeStorageType dataType = static_cast(attributeDataType); + stream.writeBytes((const uint8_t*)&dataType, sizeof(OmniPvdDataTypeStorageType)); +} + +OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdDataType::Enum attributeDataType, uint32_t nbElements) { setVersionHelper(); if (mStream) { - mLog.outputLine("OmniPvdWriterImpl::registerAttribute classHandle(%llu), attributeName(%s), attributeDataType(%d), nbrFields(%llu)", static_cast(classHandle), attributeName, static_cast(attributeDataType), static_cast(nbrFields)); + mLog.outputLine("OmniPvdWriterImpl::registerAttribute classHandle(%llu), attributeName(%s), attributeDataType(%d), nbrFields(%llu)", static_cast(classHandle), attributeName, static_cast(attributeDataType), static_cast(nbElements)); int attribNameLen = (int)strlen(attributeName); - unsigned char command = OmniPvdCommandEnum::eOmniPvdRegisterAttribute; - mStream->writeBytes(&command, sizeof(uint8_t)); + writeCommand(*mStream, OmniPvdCommand::eREGISTER_ATTRIBUTE); mLastAttributeHandle++; - mStream->writeBytes((unsigned char*)&classHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->writeBytes((unsigned char*)&attributeDataType, sizeof(OmniPvdAttributeDataType)); - mStream->writeBytes((unsigned char*)&nbrFields, sizeof(uint32_t)); - mStream->writeBytes((unsigned char*)&attribNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)attributeName, attribNameLen); + mStream->writeBytes((const uint8_t*)&classHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); + writeDataType(*mStream, attributeDataType); + mStream->writeBytes((const uint8_t*)&nbElements, sizeof(uint32_t)); + mStream->writeBytes((const uint8_t*)&attribNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)attributeName, attribNameLen); return mLastAttributeHandle; } else { @@ -132,7 +143,7 @@ OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerAttribute(const } } -OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerFlagsAttribute(const OmniPvdClassHandle classHandle, const OmniPvdClassHandle enumClassHandle, const char* attributeName) +OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerFlagsAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle enumClassHandle) { setVersionHelper(); if (mStream) { @@ -140,16 +151,14 @@ OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerFlagsAttribute(c mLog.outputLine("OmniPvdWriterImpl::registerFlagsAttribute classHandle(%llu), enumClassHandle(%llu), attributeName(%s)", static_cast(classHandle), static_cast(enumClassHandle), attributeName); int attribNameLen = (int)strlen(attributeName); - unsigned char command = OmniPvdCommandEnum::eOmniPvdRegisterAttribute; - const OmniPvdAttributeDataType attributeDataType = OmniPvdDataTypeEnum::eFLAGS_WORD; - mStream->writeBytes(&command, sizeof(uint8_t)); + writeCommand(*mStream, OmniPvdCommand::eREGISTER_ATTRIBUTE); mLastAttributeHandle++; - mStream->writeBytes((unsigned char*)&classHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->writeBytes((unsigned char*)&attributeDataType, sizeof(OmniPvdAttributeDataType)); - mStream->writeBytes((unsigned char*)&enumClassHandle, sizeof(uint32_t)); - mStream->writeBytes((unsigned char*)&attribNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)attributeName, attribNameLen); + mStream->writeBytes((const uint8_t*)&classHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); + writeDataType(*mStream, OmniPvdDataType::eFLAGS_WORD); + mStream->writeBytes((const uint8_t*)&enumClassHandle, sizeof(uint32_t)); + mStream->writeBytes((const uint8_t*)&attribNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)attributeName, attribNameLen); return mLastAttributeHandle; } else { @@ -157,21 +166,19 @@ OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerFlagsAttribute(c } } -OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerEnumValue(const OmniPvdClassHandle classHandle, const char* attributeName, uint32_t value) +OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerEnumValue(OmniPvdClassHandle classHandle, const char* attributeName, uint32_t value) { setVersionHelper(); if (mStream) { int attribNameLen = (int)strlen(attributeName); - unsigned char command = OmniPvdCommandEnum::eOmniPvdRegisterAttribute; - OmniPvdAttributeDataType attributeDataType = OmniPvdDataTypeEnum::eENUM_VALUE; - mStream->writeBytes(&command, sizeof(uint8_t)); + writeCommand(*mStream, OmniPvdCommand::eREGISTER_ATTRIBUTE); mLastAttributeHandle++; - mStream->writeBytes((unsigned char*)&classHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->writeBytes((unsigned char*)&attributeDataType, sizeof(OmniPvdAttributeDataType)); - mStream->writeBytes((unsigned char*)&value, sizeof(uint32_t)); - mStream->writeBytes((unsigned char*)&attribNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)attributeName, attribNameLen); + mStream->writeBytes((const uint8_t*)&classHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); + writeDataType(*mStream, OmniPvdDataType::eENUM_VALUE); + mStream->writeBytes((const uint8_t*)&value, sizeof(uint32_t)); + mStream->writeBytes((const uint8_t*)&attribNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)attributeName, attribNameLen); return mLastAttributeHandle; } else { @@ -179,20 +186,19 @@ OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerEnumValue(const } } -OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerClassAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle classAttributeHandle) +OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerClassAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle classAttributeHandle) { setVersionHelper(); if (mStream) { int attribNameLen = (int)strlen(attributeName); - unsigned char command = OmniPvdCommandEnum::eOmniPvdRegisterClassAttribute; - mStream->writeBytes(&command, sizeof(uint8_t)); + writeCommand(*mStream, OmniPvdCommand::eREGISTER_CLASS_ATTRIBUTE); mLastAttributeHandle++; - mStream->writeBytes((unsigned char*)&classHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->writeBytes((unsigned char*)&classAttributeHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&attribNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)attributeName, attribNameLen); + mStream->writeBytes((const uint8_t*)&classHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); + mStream->writeBytes((const uint8_t*)&classAttributeHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&attribNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)attributeName, attribNameLen); return mLastAttributeHandle; } else { @@ -200,20 +206,19 @@ OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerClassAttribute(c } } -OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerSetAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdAttributeDataType attributeDataType) +OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerUniqueListAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdDataType::Enum attributeDataType) { setVersionHelper(); if (mStream) { int attribNameLen = (int)strlen(attributeName); - unsigned char command = OmniPvdCommandEnum::eOmniPvdRegisterSetAttribute; - mStream->writeBytes(&command, sizeof(uint8_t)); + writeCommand(*mStream, OmniPvdCommand::eREGISTER_UNIQUE_LIST_ATTRIBUTE); mLastAttributeHandle++; - mStream->writeBytes((unsigned char*)&classHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); - mStream->writeBytes((unsigned char*)&attributeDataType, sizeof(OmniPvdAttributeDataType)); - mStream->writeBytes((unsigned char*)&attribNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)attributeName, attribNameLen); + mStream->writeBytes((const uint8_t*)&classHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&mLastAttributeHandle, sizeof(OmniPvdAttributeHandle)); + writeDataType(*mStream, attributeDataType); + mStream->writeBytes((const uint8_t*)&attribNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)attributeName, attribNameLen); return mLastAttributeHandle; } else @@ -222,140 +227,115 @@ OmniPvdAttributeHandle OMNI_PVD_CALL OmniPvdWriterImpl::registerSetAttribute(con } } -void OMNI_PVD_CALL OmniPvdWriterImpl::setAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes) +void OMNI_PVD_CALL OmniPvdWriterImpl::setAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdSetAttribute; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&objectHandle, sizeof(OmniPvdObjectHandle)); - mStream->writeBytes((unsigned char*)&handleDepth, sizeof(uint8_t)); - for (int i = 0; i < handleDepth; i++) + writeCommand(*mStream, OmniPvdCommand::eSET_ATTRIBUTE); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&objectHandle, sizeof(OmniPvdObjectHandle)); + mStream->writeBytes((const uint8_t*)&nbAttributeHandles, sizeof(uint8_t)); + for (int i = 0; i < nbAttributeHandles; i++) { - mStream->writeBytes((unsigned char*)attributeHandles, sizeof(OmniPvdAttributeHandle)); + mStream->writeBytes((const uint8_t*)attributeHandles, sizeof(OmniPvdAttributeHandle)); attributeHandles++; } - mStream->writeBytes((unsigned char*)&nbrBytes, sizeof(uint32_t)); - mStream->writeBytes((unsigned char*)data, nbrBytes); + mStream->writeBytes((const uint8_t*)&nbrBytes, sizeof(uint32_t)); + mStream->writeBytes((const uint8_t*)data, nbrBytes); } } -void OMNI_PVD_CALL OmniPvdWriterImpl::setAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t *data, const uint32_t nbrBytes) -{ - const uint8_t handleDepth = 1; - setAttribute(contextHandle, objectHandle, handleDepth, &attributeHandle, data, nbrBytes); -} - -void OMNI_PVD_CALL OmniPvdWriterImpl::addToSetAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes) +void OMNI_PVD_CALL OmniPvdWriterImpl::addToUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdAddToSetAttribute; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&objectHandle, sizeof(OmniPvdObjectHandle)); - mStream->writeBytes((unsigned char*)&handleDepth, sizeof(uint8_t)); - for (int i = 0; i < handleDepth; i++) + writeCommand(*mStream, OmniPvdCommand::eADD_TO_UNIQUE_LIST_ATTRIBUTE); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&objectHandle, sizeof(OmniPvdObjectHandle)); + mStream->writeBytes((const uint8_t*)&nbAttributeHandles, sizeof(uint8_t)); + for (int i = 0; i < nbAttributeHandles; i++) { - mStream->writeBytes((unsigned char*)attributeHandles, sizeof(OmniPvdAttributeHandle)); + mStream->writeBytes((const uint8_t*)attributeHandles, sizeof(OmniPvdAttributeHandle)); attributeHandles++; } - mStream->writeBytes((unsigned char*)&nbrBytes, sizeof(uint32_t)); - mStream->writeBytes((unsigned char*)data, nbrBytes); + mStream->writeBytes((const uint8_t*)&nbrBytes, sizeof(uint32_t)); + mStream->writeBytes((const uint8_t*)data, nbrBytes); } } -void OMNI_PVD_CALL OmniPvdWriterImpl::addToSetAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t* data, const uint32_t nbrBytes) -{ - const uint8_t handleDepth = 1; - addToSetAttribute(contextHandle, objectHandle, handleDepth, &attributeHandle, data, nbrBytes); -} - -void OMNI_PVD_CALL OmniPvdWriterImpl::removeFromSetAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes) +void OMNI_PVD_CALL OmniPvdWriterImpl::removeFromUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdRemoveFromSetAttribute; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&objectHandle, sizeof(OmniPvdObjectHandle)); - mStream->writeBytes((unsigned char*)&handleDepth, sizeof(uint8_t)); - for (int i = 0; i < handleDepth; i++) + writeCommand(*mStream, OmniPvdCommand::eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&objectHandle, sizeof(OmniPvdObjectHandle)); + mStream->writeBytes((const uint8_t*)&nbAttributeHandles, sizeof(uint8_t)); + for (int i = 0; i < nbAttributeHandles; i++) { - mStream->writeBytes((unsigned char*)attributeHandles, sizeof(OmniPvdAttributeHandle)); + mStream->writeBytes((const uint8_t*)attributeHandles, sizeof(OmniPvdAttributeHandle)); attributeHandles++; } - mStream->writeBytes((unsigned char*)&nbrBytes, sizeof(uint32_t)); - mStream->writeBytes((unsigned char*)data, nbrBytes); + mStream->writeBytes((const uint8_t*)&nbrBytes, sizeof(uint32_t)); + mStream->writeBytes((const uint8_t*)data, nbrBytes); } } -void OMNI_PVD_CALL OmniPvdWriterImpl::removeFromSetAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t* data, const uint32_t nbrBytes) -{ - const uint8_t handleDepth = 1; - removeFromSetAttribute(contextHandle, objectHandle, handleDepth, &attributeHandle, data, nbrBytes); -} - -void OMNI_PVD_CALL OmniPvdWriterImpl::createObject(const OmniPvdContextHandle contextHandle, const OmniPvdClassHandle classHandle, const OmniPvdObjectHandle objectHandle, const char* objectName) +void OMNI_PVD_CALL OmniPvdWriterImpl::createObject(OmniPvdContextHandle contextHandle, OmniPvdClassHandle classHandle, OmniPvdObjectHandle objectHandle, const char* objectName) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdCreateObject; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&classHandle, sizeof(OmniPvdClassHandle)); - mStream->writeBytes((unsigned char*)&objectHandle, sizeof(OmniPvdObjectHandle)); + writeCommand(*mStream, OmniPvdCommand::eCREATE_OBJECT); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&classHandle, sizeof(OmniPvdClassHandle)); + mStream->writeBytes((const uint8_t*)&objectHandle, sizeof(OmniPvdObjectHandle)); int objectNameLen = 0; if (objectName) { objectNameLen = (int)strlen(objectName); - mStream->writeBytes((unsigned char*)&objectNameLen, sizeof(uint16_t)); - mStream->writeBytes((unsigned char*)objectName, objectNameLen); + mStream->writeBytes((const uint8_t*)&objectNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)objectName, objectNameLen); } else { - mStream->writeBytes((unsigned char*)&objectNameLen, sizeof(uint16_t)); + mStream->writeBytes((const uint8_t*)&objectNameLen, sizeof(uint16_t)); } } } -void OMNI_PVD_CALL OmniPvdWriterImpl::destroyObject(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle) +void OMNI_PVD_CALL OmniPvdWriterImpl::destroyObject(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdDestroyObject; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&objectHandle, sizeof(OmniPvdObjectHandle)); + writeCommand(*mStream, OmniPvdCommand::eDESTROY_OBJECT); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&objectHandle, sizeof(OmniPvdObjectHandle)); } } -void OMNI_PVD_CALL OmniPvdWriterImpl::startFrame(const OmniPvdContextHandle contextHandle, const uint64_t timeStamp) +void OMNI_PVD_CALL OmniPvdWriterImpl::startFrame(OmniPvdContextHandle contextHandle, uint64_t timeStamp) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdStartFrame; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&timeStamp, sizeof(uint64_t)); + writeCommand(*mStream, OmniPvdCommand::eSTART_FRAME); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&timeStamp, sizeof(uint64_t)); } } -void OMNI_PVD_CALL OmniPvdWriterImpl::stopFrame(const OmniPvdContextHandle contextHandle, const uint64_t timeStamp) +void OMNI_PVD_CALL OmniPvdWriterImpl::stopFrame(OmniPvdContextHandle contextHandle, uint64_t timeStamp) { setVersionHelper(); if (mStream) { - unsigned char command = OmniPvdCommandEnum::eOmniPvdStopFrame; - mStream->writeBytes(&command, sizeof(uint8_t)); - mStream->writeBytes((unsigned char*)&contextHandle, sizeof(OmniPvdContextHandle)); - mStream->writeBytes((unsigned char*)&timeStamp, sizeof(uint64_t)); + writeCommand(*mStream, OmniPvdCommand::eSTOP_FRAME); + mStream->writeBytes((const uint8_t*)&contextHandle, sizeof(OmniPvdContextHandle)); + mStream->writeBytes((const uint8_t*)&timeStamp, sizeof(uint64_t)); } } diff --git a/physx/pvdruntime/src/OmniPvdWriterImpl.h b/physx/pvdruntime/src/OmniPvdWriterImpl.h index e575facfc..88143a41d 100644 --- a/physx/pvdruntime/src/OmniPvdWriterImpl.h +++ b/physx/pvdruntime/src/OmniPvdWriterImpl.h @@ -38,33 +38,30 @@ class OmniPvdWriterImpl : public OmniPvdWriter { ~OmniPvdWriterImpl(); void OMNI_PVD_CALL setLogFunction(OmniPvdLogFunction logFunction); void setVersionHelper(); - void setVersion(const OmniPvdVersionType majorVersion, const OmniPvdVersionType minorVersion, const OmniPvdVersionType patch); - void OMNI_PVD_CALL setWriteStream(const OmniPvdWriteStream* stream); + void setVersion(OmniPvdVersionType majorVersion, OmniPvdVersionType minorVersion, OmniPvdVersionType patch); + void OMNI_PVD_CALL setWriteStream(OmniPvdWriteStream& stream); OmniPvdWriteStream* OMNI_PVD_CALL getWriteStream(); OmniPvdClassHandle OMNI_PVD_CALL registerClass(const char* className, OmniPvdClassHandle baseClass); - OmniPvdAttributeHandle OMNI_PVD_CALL registerEnumValue(const OmniPvdClassHandle classHandle, const char* attributeName, const uint32_t value); - OmniPvdAttributeHandle OMNI_PVD_CALL registerAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdAttributeDataType attributeDataType, const uint32_t nbrFields); - OmniPvdAttributeHandle OMNI_PVD_CALL registerFlagsAttribute(const OmniPvdClassHandle classHandle, const OmniPvdClassHandle enumClassHandle, const char* attributeName); - OmniPvdAttributeHandle OMNI_PVD_CALL registerClassAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdClassHandle classAttributeHandle); - OmniPvdAttributeHandle OMNI_PVD_CALL registerSetAttribute(const OmniPvdClassHandle classHandle, const char* attributeName, const OmniPvdAttributeDataType attributeDataType); - void OMNI_PVD_CALL setAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes); - void OMNI_PVD_CALL setAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t *data, const uint32_t nbrBytes); + OmniPvdAttributeHandle OMNI_PVD_CALL registerEnumValue(OmniPvdClassHandle classHandle, const char* attributeName, uint32_t value); + OmniPvdAttributeHandle OMNI_PVD_CALL registerAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdDataType::Enum attributeDataType, uint32_t nbElements); + OmniPvdAttributeHandle OMNI_PVD_CALL registerFlagsAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle enumClassHandle); + OmniPvdAttributeHandle OMNI_PVD_CALL registerClassAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdClassHandle classAttributeHandle); + OmniPvdAttributeHandle OMNI_PVD_CALL registerUniqueListAttribute(OmniPvdClassHandle classHandle, const char* attributeName, OmniPvdDataType::Enum attributeDataType); + void OMNI_PVD_CALL setAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes); - void OMNI_PVD_CALL addToSetAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes); - void OMNI_PVD_CALL addToSetAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t* data, const uint32_t nbrBytes); + void OMNI_PVD_CALL addToUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes); - void OMNI_PVD_CALL removeFromSetAttribute(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const uint8_t handleDepth, const OmniPvdAttributeHandle* attributeHandles, const uint8_t* data, const uint32_t nbrBytes); - void OMNI_PVD_CALL removeFromSetAttributeShallow(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle attributeHandle, const uint8_t* data, const uint32_t nbrBytes); + void OMNI_PVD_CALL removeFromUniqueListAttribute(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle, const OmniPvdAttributeHandle* attributeHandles, uint8_t nbAttributeHandles, const uint8_t* data, uint32_t nbrBytes); - void OMNI_PVD_CALL createObject(const OmniPvdContextHandle contextHandle, const OmniPvdClassHandle classHandle, const OmniPvdObjectHandle objectHandle, const char* objectName); - void OMNI_PVD_CALL destroyObject(const OmniPvdContextHandle contextHandle, const OmniPvdObjectHandle objectHandle); - void OMNI_PVD_CALL startFrame(const OmniPvdContextHandle contextHandle, const uint64_t timeStamp); - void OMNI_PVD_CALL stopFrame(const OmniPvdContextHandle contextHandle, const uint64_t timeStamp); + void OMNI_PVD_CALL createObject(OmniPvdContextHandle contextHandle, OmniPvdClassHandle classHandle, OmniPvdObjectHandle objectHandle, const char* objectName); + void OMNI_PVD_CALL destroyObject(OmniPvdContextHandle contextHandle, OmniPvdObjectHandle objectHandle); + void OMNI_PVD_CALL startFrame(OmniPvdContextHandle contextHandle, uint64_t timeStamp); + void OMNI_PVD_CALL stopFrame(OmniPvdContextHandle contextHandle, uint64_t timeStamp); bool mIsFirstWrite; OmniPvdLog mLog; - OmniPvdWriteStream *mStream; + OmniPvdWriteStream* mStream; int mLastClassHandle; int mLastAttributeHandle;}; diff --git a/physx/snippets/compiler/cmake/CMakeLists.txt b/physx/snippets/compiler/cmake/CMakeLists.txt index ed9a6837f..fdbe35f54 100644 --- a/physx/snippets/compiler/cmake/CMakeLists.txt +++ b/physx/snippets/compiler/cmake/CMakeLists.txt @@ -27,20 +27,6 @@ cmake_minimum_required(VERSION 3.7) project(Snippets C CXX) -IF(NOT DEFINED CMAKEMODULES_VERSION) - SET(CMAKEMODULES_PATH $ENV{PM_CMakeModules_PATH} CACHE INTERNAL "Path to CMakeModules") - SET(CMAKEMODULES_NAME $ENV{PM_CMakeModules_NAME} CACHE INTERNAL "CMakeModules name") - SET(CMAKEMODULES_VERSION $ENV{PM_CMakeModules_VERSION} CACHE INTERNAL "CMakeModules version from generation batch") - - #TODO: More elegance - IF(NOT EXISTS ${CMAKEMODULES_PATH}) - MESSAGE(FATAL_ERROR "Could not find ${CMAKEMODULES_PATH}") - ENDIF() - -ENDIF() - -SET(CMAKE_MODULE_PATH ${CMAKEMODULES_PATH}) - # This is required to be defined by external callers! IF(NOT DEFINED PHYSX_ROOT_DIR) MESSAGE(FATAL_ERROR "PHYSX_ROOT_DIR variable wasn't set.") @@ -91,16 +77,16 @@ LIST(APPEND SNIPPETS_LIST ${PLATFORM_SNIPPETS_LIST}) # These are separate because we don't ship CUDA in the public release yet. # To be changed if we decide otherwise. SET(GPU_SNIPPET_LIST - HelloGRB SoftBody SoftBodyAttachment SDF PBF PBFMultiMat PBDCloth PBDInflatable) + HelloGRB SoftBody SoftBodyAttachment KinematicSoftBody SDF PBF PBFMultiMat PBDCloth PBDInflatable Isosurface) -# Add snippets of GPU features that are under development OR require PhysXGpuExtensions +# Add snippets of GPU features that are under development IF(NOT PUBLIC_RELEASE AND NOT PX_GENERATE_SOURCE_DISTRO) LIST(APPEND GPU_SNIPPET_LIST - BigHairSystem FLIPFluid HairSystem MPM Isosurface) + BigHairSystem FLIPFluid HairSystem MPM) ENDIF() #TODO, create a propper define for whether GPU features are enabled or not! -IF ((PUBLIC_RELEASE OR PX_GENERATE_GPU_PROJECTS) AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) +IF ((PUBLIC_RELEASE OR PX_GENERATE_GPU_PROJECTS) AND (NOT CMAKE_CROSSCOMPILING)) LIST(APPEND SNIPPETS_LIST ${GPU_SNIPPET_LIST}) ENDIF() diff --git a/physx/snippets/compiler/cmake/SnippetRender.cmake b/physx/snippets/compiler/cmake/SnippetRender.cmake index 162a82368..f20aa3264 100644 --- a/physx/snippets/compiler/cmake/SnippetRender.cmake +++ b/physx/snippets/compiler/cmake/SnippetRender.cmake @@ -54,12 +54,12 @@ TARGET_INCLUDE_DIRECTORIES(SnippetRender PUBLIC ${SNIPPETRENDER_PLATFORM_INCLUDES} ) -TARGET_COMPILE_DEFINITIONS(SnippetRender +TARGET_COMPILE_DEFINITIONS(SnippetRender PRIVATE ${SNIPPETRENDER_COMPILE_DEFS} ) IF(NV_USE_GAMEWORKS_OUTPUT_DIRS) - SET_TARGET_PROPERTIES(SnippetRender PROPERTIES + SET_TARGET_PROPERTIES(SnippetRender PROPERTIES COMPILE_PDB_NAME_DEBUG "SnippetRender_static_${CMAKE_DEBUG_POSTFIX}" COMPILE_PDB_NAME_CHECKED "SnippetRender_static_${CMAKE_CHECKED_POSTFIX}" COMPILE_PDB_NAME_PROFILE "SnippetRender_static_${CMAKE_PROFILE_POSTFIX}" @@ -71,7 +71,7 @@ IF(NV_USE_GAMEWORKS_OUTPUT_DIRS) ARCHIVE_OUTPUT_NAME_RELEASE "SnippetRender_static" ) ELSE() - SET_TARGET_PROPERTIES(SnippetRender PROPERTIES + SET_TARGET_PROPERTIES(SnippetRender PROPERTIES COMPILE_PDB_NAME_DEBUG "SnippetRender${CMAKE_DEBUG_POSTFIX}" COMPILE_PDB_NAME_CHECKED "SnippetRender${CMAKE_CHECKED_POSTFIX}" COMPILE_PDB_NAME_PROFILE "SnippetRender${CMAKE_PROFILE_POSTFIX}" @@ -79,12 +79,12 @@ ELSE() ) ENDIF() - -TARGET_LINK_LIBRARIES(SnippetRender +TARGET_LINK_LIBRARIES(SnippetRender PUBLIC PhysXFoundation - PUBLIC ${SNIPPETRENDER_PLATFORM_LINKED_LIBS}) + PUBLIC ${SNIPPETRENDER_PLATFORM_LINKED_LIBS} +) IF(PX_GENERATE_SOURCE_DISTRO) - LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPETRENDER_FILES}) + LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPETRENDER_FILES}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPETRENDER_PLATFORM_FILES}) ENDIF() diff --git a/physx/snippets/compiler/cmake/SnippetTemplate.cmake b/physx/snippets/compiler/cmake/SnippetTemplate.cmake index 2e3c8a33b..37e20c275 100644 --- a/physx/snippets/compiler/cmake/SnippetTemplate.cmake +++ b/physx/snippets/compiler/cmake/SnippetTemplate.cmake @@ -47,7 +47,6 @@ TARGET_INCLUDE_DIRECTORIES(Snippet${SNIPPET_NAME} PRIVATE ${PHYSX_ROOT_DIR}/include/ PRIVATE ${PHYSX_ROOT_DIR}/source/physxextensions/src - PRIVATE ${PHYSX_ROOT_DIR}/source/physxgpuextensions/src ) TARGET_COMPILE_DEFINITIONS(Snippet${SNIPPET_NAME} diff --git a/physx/snippets/compiler/cmake/linux/SnippetRender.cmake b/physx/snippets/compiler/cmake/linux/SnippetRender.cmake index 9d8c4bfc5..03357a8af 100644 --- a/physx/snippets/compiler/cmake/linux/SnippetRender.cmake +++ b/physx/snippets/compiler/cmake/linux/SnippetRender.cmake @@ -29,10 +29,7 @@ # IF(NOT ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") - find_package(OpenGL $ENV{PM_OpenGL_VERSION} CONFIG REQUIRED) # Pull in OpenGL and GLUT -ENDIF() -IF(NOT PUBLIC_RELEASE) - find_package(CUDA $ENV{PM_CUDA_Version} REQUIRED) + FIND_PACKAGE(OpenGL $ENV{PM_OpenGL_VERSION} CONFIG REQUIRED) # Pull in OpenGL and GLUT ENDIF() SET(SNIPPETRENDER_COMPILE_DEFS @@ -46,17 +43,6 @@ SET(SNIPPETRENDER_COMPILE_DEFS $<$:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};> ) -# vreutskyy: copied from SdkUnitTest.cmake -# preist@: FIND_PACKAGE will not find the fallback stub/libcuda.so in case that the -# machine does not have graphics drivers installed (that come with libcuda.so) -# and linking will fail. So use stub fallback explicitly here: -IF(NOT PUBLIC_RELEASE) - IF(${CUDA_CUDA_LIBRARY} STREQUAL "CUDA_CUDA_LIBRARY-NOTFOUND") - find_library(CUDA_CUDA_LIBRARY cuda PATHS ${CUDA_TOOLKIT_TARGET_DIR}/lib64/stubs) - ENDIF() - SET(CUDA_LIBS ${CUDA_CUDA_LIBRARY}) -ENDIF() - SET(SNIPPETRENDER_PLATFORM_INCLUDES) # gwoolery: aarch64 requires glut library to be lower case, for whatever reason @@ -69,6 +55,6 @@ ENDIF() SET(SNIPPETRENDER_PLATFORM_LINKED_LIBS GL GLU ${GLUT_LIB}) IF(NOT PUBLIC_RELEASE) - LIST(APPEND SNIPPETRENDER_PLATFORM_INCLUDES ${CUDA_INCLUDE_DIRS}) - LIST(APPEND SNIPPETRENDER_PLATFORM_LINKED_LIBS ${CUDA_LIBS}) + LIST(APPEND SNIPPETRENDER_PLATFORM_INCLUDES ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) + LIST(APPEND SNIPPETRENDER_PLATFORM_LINKED_LIBS CUDA::cuda_driver) ENDIF() diff --git a/physx/snippets/compiler/cmake/linux/SnippetTemplate.cmake b/physx/snippets/compiler/cmake/linux/SnippetTemplate.cmake index 256fe46d8..08a04541c 100644 --- a/physx/snippets/compiler/cmake/linux/SnippetTemplate.cmake +++ b/physx/snippets/compiler/cmake/linux/SnippetTemplate.cmake @@ -65,10 +65,6 @@ ENDIF() SET(SNIPPET_PLATFORM_LINKED_LIBS SnippetRender GL GLU ${GLUT_LIB} X11 rt pthread dl -Wl,-rpath='${ORIGIN}') -IF(NOT PUBLIC_RELEASE) - LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS PhysXGPUExtensions) -ENDIF() - IF(PX_GENERATE_GPU_STATIC_LIBRARIES) LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS PhysXGpu) diff --git a/physx/snippets/compiler/cmake/windows/SnippetRender.cmake b/physx/snippets/compiler/cmake/windows/SnippetRender.cmake index 625a6a9ec..5f53611cc 100644 --- a/physx/snippets/compiler/cmake/windows/SnippetRender.cmake +++ b/physx/snippets/compiler/cmake/windows/SnippetRender.cmake @@ -28,10 +28,6 @@ # Build SnippetRender # -IF(NOT PUBLIC_RELEASE) - FIND_PACKAGE(CUDA $ENV{PM_CUDA_Version} REQUIRED) -ENDIF() - IF(NOT FREEGLUT_PATH) SET(FREEGLUT_PATH $ENV{PM_freeglut_PATH} CACHE INTERNAL "Freeglut package path") ENDIF() @@ -54,7 +50,7 @@ SET(SNIPPETRENDER_PLATFORM_INCLUDES ${FREEGLUT_PATH}/include) SET(SNIPPETRENDER_PLATFORM_LINKED_LIBS opengl32.lib glu32.lib) IF(NOT PUBLIC_RELEASE) - LIST(APPEND SNIPPETRENDER_PLATFORM_INCLUDES ${CUDA_INCLUDE_DIRS}) - LIST(APPEND SNIPPETRENDER_PLATFORM_LINKED_LIBS ${CUDA_CUDA_LIBRARY}) + LIST(APPEND SNIPPETRENDER_PLATFORM_INCLUDES ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) + LIST(APPEND SNIPPETRENDER_PLATFORM_LINKED_LIBS CUDA::cuda_driver) ENDIF() diff --git a/physx/snippets/compiler/cmake/windows/SnippetTemplate.cmake b/physx/snippets/compiler/cmake/windows/SnippetTemplate.cmake index 0a9d8a492..f3d71306f 100644 --- a/physx/snippets/compiler/cmake/windows/SnippetTemplate.cmake +++ b/physx/snippets/compiler/cmake/windows/SnippetTemplate.cmake @@ -50,7 +50,7 @@ SET(SNIPPET_PLATFORM_SOURCES ) SET(SNIPPET_PLATFORM_INCLUDES - #adding PhysXGpu include for configs that don't add link target PhysXGpu + #adding PhysXGpu include for configs that don't add link target PhysXGpu ${PHYSX_ROOT_DIR}/include/cudamanager ${FREEGLUT_PATH}/include ) @@ -73,12 +73,6 @@ ELSE() ) ENDIF() -IF(NOT PUBLIC_RELEASE AND CMAKE_SIZEOF_VOID_P EQUAL 8) - LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS - PhysXGPUExtensions - ) -ENDIF() - IF(${SNIPPET_NAME} STREQUAL "ArticulationLoader") LIST(APPEND SNIPPET_PLATFORM_SOURCES ${TINYXML2_PATH}/tinyxml2.h @@ -97,8 +91,4 @@ ENDIF() IF(PX_GENERATE_GPU_STATIC_LIBRARIES) LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS PhysXGpu) - - IF(NOT PUBLIC_RELEASE) - LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS ${CUDA_CUDA_LIBRARY}) - ENDIF() ENDIF() diff --git a/physx/snippets/media/vehicledata/Base.json b/physx/snippets/media/vehicledata/Base.json index 35165c7d8..606c92a33 100644 --- a/physx/snippets/media/vehicledata/Base.json +++ b/physx/snippets/media/vehicledata/Base.json @@ -105,7 +105,7 @@ "WheelId": 1, "SuspensionAttachment": { "Pos": [ - 0.7558199763298035, + 0.7952629923820496, -0.10795000195503235, 1.269219994544983 ], @@ -528,7 +528,7 @@ "WheelId": 2, "HalfWidth": 0.15768450498580934, "Radius": 0.3432520031929016, - "Mass": 30.0, + "Mass": 20.0, "MOI": 1.1716899871826172, "DampingRate": 0.25 }, @@ -536,7 +536,7 @@ "WheelId": 3, "HalfWidth": 0.15768450498580934, "Radius": 0.3432520031929016, - "Mass": 30.0, + "Mass": 20.0, "MOI": 1.1716899871826172, "DampingRate": 0.25 } diff --git a/physx/snippets/snippetarticulationrc/SnippetArticulation.cpp b/physx/snippets/snippetarticulationrc/SnippetArticulation.cpp index de25e9b49..d4df85160 100644 --- a/physx/snippets/snippetarticulationrc/SnippetArticulation.cpp +++ b/physx/snippets/snippetarticulationrc/SnippetArticulation.cpp @@ -104,8 +104,8 @@ static void createScissorLift() gDriveJoint = static_cast(rightRoot->getInboundJoint()); gDriveJoint->setJointType(PxArticulationJointType::ePRISMATIC); gDriveJoint->setMotion(PxArticulationAxis::eZ, PxArticulationMotion::eLIMITED); - gDriveJoint->setLimit(PxArticulationAxis::eZ, -1.4f, 0.2f); - gDriveJoint->setDrive(PxArticulationAxis::eZ, 100000.f, 0.f, PX_MAX_F32); + gDriveJoint->setLimitParams(PxArticulationAxis::eZ, PxArticulationLimit(-1.4f, 0.2f)); + gDriveJoint->setDriveParams(PxArticulationAxis::eZ, PxArticulationDrive(100000.f, 0.f, PX_MAX_F32)); gDriveJoint->setParentPose(PxTransform(PxVec3(0.f, 0.25f, 0.9f))); gDriveJoint->setChildPose(PxTransform(PxVec3(0.f, -0.05f, 0.f))); @@ -133,7 +133,7 @@ static void createScissorLift() leftParentRot = leftRot; joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED); - joint->setLimit(PxArticulationAxis::eTWIST, -PxPi, angle); + joint->setLimitParams(PxArticulationAxis::eTWIST, PxArticulationLimit(-PxPi, angle)); PxArticulationLink* rightLink = gArticulation->createLink(currRight, PxTransform(pos + PxVec3(0.f, sinAng*(2 * i + 1), 0.f), rightRot)); @@ -147,7 +147,7 @@ static void createScissorLift() joint->setParentPose(PxTransform(currRight->getGlobalPose().transformInv(rightAnchorLocation), rightParentRot)); joint->setChildPose(PxTransform(PxVec3(0.f, 0.f, 1.f), leftRot)); joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED); - joint->setLimit(PxArticulationAxis::eTWIST, -angle, PxPi); + joint->setLimitParams(PxArticulationAxis::eTWIST, PxArticulationLimit(-angle, PxPi)); rightParentRot = rightRot; @@ -176,14 +176,12 @@ static void createScissorLift() joint->setChildPose(PxTransform(PxVec3(0.5f, 0.f, 0.f), leftTop->getGlobalPose().q.getConjugate())); joint->setJointType(PxArticulationJointType::eREVOLUTE); joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eFREE); - //joint->setDrive(PxArticulationAxis::eTWIST, 0.f, 10.f, PX_MAX_F32); joint = static_cast(rightTop->getInboundJoint()); joint->setParentPose(PxTransform(PxVec3(0.f, 0.f, 1.f), currRight->getGlobalPose().q.getConjugate())); joint->setChildPose(PxTransform(PxVec3(0.5f, 0.f, 0.f), rightTop->getGlobalPose().q.getConjugate())); joint->setJointType(PxArticulationJointType::eREVOLUTE); joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eFREE); - //joint->setDrive(PxArticulationAxis::eTWIST, 0.f, 10.f, PX_MAX_F32); currLeft = leftRoot; @@ -209,7 +207,7 @@ static void createScissorLift() leftParentRot = leftRot; joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED); - joint->setLimit(PxArticulationAxis::eTWIST, -PxPi, angle); + joint->setLimitParams(PxArticulationAxis::eTWIST, PxArticulationLimit(-PxPi, angle)); PxArticulationLink* rightLink = gArticulation->createLink(currRight, PxTransform(pos + PxVec3(0.f, sinAng*(2 * i + 1), 0.f), rightRot)); PxRigidActorExt::createExclusiveShape(*rightLink, PxBoxGeometry(0.05f, 0.05f, 1.f), *gMaterial); @@ -225,7 +223,7 @@ static void createScissorLift() joint->setJointType(PxArticulationJointType::eREVOLUTE); joint->setChildPose(PxTransform(PxVec3(0.f, 0.f, 1.f), leftRot)); joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED); - joint->setLimit(PxArticulationAxis::eTWIST, -angle, PxPi); + joint->setLimitParams(PxArticulationAxis::eTWIST, PxArticulationLimit(-angle, PxPi)); rightParentRot = rightRot; diff --git a/physx/snippets/snippetcustomconvex/CustomConvex.cpp b/physx/snippets/snippetcustomconvex/CustomConvex.cpp index 5336b8d04..d50a29033 100644 --- a/physx/snippets/snippetcustomconvex/CustomConvex.cpp +++ b/physx/snippets/snippetcustomconvex/CustomConvex.cpp @@ -101,7 +101,7 @@ bool CustomConvex::generateContacts(const PxGeometry& geom0, const PxGeometry& g { PxContactBuffer* contactBuffer; ContactRecorder(PxContactBuffer& _contactBuffer) : contactBuffer(&_contactBuffer) {} - virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 /*index*/) + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 /*index*/) { for (PxU32 i = 0; i < nbContacts; ++i) contactBuffer->contact(contactPoints[i]); diff --git a/physx/snippets/snippetcustomgeometry/VoxelMap.cpp b/physx/snippets/snippetcustomgeometry/VoxelMap.cpp index 3548bd90e..2ad29225e 100644 --- a/physx/snippets/snippetcustomgeometry/VoxelMap.cpp +++ b/physx/snippets/snippetcustomgeometry/VoxelMap.cpp @@ -214,7 +214,7 @@ bool VoxelMap::generateContacts(const PxGeometry& /*geom0*/, const PxGeometry& g { PxContactBuffer* contactBuffer; ContactRecorder(PxContactBuffer& _contactBuffer) : contactBuffer(&_contactBuffer) {} - virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 /*index*/) + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 /*index*/) { for (PxU32 i = 0; i < nbContacts; ++i) contactBuffer->contact(contactPoints[i]); diff --git a/physx/snippets/snippetcustomgeometrycollision/SnippetCustomGeometryCollision.cpp b/physx/snippets/snippetcustomgeometrycollision/SnippetCustomGeometryCollision.cpp index 6975057aa..19e4c7977 100644 --- a/physx/snippets/snippetcustomgeometrycollision/SnippetCustomGeometryCollision.cpp +++ b/physx/snippets/snippetcustomgeometrycollision/SnippetCustomGeometryCollision.cpp @@ -67,7 +67,7 @@ struct CheckerBoard : PxCustomGeometry::Callbacks { PxContactBuffer* contactBuffer; ContactRecorder(PxContactBuffer& _contactBuffer) : contactBuffer(&_contactBuffer) {} - virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 /*index*/) + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 /*index*/) { for (PxU32 i = 0; i < nbContacts; ++i) if (!contactBuffer->contact(contactPoints[i])) diff --git a/physx/snippets/snippetcustomjoint/PulleyJoint.cpp b/physx/snippets/snippetcustomjoint/PulleyJoint.cpp index 369b02bc2..f7352dca4 100644 --- a/physx/snippets/snippetcustomjoint/PulleyJoint.cpp +++ b/physx/snippets/snippetcustomjoint/PulleyJoint.cpp @@ -91,17 +91,6 @@ static PxU32 solverPrep(Px1DConstraint* constraints, return 1; } -static void project(const void* constantBlock, - PxTransform& bodyAToWorld, - PxTransform& bodyBToWorld, - bool projectToA) -{ - PX_UNUSED(constantBlock); - PX_UNUSED(bodyAToWorld); - PX_UNUSED(bodyBToWorld); - PX_UNUSED(projectToA); -} - static void visualize( PxConstraintVisualizer& viz, const void* constantBlock, const PxTransform& body0Transform, @@ -117,7 +106,7 @@ static void visualize( PxConstraintVisualizer& viz, viz.visualizeJointFrames(PxTransform(data.attachment0), PxTransform(data.attachment1)); } -static PxConstraintShaderTable sShaderTable = { solverPrep, project, visualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable sShaderTable = { solverPrep, visualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep PulleyJoint::getPrep() const { return solverPrep; } diff --git a/physx/snippets/snippetdelayloadhook/SnippetDelayLoadHook.cpp b/physx/snippets/snippetdelayloadhook/SnippetDelayLoadHook.cpp index f358ffb39..2a2a153da 100644 --- a/physx/snippets/snippetdelayloadhook/SnippetDelayLoadHook.cpp +++ b/physx/snippets/snippetdelayloadhook/SnippetDelayLoadHook.cpp @@ -134,7 +134,7 @@ bool loadPhysicsExplicitely() // get the function pointers s_PxCreateFoundation_Func = (PxCreateFoundation_FUNC*)GetProcAddress(foundationLibrary, "PxCreateFoundation"); - s_PxCreatePhysics_Func = (PxCreatePhysics_FUNC*)GetProcAddress(physxLibrary, "PxCreateBasePhysics"); + s_PxCreatePhysics_Func = (PxCreatePhysics_FUNC*)GetProcAddress(physxLibrary, "PxCreatePhysics"); s_PxSetPhysXDelayLoadHook_Func = (PxSetPhysXDelayLoadHook_FUNC*)GetProcAddress(physxLibrary, "PxSetPhysXDelayLoadHook"); s_PxSetPhysXCommonDelayLoadHook_Func = (PxSetPhysXCommonDelayLoadHook_FUNC*)GetProcAddress(commonLibrary, "PxSetPhysXCommonDelayLoadHook"); diff --git a/physx/snippets/snippetgeometryquery/SnippetGeometryQueryRender.cpp b/physx/snippets/snippetgeometryquery/SnippetGeometryQueryRender.cpp index c542666d9..1b5b67712 100644 --- a/physx/snippets/snippetgeometryquery/SnippetGeometryQueryRender.cpp +++ b/physx/snippets/snippetgeometryquery/SnippetGeometryQueryRender.cpp @@ -56,9 +56,9 @@ void renderCallback() static float time = 0.0f; time += 0.003f; - const PxQuat qx = SnippetUtils::getRotXQuat(time); - const PxQuat qy = SnippetUtils::getRotYQuat(time*1.7f); - const PxQuat qz = SnippetUtils::getRotZQuat(time*1.33f); + const PxQuat qx = PxGetRotXQuat(time); + const PxQuat qy = PxGetRotYQuat(time*1.7f); + const PxQuat qz = PxGetRotZQuat(time*1.33f); const PxTransform pose(PxVec3(0.0f), qx*qy*qz); diff --git a/physx/snippets/snippethellogrb/SnippetHelloGRBRender.cpp b/physx/snippets/snippethellogrb/SnippetHelloGRBRender.cpp index efebbbe6d..10f9bebff 100644 --- a/physx/snippets/snippethellogrb/SnippetHelloGRBRender.cpp +++ b/physx/snippets/snippethellogrb/SnippetHelloGRBRender.cpp @@ -73,9 +73,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -88,8 +85,6 @@ void renderLoop() initPhysics(true); glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetimmediatearticulation/SnippetImmediateArticulation.cpp b/physx/snippets/snippetimmediatearticulation/SnippetImmediateArticulation.cpp index a0e076b07..6ece4f040 100644 --- a/physx/snippets/snippetimmediatearticulation/SnippetImmediateArticulation.cpp +++ b/physx/snippets/snippetimmediatearticulation/SnippetImmediateArticulation.cpp @@ -31,13 +31,17 @@ // **************************************************************************** #include "PxImmediateMode.h" +#include "PxMaterial.h" #include "geometry/PxGeometryQuery.h" +#include "geometry/PxConvexMesh.h" #include "foundation/PxPhysicsVersion.h" #include "foundation/PxArray.h" #include "foundation/PxHashSet.h" #include "foundation/PxHashMap.h" #include "foundation/PxMathUtils.h" #include "foundation/PxFPU.h" +#include "cooking/PxCooking.h" +#include "cooking/PxConvexMeshDesc.h" #include "ExtConstraintHelper.h" #include "extensions/PxMassProperties.h" #include "extensions/PxDefaultAllocator.h" @@ -93,6 +97,7 @@ static bool gPause = false; static bool gOneFrame = false; static bool gDrawBounds = false; static PxU32 gSceneIndex = 2; +static float gTime = 0.0f; #if WITH_PERSISTENCY struct PersistentContactPair @@ -359,6 +364,7 @@ void ImmediateScene::reset() mNbStaticActors = mNbArticulationLinks = 0; mMotorLinkCookie = PxCreateArticulationLinkCookie(); mMotorLink = PxArticulationLinkHandle(); + gTime = 0.0f; } PxU32 ImmediateScene::createActor(const PxGeometry& geometry, const PxTransform& pose, const MassProps* massProps, PxArticulationLinkCookie* linkCookie) @@ -1124,13 +1130,70 @@ void ImmediateScene::createScene() } } - endCreateImmediateArticulation(immArt); allocateTempBuffer(mMaxNumArticulationsLinks); createGroundPlane(); } + else if(index==6) + { + //const float scaleFactor = 0.25f; + const float scaleFactor = 1.0f; + const float halfHeight = 1.0f*scaleFactor; + const float radius = 1.0f*scaleFactor; + const PxU32 nbCirclePts = 20; + const PxU32 totalNbVerts = nbCirclePts*2; + PxVec3 verts[totalNbVerts]; + const float step = 3.14159f*2.0f/float(nbCirclePts); + for(PxU32 i=0;i::Entry* e = mPersistentPairs.find(IDS(i, j)); - if(e) - { - PersistentContactPair& persistentData = const_cast(e->second); - //No collision detection performed at all so clear contact cache and friction data - persistentData.reset(); - } + //No collision detection performed at all so clear contact cache and friction data + mPersistentPairs.erase(IDS(i, j)); } #endif } @@ -1215,7 +1273,7 @@ void ImmediateScene::narrowPhase() public: ContactRecorder(ImmediateScene* scene, PxU32 id0, PxU32 id1) : mScene(scene), mID0(id0), mID1(id1), mHasContacts(false) {} - virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 /*index*/) + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 /*index*/) { { ImmediateScene::ContactPair pair; @@ -1236,7 +1294,7 @@ void ImmediateScene::narrowPhase() point.staticFriction = gStaticFriction; point.dynamicFriction = gDynamicFriction; point.restitution = gRestitution; - point.materialFlags = 0; + point.materialFlags = PxMaterialFlag::eIMPROVED_PATCH_FRICTION; mScene->mContactPoints.pushBack(point); } return true; @@ -1431,11 +1489,10 @@ static PxU32 SphericalJointSolverPrep(Px1DConstraint* constraints, { const MyJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; Ext::joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); - if(cB2w.q.dot(cA2w.q)<0.0f) - cB2w.q = -cB2w.q; + Ext::joint::applyNeighborhoodOperator(cA2w, cB2w); /* if(data.jointFlags & PxSphericalJointFlag::eLIMIT_ENABLED) { @@ -1882,7 +1939,6 @@ void ImmediateScene::solveAndIntegrate(float dt) mActors[i].mLinearVelocity = data.linearVelocity; mActors[i].mAngularVelocity = data.angularVelocity; } - #else PxIntegrateSolverBodies(mSolverBodyData.begin(), mSolverBodies.begin(), mMotionLinearVelocity.begin(), mMotionAngularVelocity.begin(), nbDynamicActors, dt); for (PxU32 i = 0; icreateScene(); } @@ -2093,9 +2147,8 @@ void stepPhysics(bool /*interactive*/) if(gScene->mMotorLink.articulation) { - static float time = 0.0f; - time += 0.1f; - const float target = sinf(time) * 4.0f; + gTime += 0.1f; + const float target = sinf(gTime) * 4.0f; // printf("target: %f\n", target); PxArticulationJointDataRC data; @@ -2105,7 +2158,7 @@ void stepPhysics(bool /*interactive*/) data.targetVel[PxArticulationAxis::eTWIST] = target; const PxVec3 boxExtents(0.5f, 0.1f, 0.5f); - const float s = boxExtents.x*1.1f + fabsf(sinf(time))*0.5f; + const float s = boxExtents.x*1.1f + fabsf(sinf(gTime))*0.5f; data.parentPose = PxTransform(PxVec3(0.0f, 0.0f, s)); data.childPose = PxTransform(PxVec3(0.0f, 0.0f, -s)); @@ -2141,7 +2194,7 @@ void keyPress(unsigned char key, const PxTransform& /*camera*/) if(gScene) { - if(key>=1 && key<=6) + if(key>=1 && key<=7) { gSceneIndex = key-1; gScene->reset(); @@ -2159,7 +2212,7 @@ void keyPress(unsigned char key, const PxTransform& /*camera*/) void renderText() { #ifdef RENDER_SNIPPET - Snippets::print("Press F1 to F6 to select a scene."); + Snippets::print("Press F1 to F7 to select a scene."); #endif } diff --git a/physx/snippets/snippetimmediatemode/SnippetImmediateMode.cpp b/physx/snippets/snippetimmediatemode/SnippetImmediateMode.cpp index 88c8187a4..46f24e0c3 100644 --- a/physx/snippets/snippetimmediatemode/SnippetImmediateMode.cpp +++ b/physx/snippets/snippetimmediatemode/SnippetImmediateMode.cpp @@ -175,7 +175,7 @@ class TestContactRecorder : public immediate::PxContactRecorder { } - virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 index) + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 index) { PX_UNUSED(index); { diff --git a/physx/snippets/snippetisosurface/SnippetIsosurface.cpp b/physx/snippets/snippetisosurface/SnippetIsosurface.cpp new file mode 100644 index 000000000..49c5b7395 --- /dev/null +++ b/physx/snippets/snippetisosurface/SnippetIsosurface.cpp @@ -0,0 +1,501 @@ +// 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. + +// **************************************************************************** +// This snippet illustrates isosurface extraction from particle-based fluid +// simulation. The fluid simulation is performed using position-based dynamics. +// +// **************************************************************************** + +#include +#include "PxPhysicsAPI.h" +#include "../snippetcommon/SnippetPrint.h" +#include "../snippetcommon/SnippetPVD.h" +#include "../snippetutils/SnippetUtils.h" + +#include "extensions/PxParticleExt.h" +#include "PxIsosurfaceExtraction.h" +#include "PxAnisotropy.h" +#include "PxSmoothing.h" + +#include "gpu/PxGpu.h" +#include "gpu/PxPhysicsGpu.h" +#include "PxArrayConverter.h" + +using namespace physx; + +static PxDefaultAllocator gAllocator; +static PxDefaultErrorCallback gErrorCallback; +static PxFoundation* gFoundation = NULL; +static PxPhysics* gPhysics = NULL; +static PxDefaultCpuDispatcher* gDispatcher = NULL; +static PxScene* gScene = NULL; +static PxMaterial* gMaterial = NULL; +static PxPvd* gPvd = NULL; +static PxPBDParticleSystem* gParticleSystem = NULL; +static PxParticleBuffer* gParticleBuffer = NULL; +static bool gIsRunning = true; + + +PxRigidDynamic* movingWall; + +using namespace ExtGpu; + +PxArray gIsosurfaceVertices; +PxArray gIsosurfaceIndices; +PxArray gIsosurfaceNormals; +PxIsosurfaceExtractor* gIsosurfaceExtractor; +extern void* gVerticesGpu; +extern void* gNormalsGpu; +extern void* gInterleavedVerticesAndNormalsGpu; + +class IsosurfaceCallback : public PxParticleSystemCallback +{ +public: + PxIsosurfaceExtractor* mIsosurfaceExtractor; + PxAnisotropyGenerator* mAnisotropyGenerator; + PxSmoothedPositionGenerator* mSmoothedPositionGenerator; + PxArrayConverter* mArrayConverter; + PxVec4* mSmoothedPositionsDeviceBuffer; + + PxVec4* mAnisotropyDeviceBuffer1; + PxVec4* mAnisotropyDeviceBuffer2; + PxVec4* mAnisotropyDeviceBuffer3; + + PxU32 mMaxVertices; + PxCudaContextManager* mCudaContextManager; + + IsosurfaceCallback() : mIsosurfaceExtractor(NULL), mAnisotropyGenerator(NULL) { } + + void initialize(PxCudaContextManager* cudaContextManager, + const PxSparseGridParams& sparseGridParams, PxIsosurfaceParams& p, + PxU32 maxNumVertices, PxU32 maxNumTriangles, PxU32 maxNumParticles) + { + mCudaContextManager = cudaContextManager; + mMaxVertices = maxNumVertices; + /*ExtGpu::PxIsosurfaceParams p; + p.isosurfaceValue =threshold; + p.clearFilteringPasses();*/ + + PxPhysicsGpu* pxGpu = PxGetPhysicsGpu(); + + mSmoothedPositionGenerator = pxGpu->createSmoothedPositionGenerator(cudaContextManager, maxNumParticles, 0.5f); + PX_DEVICE_ALLOC(cudaContextManager, mSmoothedPositionsDeviceBuffer, maxNumParticles); + mSmoothedPositionGenerator->setResultBufferDevice(mSmoothedPositionsDeviceBuffer); + + //Too small minAnisotropy values will shrink particles to ellipsoids that are smaller than a isosurface grid cell which can lead to unpleasant aliasing/flickering + PxReal minAnisotropy = 1.0f;// 0.5f; // 0.1f; + PxReal anisotropyScale = 5.0f; + mAnisotropyGenerator = pxGpu->createAnisotropyGenerator(cudaContextManager, maxNumParticles, anisotropyScale, minAnisotropy, 2.0f); + PX_DEVICE_ALLOC(cudaContextManager, mAnisotropyDeviceBuffer1, maxNumParticles); + PX_DEVICE_ALLOC(cudaContextManager, mAnisotropyDeviceBuffer2, maxNumParticles); + PX_DEVICE_ALLOC(cudaContextManager, mAnisotropyDeviceBuffer3, maxNumParticles); + mAnisotropyGenerator->setResultBufferDevice(mAnisotropyDeviceBuffer1, mAnisotropyDeviceBuffer2, mAnisotropyDeviceBuffer3); + + gIsosurfaceVertices.resize(maxNumVertices); + gIsosurfaceNormals.resize(maxNumVertices); + gIsosurfaceIndices.resize(3 * maxNumTriangles); + + mIsosurfaceExtractor = pxGpu->createSparseGridIsosurfaceExtractor(cudaContextManager, sparseGridParams, p, maxNumParticles, maxNumVertices, maxNumTriangles); + + gIsosurfaceExtractor = mIsosurfaceExtractor; + mArrayConverter = pxGpu->createArrayConverter(cudaContextManager); + } + + virtual void onPostSolve(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) + { + PxGpuParticleSystem& p = *gpuParticleSystem.mHostPtr; + + if (mAnisotropyGenerator) + { + mAnisotropyGenerator->generateAnisotropy(gpuParticleSystem.mDevicePtr, p.mCommonData.mMaxParticles, stream); + } + + mSmoothedPositionGenerator->generateSmoothedPositions(gpuParticleSystem.mDevicePtr, p.mCommonData.mMaxParticles, stream); + + mIsosurfaceExtractor->extractIsosurface(mSmoothedPositionsDeviceBuffer/*reinterpret_cast(p.mUnsortedPositions_InvMass)*/, p.mCommonData.mNumParticles, stream, p.mUnsortedPhaseArray, PxParticlePhaseFlag::eParticlePhaseFluid, + NULL, mAnisotropyDeviceBuffer1, mAnisotropyDeviceBuffer2, mAnisotropyDeviceBuffer3, p.mCommonData.mParticleContactDistance); + + if (gInterleavedVerticesAndNormalsGpu) + { + //Bring the data into a form that is better suited for rendering + mArrayConverter->interleaveGpuBuffers(static_cast(gVerticesGpu), static_cast(gNormalsGpu), mMaxVertices, static_cast(gInterleavedVerticesAndNormalsGpu), stream); + } + } + + virtual void onBegin(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + virtual void onAdvance(const PxGpuMirroredPointer& /*gpuParticleSystem*/, CUstream /*stream*/) { } + + virtual ~IsosurfaceCallback() { } + + void release() + { + mIsosurfaceExtractor->release(); + PX_DELETE(mIsosurfaceExtractor); + + PX_DELETE(mArrayConverter); + + if (mAnisotropyGenerator) + { + mAnisotropyGenerator->release(); + mCudaContextManager->freeDeviceBuffer(mAnisotropyDeviceBuffer1); + mCudaContextManager->freeDeviceBuffer(mAnisotropyDeviceBuffer2); + mCudaContextManager->freeDeviceBuffer(mAnisotropyDeviceBuffer3); + } + if (mSmoothedPositionGenerator) + { + mSmoothedPositionGenerator->release(); + mCudaContextManager->freeDeviceBuffer(mSmoothedPositionsDeviceBuffer); + } + } +}; + +static IsosurfaceCallback gIsosuraceCallback; + +// ----------------------------------------------------------------------------------------------------------------- +static void initScene() +{ + PxCudaContextManager* cudaContextManager = NULL; + if (PxGetSuggestedCudaDeviceOrdinal(gFoundation->getErrorCallback()) >= 0) + { + // initialize CUDA + PxCudaContextManagerDesc cudaContextManagerDesc; + cudaContextManager = PxCreateCudaContextManager(*gFoundation, cudaContextManagerDesc, PxGetProfilerCallback()); + if (cudaContextManager && !cudaContextManager->contextIsValid()) + { + cudaContextManager->release(); + cudaContextManager = NULL; + } + } + if (cudaContextManager == NULL) + { + PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Failed to initialize CUDA!\n"); + } + + PxSceneDesc sceneDesc(gPhysics->getTolerancesScale()); + sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); + gDispatcher = PxDefaultCpuDispatcherCreate(2); + sceneDesc.cpuDispatcher = gDispatcher; + sceneDesc.filterShader = PxDefaultSimulationFilterShader; + sceneDesc.cudaContextManager = cudaContextManager; + sceneDesc.staticStructure = PxPruningStructureType::eDYNAMIC_AABB_TREE; + sceneDesc.flags |= PxSceneFlag::eENABLE_PCM; + sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS; + sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU; + sceneDesc.solverType = PxSolverType::eTGS; + gScene = gPhysics->createScene(sceneDesc); +} + +// ----------------------------------------------------------------------------------------------------------------- +static PxReal initParticles(const PxU32 numX, const PxU32 numY, const PxU32 numZ, const PxVec3& position = PxVec3(0, 0, 0), const PxReal particleSpacing = 0.2f, const PxReal fluidDensity = 1000.f) +{ + PxCudaContextManager* cudaContextManager = gScene->getCudaContextManager(); + if (cudaContextManager == NULL) + return -1; + + const PxU32 maxParticles = numX * numY * numZ; + + const PxReal fluidRestOffset = 0.5f * particleSpacing; + + // Material setup + PxPBDMaterial* defaultMat = gPhysics->createPBDMaterial(0.05f, 0.05f, 0.f, 0.001f, 0.5f, 0.005f, 0.01f, 0.f, 0.f); + + PxPBDParticleSystem *particleSystem = gPhysics->createPBDParticleSystem(*cudaContextManager, 96); + gParticleSystem = particleSystem; + + bool highCohesion = false; + if (highCohesion) + { + defaultMat->setViscosity(50.0f); + defaultMat->setSurfaceTension(0.f); + defaultMat->setCohesion(100.0f); + particleSystem->setSolverIterationCounts(20, 0); + } + else + { + defaultMat->setViscosity(0.001f); + defaultMat->setSurfaceTension(0.00704f); + defaultMat->setCohesion(0.704f); + defaultMat->setVorticityConfinement(10.f); + } + + // General particle system setting + + const PxReal restOffset = fluidRestOffset / 0.6f; + const PxReal solidRestOffset = restOffset; + const PxReal particleMass = fluidDensity * 1.333f * 3.14159f * particleSpacing * particleSpacing * particleSpacing; + particleSystem->setRestOffset(restOffset); + particleSystem->setContactOffset(restOffset + 0.01f); + particleSystem->setParticleContactOffset(fluidRestOffset / 0.6f); + particleSystem->setSolidRestOffset(solidRestOffset); + particleSystem->setFluidRestOffset(fluidRestOffset); + particleSystem->enableCCD(false); + particleSystem->setMaxVelocity(100.f); + + gScene->addActor(*particleSystem); + + + // Create particles and add them to the particle system + const PxU32 particlePhase = particleSystem->createPhase(defaultMat, PxParticlePhaseFlags(PxParticlePhaseFlag::eParticlePhaseFluid | PxParticlePhaseFlag::eParticlePhaseSelfCollide)); + + PxU32* phase = cudaContextManager->allocPinnedHostBuffer(maxParticles); + PxVec4* positionInvMass = cudaContextManager->allocPinnedHostBuffer(maxParticles); + PxVec4* velocity = cudaContextManager->allocPinnedHostBuffer(maxParticles); + + PxReal x = position.x; + PxReal y = position.y; + PxReal z = position.z; + + for (PxU32 i = 0; i < numX; ++i) + { + for (PxU32 j = 0; j < numY; ++j) + { + for (PxU32 k = 0; k < numZ; ++k) + { + const PxU32 index = i * (numY * numZ) + j * numZ + k; + + PxVec4 pos(x, y, z, 1.0f / particleMass); + phase[index] = particlePhase; + positionInvMass[index] = pos; + velocity[index] = PxVec4(0.0f); + + z += particleSpacing; + } + z = position.z; + y += particleSpacing; + } + y = position.y; + x += particleSpacing; + } + + ExtGpu::PxParticleBufferDesc bufferDesc; + bufferDesc.maxParticles = maxParticles; + bufferDesc.numActiveParticles = maxParticles; + + + bufferDesc.positions = positionInvMass; + bufferDesc.velocities = velocity; + bufferDesc.phases = phase; + + gParticleBuffer = physx::ExtGpu::PxCreateAndPopulateParticleBuffer(bufferDesc, cudaContextManager); + gParticleSystem->addParticleBuffer(gParticleBuffer); + + cudaContextManager->freePinnedHostBuffer(positionInvMass); + cudaContextManager->freePinnedHostBuffer(velocity); + cudaContextManager->freePinnedHostBuffer(phase); + + return particleSpacing; +} + +PxPBDParticleSystem* getParticleSystem() +{ + return gParticleSystem; +} + +PxParticleBuffer* getParticleBuffer() +{ + return gParticleBuffer; +} + +void addKinematicBox(PxVec3 boxSize, PxVec3 boxCenter) +{ + PxShape* shape = gPhysics->createShape(PxBoxGeometry(boxSize.x, boxSize.y, boxSize.z), *gMaterial); + PxRigidDynamic* body = gPhysics->createRigidDynamic(PxTransform(boxCenter)); + body->attachShape(*shape); + body->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true); + gScene->addActor(*body); + shape->release(); +} + +// ----------------------------------------------------------------------------------------------------------------- +void initPhysics(bool /*interactive*/) +{ + gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback); + + gPvd = PxCreatePvd(*gFoundation); + PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10); + gPvd->connect(*transport, PxPvdInstrumentationFlag::eALL); + + gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd); + + initScene(); + + PxPvdSceneClient* pvdClient = gScene->getScenePvdClient(); + if (pvdClient) + { + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true); + } + gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f); + + // Setup PBF + bool useMovingWall = true; + + const PxReal fluidDensity = 1000.0f; + + PxU32 numX = 50; + PxU32 numY = 200; + PxU32 numZ = 100; + PxReal particleSpacing = initParticles(numX, numY, numZ, PxVec3(1.5f, /*3.f*/8, -4.f), 0.1f, fluidDensity); + + addKinematicBox(PxVec3(7.5f,0.25f,7.5f), PxVec3(3,7.5f,0)); + addKinematicBox(PxVec3(0.25f, 7.5f, 7.5f), PxVec3(-2.f, 7.5f+ 7.5f+0.5f, 0)); + + // Setup container + gScene->addActor(*PxCreatePlane(*gPhysics, PxPlane(0.f, 1.f, 0.f, 0.0f), *gMaterial)); + gScene->addActor(*PxCreatePlane(*gPhysics, PxPlane(-1.f, 0.f, 0.f, 7.5f), *gMaterial)); + gScene->addActor(*PxCreatePlane(*gPhysics, PxPlane(0.f, 0.f, 1.f, 7.5f), *gMaterial)); + gScene->addActor(*PxCreatePlane(*gPhysics, PxPlane(0.f, 0.f, -1.f, 7.5f), *gMaterial)); + + if (!useMovingWall) + { + gScene->addActor(*PxCreatePlane(*gPhysics, PxPlane(1.f, 0.f, 0.f, 7.5f), *gMaterial)); + movingWall = NULL; + } + else + { + PxTransform trans = PxTransformFromPlaneEquation(PxPlane(1.f, 0.f, 0.f, 20.f)); + movingWall = gPhysics->createRigidDynamic(trans); + movingWall->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true); + PxRigidActorExt::createExclusiveShape(*movingWall, PxPlaneGeometry(), *gMaterial); + gScene->addActor(*movingWall); + } + + const PxReal fluidRestOffset = 0.5f * particleSpacing; + + PxSparseGridParams sgIsosurfaceParams; + sgIsosurfaceParams.subgridSizeX = 16; + sgIsosurfaceParams.subgridSizeY = 16; + sgIsosurfaceParams.subgridSizeZ = 16; + sgIsosurfaceParams.haloSize = 0; + sgIsosurfaceParams.maxNumSubgrids = 4096; + sgIsosurfaceParams.gridSpacing = 1.5f*fluidRestOffset; + + PxIsosurfaceParams p; + p.particleCenterToIsosurfaceDistance = 1.6f*fluidRestOffset; + p.clearFilteringPasses(); + p.numMeshSmoothingPasses = 4; + p.numMeshNormalSmoothingPasses = 4; + + gIsosuraceCallback.initialize(gScene->getCudaContextManager(), sgIsosurfaceParams, p, 2*1024 * 1024, 4*1024 * 1024, numX * numY * numZ); + gParticleSystem->setParticleSystemCallback(&gIsosuraceCallback); + + // Setup rigid bodies + const PxReal dynamicsDensity = fluidDensity * 0.5f; + const PxReal boxSize = 1.0f; + const PxReal boxMass = boxSize * boxSize * boxSize * dynamicsDensity; + PxShape* shape = gPhysics->createShape(PxBoxGeometry(0.5f * boxSize, 0.5f * boxSize, 0.5f * boxSize), *gMaterial); + for (int i = 0; i < 5; ++i) + { + PxRigidDynamic* body = gPhysics->createRigidDynamic(PxTransform(PxVec3(i - 8.0f, 10, 7.5f))); + body->attachShape(*shape); + PxRigidBodyExt::updateMassAndInertia(*body, boxMass); + gScene->addActor(*body); + } + shape->release(); +} + +// --------------------------------------------------- +PxI32 stepCounter = 0; +void stepPhysics(bool /*interactive*/) +{ + if (gIsRunning) + { + const PxReal dt = 1.0f / 60.0f; + + if (movingWall) + { + static bool moveOut = false; + const PxReal speed = stepCounter > 1200 ? 2.0f : 0.0f; + PxTransform pose = movingWall->getGlobalPose(); + if (moveOut) + { + pose.p.x += dt * speed; + if (pose.p.x > -7.f) + moveOut = false; + } + else + { + pose.p.x -= dt * speed; + if (pose.p.x < -11.5f) + moveOut = true; + } + movingWall->setKinematicTarget(pose); + } + + gScene->simulate(dt); + gScene->fetchResults(true); + gScene->fetchResultsParticleSystem(); + ++stepCounter; + } +} + +void cleanupPhysics(bool /*interactive*/) +{ + gParticleSystem->setParticleSystemCallback(NULL); + gIsosuraceCallback.release(); + + PX_RELEASE(gScene); + PX_RELEASE(gDispatcher); + PX_RELEASE(gPhysics); + if(gPvd) + { + PxPvdTransport* transport = gPvd->getTransport(); + gPvd->release(); gPvd = NULL; + PX_RELEASE(transport); + } + PX_RELEASE(gFoundation); + + printf("SnippetIsosurface done.\n"); +} + +void keyPress(unsigned char key, const PxTransform& /*camera*/) +{ + switch(toupper(key)) + { + case 'P': gIsRunning = !gIsRunning; break; + } +} + +int snippetMain(int, const char*const*) +{ +#ifdef RENDER_SNIPPET + extern void renderLoop(); + renderLoop(); +#else + static const PxU32 frameCount = 100; + initPhysics(false); + for(PxU32 i=0; i + +#include "PxPhysicsAPI.h" +#include "cudamanager/PxCudaContext.h" +#include "cudamanager/PxCudaContextManager.h" + +#include "../snippetrender/SnippetRender.h" +#include "../snippetrender/SnippetCamera.h" + +#include "PxIsosurfaceExtraction.h" +#include "foundation/PxArray.h" + +#define CUDA_SUCCESS 0 +#define SHOW_SOLID_SDF_SLICE 0 +#define IDX(i, j, k, offset) ((i) + dimX * ((j) + dimY * ((k) + dimZ * (offset)))) +using namespace physx; + +extern void initPhysics(bool interactive); +extern void stepPhysics(bool interactive); +extern void cleanupPhysics(bool interactive); +extern void keyPress(unsigned char key, const PxTransform& camera); +extern PxPBDParticleSystem* getParticleSystem(); +extern PxParticleBuffer* getParticleBuffer(); + + +#if PX_SUPPORT_GPU_PHYSX +extern PxArray gIsosurfaceVertices; +extern PxArray gIsosurfaceIndices; +extern PxArray gIsosurfaceNormals; +extern PxIsosurfaceExtractor* gIsosurfaceExtractor; +void* gVerticesGpu; +void* gNormalsGpu; +void* gInterleavedVerticesAndNormalsGpu; +#endif + +namespace +{ + Snippets::Camera* sCamera; + +#if PX_SUPPORT_GPU_PHYSX + +#if USE_CUDA_INTEROP + bool directGpuRendering = true; +#else + bool directGpuRendering = false; +#endif + + Snippets::SharedGLBuffer sPosBuffer; + Snippets::SharedGLBuffer sNormalBuffer; + Snippets::SharedGLBuffer sTriangleBuffer; + Snippets::SharedGLBuffer sInterleavedPosNormalBuffer; + Snippets::SharedGLBuffer sParticlePosBuffer; + + void onBeforeRenderParticles() + { + PxPBDParticleSystem* particleSystem = getParticleSystem(); + if (particleSystem) + { + PxParticleBuffer* userBuffer = getParticleBuffer(); + PxVec4* positions = userBuffer->getPositionInvMasses(); + + const PxU32 numParticles = userBuffer->getNbActiveParticles(); + + PxScene* scene; + PxGetPhysics().getScenes(&scene, 1); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); + + cudaContextManager->acquireContext(); + + PxCudaContext* cudaContext = cudaContextManager->getCudaContext(); + cudaContext->memcpyDtoH(sParticlePosBuffer.map(), CUdeviceptr(positions), sizeof(PxVec4) * numParticles); + + cudaContextManager->releaseContext(); + } + } + + void renderParticles() + { + sParticlePosBuffer.unmap(); + sPosBuffer.unmap(); + sNormalBuffer.unmap(); + sTriangleBuffer.unmap(); + if (directGpuRendering) + { + PxVec3 color(0.5f, 0.5f, 1); + Snippets::DrawMeshIndexed(sInterleavedPosNormalBuffer.vbo, sTriangleBuffer.vbo, gIsosurfaceExtractor->getNumTriangles(), color); + + //PxVec3 particleColor(1.0f, 1.0f, 0.0f); + //Snippets::DrawPoints(sParticlePosBuffer.vbo, sParticlePosBuffer.size / sizeof(PxVec4), particleColor, 2.f); + } + else + { + //Draw a triangle mesh where the data gets copied to the host and back to the device for rendering + Snippets::renderMesh(gIsosurfaceExtractor->getNumVertices(), gIsosurfaceVertices.begin(), gIsosurfaceExtractor->getNumTriangles(), + gIsosurfaceIndices.begin(), PxVec3(1, 0, 0), gIsosurfaceNormals.begin()); + + //Check for unused vertices + PxVec4 marker(10000000, 0, 0, 0); + PxU32 numIndices = 3 * gIsosurfaceExtractor->getNumTriangles(); + for (PxU32 i = 0; i < numIndices; ++i) + { + gIsosurfaceNormals[gIsosurfaceIndices[i]] = marker; + } + for (PxU32 i = 0; i < gIsosurfaceExtractor->getNumVertices(); ++i) + { + if (gIsosurfaceNormals[i] != marker) + { + printf("Isosurface mesh contains unreferenced vertices\n"); + } + } + } + + Snippets::DrawFrame(PxVec3(0, 0, 0)); + } + + void allocParticleBuffers() + { + PxScene* scene; + PxGetPhysics().getScenes(&scene, 1); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); + + //PxPBDParticleSystem* particleSystem = getParticleSystem(); + PxU32 maxVertices = gIsosurfaceExtractor->getMaxVertices(); + PxU32 maxIndices = gIsosurfaceExtractor->getMaxTriangles() * 3; + + sParticlePosBuffer.initialize(cudaContextManager); + sParticlePosBuffer.allocate(gIsosurfaceExtractor->getMaxParticles() * sizeof(PxVec4)); + + sPosBuffer.initialize(cudaContextManager); + sPosBuffer.allocate(maxVertices * sizeof(PxVec4)); + gVerticesGpu = sPosBuffer.map(); + sNormalBuffer.initialize(cudaContextManager); + sNormalBuffer.allocate(maxVertices * sizeof(PxVec4)); + gNormalsGpu = sNormalBuffer.map(); + sTriangleBuffer.initialize(cudaContextManager); + sTriangleBuffer.allocate(maxIndices * sizeof(PxU32)); + + sInterleavedPosNormalBuffer.initialize(cudaContextManager); + sInterleavedPosNormalBuffer.allocate(2 * maxVertices * sizeof(PxVec3)); + gInterleavedVerticesAndNormalsGpu = sInterleavedPosNormalBuffer.map(); + + if (directGpuRendering) + { + gIsosurfaceExtractor->setResultBufferDevice(reinterpret_cast(sPosBuffer.map()), + reinterpret_cast(sTriangleBuffer.map()), reinterpret_cast(sNormalBuffer.map())); + } + else + { + gIsosurfaceExtractor->setResultBufferHost(gIsosurfaceVertices.begin(), gIsosurfaceIndices.begin(), gIsosurfaceNormals.begin()); + gInterleavedVerticesAndNormalsGpu = NULL; + } + } + + void clearupParticleBuffers() + { + sParticlePosBuffer.release(); + sPosBuffer.release(); + sNormalBuffer.release(); + sTriangleBuffer.release(); + sInterleavedPosNormalBuffer.release(); + } +#else + void onBeforeRenderParticles() + { + } + + void renderParticles() + { + } + + void allocParticleBuffers() + { + } + + void clearupParticleBuffers() + { + } +#endif + + void renderCallback() + { + onBeforeRenderParticles(); + + stepPhysics(true); + + Snippets::startRender(sCamera); + + PxScene* scene; + PxGetPhysics().getScenes(&scene, 1); + PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC); + if (nbActors) + { + std::vector actors(nbActors); + scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast(&actors[0]), nbActors); + Snippets::renderActors(&actors[0], static_cast(actors.size()), true); + } + + renderParticles(); + + Snippets::showFPS(); + + Snippets::finishRender(); + } + + void cleanup() + { + gIsosurfaceVertices.reset(); + gIsosurfaceIndices.reset(); + gIsosurfaceNormals.reset(); + + delete sCamera; + clearupParticleBuffers(); + cleanupPhysics(true); + } + + void exitCallback(void) + { + + } +} + + +void renderLoop() +{ + sCamera = new Snippets::Camera(PxVec3(15.0f, 10.0f, 15.0f), PxVec3(-0.6f, -0.2f, -0.6f)); + + Snippets::setupDefault("PhysX Snippet Isosurface", sCamera, keyPress, renderCallback, exitCallback); + + initPhysics(true); + Snippets::initFPS(); + + allocParticleBuffers(); + + glutMainLoop(); + + cleanup(); +} +#endif diff --git a/physx/snippets/snippetjoint/SnippetJoint.cpp b/physx/snippets/snippetjoint/SnippetJoint.cpp index 8bcecc0a2..fa36a36ba 100644 --- a/physx/snippets/snippetjoint/SnippetJoint.cpp +++ b/physx/snippets/snippetjoint/SnippetJoint.cpp @@ -63,7 +63,7 @@ static PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geo static PxJoint* createLimitedSpherical(PxRigidActor* a0, const PxTransform& t0, PxRigidActor* a1, const PxTransform& t1) { PxSphericalJoint* j = PxSphericalJointCreate(*gPhysics, a0, t0, a1, t1); - j->setLimitCone(PxJointLimitCone(PxPi/4, PxPi/4, 0.05f)); + j->setLimitCone(PxJointLimitCone(PxPi/4, PxPi/4)); j->setSphericalJointFlag(PxSphericalJointFlag::eLIMIT_ENABLED, true); return j; } diff --git a/physx/snippets/snippetjointdrive/SnippetJointDrive.cpp b/physx/snippets/snippetjointdrive/SnippetJointDrive.cpp index d1440df3b..4d50a7584 100644 --- a/physx/snippets/snippetjointdrive/SnippetJointDrive.cpp +++ b/physx/snippets/snippetjointdrive/SnippetJointDrive.cpp @@ -34,7 +34,6 @@ #include "PxPhysicsAPI.h" #include "../snippetcommon/SnippetPrint.h" #include "../snippetcommon/SnippetPVD.h" -#include "../snippetutils/SnippetUtils.h" #ifdef RENDER_SNIPPET #include "../snippetrender/SnippetRender.h" #endif @@ -54,6 +53,7 @@ static PxCudaContextManager* gCudaContextManager = NULL; #endif static bool gPause = false; static bool gOneFrame = false; +static bool gChangeObjectAType = false; static bool gChangeObjectBRotation = false; static bool gChangeJointFrameARotation = false; static bool gChangeJointFrameBRotation = false; @@ -107,15 +107,27 @@ static void createScene() if(gSceneIndexsetRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true); + actor0 = actor; + } + else + { + actor0 = PxCreateStatic(*gPhysics, tr, boxGeom, *gMaterial); + } setupActor(actor0); tr.p.x += boxGeom.halfExtents.x * 2.0f; if(gChangeObjectBRotation) - tr.q = SnippetUtils::getRotZQuat(-PxPi/4.0f); + tr.q = rotZ; PxRigidDynamic* actor1 = PxCreateDynamic(*gPhysics, tr, boxGeom, *gMaterial, 1.0f); setupActor(actor1); @@ -126,12 +138,12 @@ static void createScene() // We're going to setup a linear drive along "X" = actor0's joint frame's X axis. // That axis will be either aligned with the actors' X axis or tilted 45 degrees. if(gChangeJointFrameARotation) - jointFrame0.q = SnippetUtils::getRotZQuat(-PxPi/4.0f); + jointFrame0.q = rotZ; else jointFrame0.q = PxQuat(PxIdentity); if(gChangeJointFrameBRotation) - jointFrame1.q = SnippetUtils::getRotZQuat(-PxPi/4.0f); + jointFrame1.q = rotZ; else jointFrame1.q = PxQuat(PxIdentity); @@ -231,12 +243,13 @@ void renderText() { #ifdef RENDER_SNIPPET Snippets::print("Press F1 to change body0's joint frame orientation"); - Snippets::print("Press F2 to change body1's joint frame orientation"); - Snippets::print("Press F3 to change body1's orientation"); + Snippets::print("Press F2 to change body0's type (static/kinematic)"); + Snippets::print("Press F3 to change body1's joint frame orientation"); + Snippets::print("Press F4 to change body1's orientation"); #if PX_SUPPORT_GPU_PHYSX - Snippets::print("Press F4 to use CPU or GPU"); + Snippets::print("Press F5 to use CPU or GPU"); #endif - Snippets::print("Press F5 to select the next drive"); + Snippets::print("Press F6 to select the next drive"); switch(gSceneIndex) { case 0: @@ -278,28 +291,29 @@ void keyPress(unsigned char key, const PxTransform&) gChangeJointFrameARotation = !gChangeJointFrameARotation; createScene(); } - - if(key==2) + else if(key==2) + { + gChangeObjectAType = !gChangeObjectAType; + createScene(); + } + else if(key==3) { gChangeJointFrameBRotation = !gChangeJointFrameBRotation; createScene(); } - - if(key==3) + else if(key==4) { gChangeObjectBRotation = !gChangeObjectBRotation; createScene(); } - #if PX_SUPPORT_GPU_PHYSX - if(key==4) + else if(key==5) { gUseGPU = !gUseGPU; createScene(); } #endif - - if(key==5) + else if(key==6) { gSceneIndex = gSceneIndex + 1; if(gSceneIndex==gMaxSceneIndex) diff --git a/physx/snippets/snippetjointdrive/SnippetJointDriveRender.cpp b/physx/snippets/snippetjointdrive/SnippetJointDriveRender.cpp index 485b505c4..e2146b05d 100644 --- a/physx/snippets/snippetjointdrive/SnippetJointDriveRender.cpp +++ b/physx/snippets/snippetjointdrive/SnippetJointDriveRender.cpp @@ -84,11 +84,15 @@ void renderCallback() Snippets::finishRender(); } -void exitCallback(void) +void cleanup() { delete sCamera; cleanupPhysics(true); } + +void exitCallback(void) +{ +} } void renderLoop() @@ -99,5 +103,7 @@ void renderLoop() initPhysics(true); glutMainLoop(); + + cleanup(); } #endif diff --git a/physx/snippets/snippetkinematicsoftbody/MeshGenerator.h b/physx/snippets/snippetkinematicsoftbody/MeshGenerator.h new file mode 100644 index 000000000..c33a1353c --- /dev/null +++ b/physx/snippets/snippetkinematicsoftbody/MeshGenerator.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. + +#ifndef PHYSX_MESHGENERATOR_H +#define PHYSX_MESHGENERATOR_H + +#include "PxPhysicsAPI.h" +#include "extensions/PxRemeshingExt.h" + +namespace meshgenerator +{ +using namespace physx; + +void createCube(PxArray& triVerts, PxArray& triIndices, const PxVec3& pos, const PxVec3& scaling) +{ + triVerts.clear(); + triIndices.clear(); + triVerts.pushBack(scaling.multiply(PxVec3(0.5f, -0.5f, -0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(0.5f, -0.5f, 0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(-0.5f, -0.5f, 0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(-0.5f, -0.5f, -0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(0.5f, 0.5f, -0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(0.5f, 0.5f, 0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(-0.5f, 0.5f, 0.5f)) + pos); + triVerts.pushBack(scaling.multiply(PxVec3(-0.5f, 0.5f, -0.5f)) + pos); + + triIndices.pushBack(1); triIndices.pushBack(2); triIndices.pushBack(3); + triIndices.pushBack(7); triIndices.pushBack(6); triIndices.pushBack(5); + triIndices.pushBack(4); triIndices.pushBack(5); triIndices.pushBack(1); + triIndices.pushBack(5); triIndices.pushBack(6); triIndices.pushBack(2); + + triIndices.pushBack(2); triIndices.pushBack(6); triIndices.pushBack(7); + triIndices.pushBack(0); triIndices.pushBack(3); triIndices.pushBack(7); + triIndices.pushBack(0); triIndices.pushBack(1); triIndices.pushBack(3); + triIndices.pushBack(4); triIndices.pushBack(7); triIndices.pushBack(5); + + triIndices.pushBack(0); triIndices.pushBack(4); triIndices.pushBack(1); + triIndices.pushBack(1); triIndices.pushBack(5); triIndices.pushBack(2); + triIndices.pushBack(3); triIndices.pushBack(2); triIndices.pushBack(7); + triIndices.pushBack(4); triIndices.pushBack(0); triIndices.pushBack(7); +} + +void createConeY(PxArray& triVerts, PxArray& triIndices, const PxVec3& center, PxReal radius, PxReal height, PxU32 numPointsOnRing = 32) +{ + triVerts.clear(); + triIndices.clear(); + for (PxU32 i = 0; i < numPointsOnRing; ++i) + { + PxReal angle = i * 2.0f * 3.1415926535898f / numPointsOnRing; + triVerts.pushBack(center + radius * PxVec3(PxSin(angle), 0, PxCos(angle))); + } + + triVerts.pushBack(center); + triVerts.pushBack(center + PxVec3(0, height, 0)); + for (PxU32 i = 0; i < numPointsOnRing; ++i) + { + triIndices.pushBack(numPointsOnRing); triIndices.pushBack(i); triIndices.pushBack((i + 1) % numPointsOnRing); + triIndices.pushBack(numPointsOnRing + 1); triIndices.pushBack((i + 1) % numPointsOnRing); triIndices.pushBack(i); + } +} + +void projectPointsOntoSphere(PxArray& triVerts, const PxVec3& center, PxReal radius) +{ + for (PxU32 i = 0; i < triVerts.size(); ++i) + { + PxVec3 dir = triVerts[i] - center; + dir.normalize(); + triVerts[i] = center + radius * dir; + } +} + +void createSphere(PxArray& triVerts, PxArray& triIndices, const PxVec3& center, PxReal radius, const PxReal maxEdgeLength) +{ + triVerts.clear(); + triIndices.clear(); + createCube(triVerts, triIndices, center, PxVec3(radius)); + projectPointsOntoSphere(triVerts, center, radius); + while (PxRemeshingExt::limitMaxEdgeLength(triIndices, triVerts, maxEdgeLength, 1)) + projectPointsOntoSphere(triVerts, center, radius); +} +} + +#endif diff --git a/physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBody.cpp b/physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBody.cpp new file mode 100644 index 000000000..16b856e26 --- /dev/null +++ b/physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBody.cpp @@ -0,0 +1,413 @@ +// 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. + +// **************************************************************************** +// This snippet demonstrates how to setup softbodies. +// **************************************************************************** + +#include +#include "PxPhysicsAPI.h" +#include "../snippetcommon/SnippetPrint.h" +#include "../snippetcommon/SnippetPVD.h" +#include "../snippetutils/SnippetUtils.h" +#include "../snippetkinematicsoftbody/SnippetKinematicSoftBody.h" +#include "../snippetkinematicsoftbody/MeshGenerator.h" +#include "extensions/PxTetMakerExt.h" +#include "extensions/PxSoftBodyExt.h" + +using namespace physx; +using namespace meshgenerator; + +static PxDefaultAllocator gAllocator; +static PxDefaultErrorCallback gErrorCallback; +static PxFoundation* gFoundation = NULL; +static PxPhysics* gPhysics = NULL; +static PxCudaContextManager* gCudaContextManager = NULL; +static PxDefaultCpuDispatcher* gDispatcher = NULL; +static PxScene* gScene = NULL; +static PxMaterial* gMaterial = NULL; +static PxPvd* gPvd = NULL; +std::vector gSoftBodies; + +void addSoftBody(PxSoftBody* softBody, const PxFEMParameters& femParams, const PxFEMMaterial& /*femMaterial*/, + const PxTransform& transform, const PxReal density, const PxReal scale, const PxU32 iterCount/*, PxMaterial* tetMeshMaterial*/) +{ + PxVec4* simPositionInvMassPinned; + PxVec4* simVelocityPinned; + PxVec4* collPositionInvMassPinned; + PxVec4* restPositionPinned; + + PxSoftBodyExt::allocateAndInitializeHostMirror(*softBody, gCudaContextManager, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + + const PxReal maxInvMassRatio = 50.f; + + softBody->setParameter(femParams); + //softBody->setMaterial(femMaterial); + softBody->setSolverIterationCounts(iterCount); + + PxSoftBodyExt::transform(*softBody, transform, scale, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio, simPositionInvMassPinned); + PxSoftBodyExt::copyToDevice(*softBody, PxSoftBodyDataFlag::eALL, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + + SoftBody sBody(softBody, gCudaContextManager); + + gSoftBodies.push_back(sBody); + + PX_PINNED_HOST_FREE(gCudaContextManager, simPositionInvMassPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, simVelocityPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, collPositionInvMassPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, restPositionPinned); +} + +static PxSoftBody* createSoftBody(const PxCookingParams& params, const PxArray& triVerts, const PxArray& triIndices, bool useCollisionMeshForSimulation = false) +{ + PxFEMSoftBodyMaterial* material = PxGetPhysics().createFEMSoftBodyMaterial(1e+6f, 0.45f, 0.5f); + material->setDamping(0.005f); + + PxSoftBodyMesh* softBodyMesh; + + PxU32 numVoxelsAlongLongestAABBAxis = 8; + + PxSimpleTriangleMesh surfaceMesh; + surfaceMesh.points.count = triVerts.size(); + surfaceMesh.points.data = triVerts.begin(); + surfaceMesh.triangles.count = triIndices.size() / 3; + surfaceMesh.triangles.data = triIndices.begin(); + + if (useCollisionMeshForSimulation) + { + softBodyMesh = PxSoftBodyExt::createSoftBodyMeshNoVoxels(params, surfaceMesh, gPhysics->getPhysicsInsertionCallback()); + } + else + { + softBodyMesh = PxSoftBodyExt::createSoftBodyMesh(params, surfaceMesh, numVoxelsAlongLongestAABBAxis, gPhysics->getPhysicsInsertionCallback()); + } + + //Alternatively one can cook a softbody mesh in a single step + //tetMesh = cooking.createSoftBodyMesh(simulationMeshDesc, collisionMeshDesc, softbodyDesc, physics.getPhysicsInsertionCallback()); + PX_ASSERT(softBodyMesh); + + if (!gCudaContextManager) + return NULL; + PxSoftBody* softBody = gPhysics->createSoftBody(*gCudaContextManager); + if (softBody) + { + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE; + + PxFEMSoftBodyMaterial* materialPtr = PxGetPhysics().createFEMSoftBodyMaterial(1e+6f, 0.45f, 0.5f); + materialPtr->setMaterialModel(PxFEMSoftBodyMaterialModel::eNEO_HOOKEAN); + PxTetrahedronMeshGeometry geometry(softBodyMesh->getCollisionMesh()); + PxShape* shape = gPhysics->createShape(geometry, &materialPtr, 1, true, shapeFlags); + if (shape) + { + softBody->attachShape(*shape); + shape->setSimulationFilterData(PxFilterData(0, 0, 2, 0)); + } + softBody->attachSimulationMesh(*softBodyMesh->getSimulationMesh(), *softBodyMesh->getSoftBodyAuxData()); + + gScene->addActor(*softBody); + + PxFEMParameters femParams; + addSoftBody(softBody, femParams, *material, PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxIdentity)), 100.f, 1.0f, 30); + softBody->setSoftBodyFlag(PxSoftBodyFlag::eDISABLE_SELF_COLLISION, true); + } + return softBody; +} + +static void createSoftbodies(const PxCookingParams& params) +{ + PxArray triVerts; + PxArray triIndices; + + PxReal maxEdgeLength = 0.75f; + + createCube(triVerts, triIndices, PxVec3(0, 0, 0), PxVec3(2.5f, 10, 2.5f)); + PxRemeshingExt::limitMaxEdgeLength(triIndices, triVerts, maxEdgeLength); + + PxVec3 position(0, 5.0f, 0); + for (PxU32 i = 0; i < triVerts.size(); ++i) + { + PxVec3& p = triVerts[i]; + PxReal corr = PxSqrt(p.x*p.x + p.z*p.z); + if (corr != 0) + corr = PxMax(PxAbs(p.x), PxAbs(p.z)) / corr; + PxReal scaling = 0.75f + 0.5f * (PxCos(1.5f*p.y) + 1.0f); + p.x *= scaling * corr; + p.z *= scaling * corr; + p += position; + } + PxRemeshingExt::limitMaxEdgeLength(triIndices, triVerts, maxEdgeLength); + + + PxSoftBody* softBody = createSoftBody(params, triVerts, triIndices, true); + + + SoftBody* sb = &gSoftBodies[0]; + sb->copyDeformedVerticesFromGPU(); + + PxCudaContextManager* cudaContextManager = gScene->getCudaContextManager(); + PxU32 vertexCount = sb->mSoftBody->getSimulationMesh()->getNbVertices(); + + + PxVec4* kinematicTargets = PX_PINNED_HOST_ALLOC_T(PxVec4, cudaContextManager, vertexCount); + PxVec4* positionInvMass = sb->mPositionsInvMass; + for (PxU32 i = 0; i < vertexCount; ++i) + { + PxVec4& p = positionInvMass[i]; + bool kinematic = false; + if (i < triVerts.size()) + { + if (p.y > 9.9f) + kinematic = true; + + if (p.y > 5 - 0.1f && p.y < 5 + 0.1f) + kinematic = true; + + if (p.y < 0.1f) + kinematic = true; + } + + kinematicTargets[i] = PxConfigureSoftBodyKinematicTarget(p, kinematic); + } + + PxVec4* kinematicTargetsD = PX_DEVICE_ALLOC_T(PxVec4, cudaContextManager, vertexCount); + cudaContextManager->getCudaContext()->memcpyHtoD(reinterpret_cast(softBody->getSimPositionInvMassBufferD()), positionInvMass, vertexCount * sizeof(PxVec4)); + cudaContextManager->getCudaContext()->memcpyHtoD(reinterpret_cast(kinematicTargetsD), kinematicTargets, vertexCount * sizeof(PxVec4)); + softBody->setKinematicTargetBufferD(kinematicTargetsD, PxSoftBodyFlag::ePARTIALLY_KINEMATIC); + + sb->mTargetPositionsH = kinematicTargets; + sb->mTargetPositionsD = kinematicTargetsD; + sb->mTargetCount = vertexCount; +} + +void initPhysics(bool /*interactive*/) +{ + gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback); + gPvd = PxCreatePvd(*gFoundation); + PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10); + gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL); + + // initialize cuda + PxCudaContextManagerDesc cudaContextManagerDesc; + gCudaContextManager = PxCreateCudaContextManager(*gFoundation, cudaContextManagerDesc, PxGetProfilerCallback()); + if (gCudaContextManager && !gCudaContextManager->contextIsValid()) + { + gCudaContextManager->release(); + gCudaContextManager = NULL; + printf("Failed to initialize cuda context.\n"); + } + + PxTolerancesScale scale; + gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, scale, true, gPvd); + PxInitExtensions(*gPhysics, gPvd); + + PxCookingParams params(scale); + params.meshWeldTolerance = 0.001f; + params.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES); + params.buildTriangleAdjacencies = false; + params.buildGPUData = true; + + PxSceneDesc sceneDesc(gPhysics->getTolerancesScale()); + sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f); + + if (!sceneDesc.cudaContextManager) + sceneDesc.cudaContextManager = gCudaContextManager; + + sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS; + sceneDesc.flags |= PxSceneFlag::eENABLE_PCM; + + PxU32 numCores = SnippetUtils::getNbPhysicalCores(); + gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1); + sceneDesc.cpuDispatcher = gDispatcher; + sceneDesc.filterShader = PxDefaultSimulationFilterShader; + sceneDesc.flags |= PxSceneFlag::eENABLE_ACTIVE_ACTORS; + + sceneDesc.sceneQueryUpdateMode = PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_DISABLED; + sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU; + sceneDesc.gpuMaxNumPartitions = 8; + + sceneDesc.solverType = PxSolverType::eTGS; + + gScene = gPhysics->createScene(sceneDesc); + PxPvdSceneClient* pvdClient = gScene->getScenePvdClient(); + if(pvdClient) + { + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true); + pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true); + } + + gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.f); + + PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial); + gScene->addActor(*groundPlane); + + createSoftbodies(params); + + // Setup rigid bodies + const PxReal dynamicsDensity = 10; + const PxReal boxSize = 0.5f; + const PxReal spacing = 0.6f; + const PxReal boxMass = boxSize * boxSize * boxSize * dynamicsDensity; + const PxU32 gridSizeA = 13; + const PxU32 gridSizeB = 3; + const PxReal initialRadius = 1.65f; + const PxReal distanceJointStiffness = 500.0f; + const PxReal distanceJointDamping = 0.5f; + PxShape* shape = gPhysics->createShape(PxBoxGeometry(0.5f * boxSize, 0.5f * boxSize, 0.5f * boxSize), *gMaterial); + shape->setDensityForFluid(dynamicsDensity); + PxArray rigids; + for (PxU32 i = 0; i < gridSizeA; ++i) + for (PxU32 j = 0; j < gridSizeB; ++j) + { + PxReal x = PxCos((2 * PxPi*i) / gridSizeA); + PxReal y = PxSin((2 * PxPi*i) / gridSizeA); + PxVec3 pos = PxVec3((x*j)*spacing + x * initialRadius, 8, (y *j)*spacing + y * initialRadius); + + PxReal d = 0.0f; + { + PxReal x2 = PxCos((2 * PxPi*(i + 1)) / gridSizeA); + PxReal y2 = PxSin((2 * PxPi*(i + 1)) / gridSizeA); + PxVec3 pos2 = PxVec3((x2*j)*spacing + x2 * initialRadius, 8, (y2 *j)*spacing + y2 * initialRadius); + d = (pos - pos2).magnitude(); + } + + PxRigidDynamic* body = gPhysics->createRigidDynamic(PxTransform(pos)); + body->attachShape(*shape); + PxRigidBodyExt::updateMassAndInertia(*body, boxMass); + gScene->addActor(*body); + rigids.pushBack(body); + + if (j > 0) + { + PxDistanceJoint* joint = PxDistanceJointCreate(*gPhysics, rigids[rigids.size() - 2], PxTransform(PxIdentity), body, PxTransform(PxIdentity)); + joint->setMaxDistance(spacing); + joint->setMinDistance(spacing*0.5f); + joint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED); + joint->setStiffness(distanceJointStiffness); + joint->setDamping(distanceJointDamping); + joint->setConstraintFlags(PxConstraintFlag::eCOLLISION_ENABLED); + } + + if (i > 0) + { + PxDistanceJoint* joint = PxDistanceJointCreate(*gPhysics, rigids[rigids.size() - gridSizeB - 1], PxTransform(PxIdentity), body, PxTransform(PxIdentity)); + joint->setMaxDistance(d); + joint->setMinDistance(d*0.5f); + joint->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED); + joint->setStiffness(distanceJointStiffness); + joint->setDamping(distanceJointDamping); + joint->setConstraintFlags(PxConstraintFlag::eCOLLISION_ENABLED); + if (i == gridSizeA - 1) + { + PxDistanceJoint* joint2 = PxDistanceJointCreate(*gPhysics, rigids[j], PxTransform(PxIdentity), body, PxTransform(PxIdentity)); + joint2->setMaxDistance(d); + joint2->setMinDistance(d*0.5f); + joint2->setDistanceJointFlags(PxDistanceJointFlag::eMAX_DISTANCE_ENABLED | PxDistanceJointFlag::eMIN_DISTANCE_ENABLED | PxDistanceJointFlag::eSPRING_ENABLED); + joint2->setStiffness(distanceJointStiffness); + joint2->setDamping(distanceJointDamping); + joint->setConstraintFlags(PxConstraintFlag::eCOLLISION_ENABLED); + } + } + } + shape->release(); +} + +PxReal simTime = 0.0f; +void stepPhysics(bool /*interactive*/) +{ + const PxReal dt = 1.0f / 60.f; + + gScene->simulate(dt); + gScene->fetchResults(true); + + for (PxU32 i = 0; i < gSoftBodies.size(); i++) + { + SoftBody* sb = &gSoftBodies[i]; + sb->copyDeformedVerticesFromGPU(); + + + PxCudaContextManager* cudaContextManager = sb->mCudaContextManager; + //Update the kinematic targets to get some motion + if (i == 0) + { + PxReal scaling = PxMin(0.01f, simTime * 0.1f); + PxReal velocity = 1.0f; + for (PxU32 j = 0; j < sb->mTargetCount; ++j) + { + PxVec4& target = sb->mTargetPositionsH[j]; + if (target.w == 0.0f) + { + PxReal phase = target.y*2.0f; + target.x += scaling * PxSin(velocity * simTime + phase); + target.z += scaling * PxCos(velocity * simTime + phase); + } + } + + PxScopedCudaLock _lock(*cudaContextManager); + cudaContextManager->getCudaContext()->memcpyHtoD(reinterpret_cast(sb->mTargetPositionsD), sb->mTargetPositionsH, sb->mTargetCount * sizeof(PxVec4)); + } + } + simTime += dt; +} + +void cleanupPhysics(bool /*interactive*/) +{ + for (PxU32 i = 0; i < gSoftBodies.size(); i++) + gSoftBodies[i].release(); + gSoftBodies.clear(); + + PX_RELEASE(gScene); + PX_RELEASE(gDispatcher); + PX_RELEASE(gPhysics); + PxPvdTransport* transport = gPvd->getTransport(); + gPvd->release(); + transport->release(); + PxCloseExtensions(); + + gCudaContextManager->release(); + PX_RELEASE(gFoundation); + + printf("Snippet Kinematic Softbody done.\n"); +} + +int snippetMain(int, const char*const*) +{ +#ifdef RENDER_SNIPPET + extern void renderLoop(); + renderLoop(); +#else + static const PxU32 frameCount = 100; + initPhysics(false); + for(PxU32 i=0; i + +class SoftBody +{ +public: + SoftBody(physx::PxSoftBody* softBody, physx::PxCudaContextManager* cudaContextManager) : + mSoftBody(softBody), + mCudaContextManager(cudaContextManager) + { + mPositionsInvMass = PX_PINNED_HOST_ALLOC_T(physx::PxVec4, cudaContextManager, softBody->getCollisionMesh()->getNbVertices()); + } + + ~SoftBody() + { + } + + void release() + { + if (mSoftBody) + mSoftBody->release(); + if (mPositionsInvMass) + PX_PINNED_HOST_FREE(mCudaContextManager, mPositionsInvMass); + + if (mTargetPositionsH) + PX_PINNED_HOST_FREE(mCudaContextManager, mTargetPositionsH); + if (mTargetPositionsD) + PX_DEVICE_FREE(mCudaContextManager, mTargetPositionsD); + } + + void copyDeformedVerticesFromGPUAsync(CUstream stream) + { + physx::PxTetrahedronMesh* tetMesh = mSoftBody->getCollisionMesh(); + + physx::PxScopedCudaLock _lock(*mCudaContextManager); + mCudaContextManager->getCudaContext()->memcpyDtoHAsync(mPositionsInvMass, reinterpret_cast(mSoftBody->getPositionInvMassBufferD()), tetMesh->getNbVertices() * sizeof(physx::PxVec4), stream); + } + + void copyDeformedVerticesFromGPU() + { + physx::PxTetrahedronMesh* tetMesh = mSoftBody->getCollisionMesh(); + + physx::PxScopedCudaLock _lock(*mCudaContextManager); + mCudaContextManager->getCudaContext()->memcpyDtoH(mPositionsInvMass, reinterpret_cast(mSoftBody->getPositionInvMassBufferD()), tetMesh->getNbVertices() * sizeof(physx::PxVec4)); + } + + + physx::PxVec4* mPositionsInvMass; + physx::PxSoftBody* mSoftBody; + physx::PxCudaContextManager* mCudaContextManager; + + physx::PxVec4* mTargetPositionsH; + physx::PxVec4* mTargetPositionsD; + physx::PxU32 mTargetCount; +}; + +#endif diff --git a/physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBodyRender.cpp b/physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBodyRender.cpp new file mode 100644 index 000000000..82d762838 --- /dev/null +++ b/physx/snippets/snippetkinematicsoftbody/SnippetKinematicSoftBodyRender.cpp @@ -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. + +#ifdef RENDER_SNIPPET + +#include + +#include "PxPhysicsAPI.h" + +#include "../snippetrender/SnippetRender.h" +#include "../snippetrender/SnippetCamera.h" +#include "SnippetKinematicSoftBody.h" + +using namespace physx; + +extern void initPhysics(bool interactive); +extern void stepPhysics(bool interactive); +extern void cleanupPhysics(bool interactive); +extern std::vector gSoftBodies; + +namespace +{ +Snippets::Camera* sCamera; + +void renderCallback() +{ + stepPhysics(true); + + Snippets::startRender(sCamera); + + const PxVec3 dynColor(1.0f, 0.5f, 0.25f); + const PxVec3 rcaColor(0.6f*0.75f, 0.8f*0.75f, 1.0f*0.75f); + + PxScene* scene; + PxGetPhysics().getScenes(&scene,1); + PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC); + if(nbActors) + { + std::vector actors(nbActors); + scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast(&actors[0]), nbActors); + Snippets::renderActors(&actors[0], static_cast(actors.size()), true, dynColor); + } + for (PxU32 i = 0; i < gSoftBodies.size(); i++) + { + SoftBody* sb = &gSoftBodies[i]; + Snippets::renderSoftBody(sb->mSoftBody, sb->mPositionsInvMass, true, rcaColor); + } + + Snippets::finishRender(); +} + +void cleanup() +{ + delete sCamera; + cleanupPhysics(true); +} + +void exitCallback(void) +{ +} +} + +void renderLoop() +{ + sCamera = new Snippets::Camera(PxVec3(10.0f, 10.0f, 10.0f), PxVec3(-0.6f, -0.2f, -0.7f)); + + Snippets::setupDefault("PhysX Snippet Partially Kinematic Softbody", sCamera, NULL, renderCallback, exitCallback); + + initPhysics(true); + glutMainLoop(); + + cleanup(); +} + +#endif diff --git a/physx/snippets/snippetloadcollection/SnippetLoadCollection.cpp b/physx/snippets/snippetloadcollection/SnippetLoadCollection.cpp index 13bffd5be..da2a7a1f4 100644 --- a/physx/snippets/snippetloadcollection/SnippetLoadCollection.cpp +++ b/physx/snippets/snippetloadcollection/SnippetLoadCollection.cpp @@ -67,7 +67,6 @@ static PxDefaultAllocator gAllocator; static PxDefaultErrorCallback gErrorCallback; static PxFoundation* gFoundation = NULL; static PxPhysics* gPhysics = NULL; -static PxCooking* gCooking = NULL; static PxSerializationRegistry* gSerializationRegistry = NULL; static PxDefaultCpuDispatcher* gDispatcher = NULL; static PxScene* gScene = NULL; @@ -231,7 +230,10 @@ static PxCollection* deserializeCollection(PxInputData& inputData, bool isBinary } else { - collection = PxSerialization::createCollectionFromXml(inputData, *gCooking, sr, sharedCollection); + PxTolerancesScale scale; + PxCookingParams params(scale); + + collection = PxSerialization::createCollectionFromXml(inputData, params, sr, sharedCollection); } return collection; @@ -263,10 +265,7 @@ void initPhysics() pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true); } - gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale())); - gSerializationRegistry = PxSerialization::createSerializationRegistry(*gPhysics); - } void cleanupPhysics() @@ -277,7 +276,6 @@ void cleanupPhysics() PxCloseExtensions(); PX_RELEASE(gPhysics); // releases of all objects - PX_RELEASE(gCooking); for(PxU32 i=0; imObjects[i]->getShapes(&shape, 1); - PxBoxGeometry boxGeom; - shape->getBoxGeometry(boxGeom); + const PxBoxGeometry& boxGeom = static_cast(shape->getGeometry()); const PxVec3 minimum = c - boxGeom.halfExtents; const PxVec3 maximum = c + boxGeom.halfExtents; diff --git a/physx/snippets/snippetomnipvd/SnippetOmniPvd.cpp b/physx/snippets/snippetomnipvd/SnippetOmniPvd.cpp index a7bdfb34c..43ffd8659 100644 --- a/physx/snippets/snippetomnipvd/SnippetOmniPvd.cpp +++ b/physx/snippets/snippetomnipvd/SnippetOmniPvd.cpp @@ -34,7 +34,7 @@ #if PX_SUPPORT_OMNI_PVD #include "../pvdruntime/include/OmniPvdWriter.h" #include "../pvdruntime/include/OmniPvdFileWriteStream.h" -#endif + using namespace physx; static PxDefaultAllocator gAllocator; @@ -82,7 +82,6 @@ void initPhysicsWithOmniPvd() return; } -#if PX_SUPPORT_OMNI_PVD gOmniPvd = PxCreateOmniPvd(*gFoundation); if (!gOmniPvd) { @@ -102,8 +101,7 @@ void initPhysicsWithOmniPvd() return; } fStream->setFileName(gOmniPvdPath); - omniWriter->setWriteStream(static_cast(fStream)); -#endif + omniWriter->setWriteStream(static_cast(*fStream)); gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, NULL, gOmniPvd); if (!gPhysics) @@ -111,7 +109,7 @@ void initPhysicsWithOmniPvd() printf("Error : could not create a PhysX instance!"); return; } -#if PX_SUPPORT_OMNI_PVD + if (gPhysics->getOmniPvd()) { gPhysics->getOmniPvd()->startSampling(); @@ -121,7 +119,7 @@ void initPhysicsWithOmniPvd() printf("Error : could not start OmniPvd sampling!"); return; } -#endif + initPhysXScene(); } @@ -129,10 +127,8 @@ void cleanupPhysics() { PX_RELEASE(gScene); PX_RELEASE(gDispatcher); - PX_RELEASE(gPhysics); -#if PX_SUPPORT_OMNI_PVD + PX_RELEASE(gPhysics); PX_RELEASE(gOmniPvd); -#endif PX_RELEASE(gFoundation); } @@ -162,9 +158,11 @@ void keyPress(unsigned char key, const PxTransform& camera) case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0, 0, -1)) * 200); break; } } +#endif // PX_SUPPORT_OMNI_PVD int snippetMain(int argc, const char *const* argv) { +#if PX_SUPPORT_OMNI_PVD if (!parseOmniPvdOutputFile(argc, argv)) { return 1; @@ -179,5 +177,12 @@ int snippetMain(int argc, const char *const* argv) stepPhysics(); cleanupPhysics(); #endif +#else + PX_UNUSED(argc); + PX_UNUSED(argv); + + printf("PVD is not supported in release build configuration. Please use any of the other build configurations to run this snippet.\n"); +#endif // PX_SUPPORT_OMNI_PVD + return 0; } diff --git a/physx/snippets/snippetomnipvd/SnippetOmniPvdRender.cpp b/physx/snippets/snippetomnipvd/SnippetOmniPvdRender.cpp index 204ce3d0d..5a9440d7d 100644 --- a/physx/snippets/snippetomnipvd/SnippetOmniPvdRender.cpp +++ b/physx/snippets/snippetomnipvd/SnippetOmniPvdRender.cpp @@ -28,6 +28,7 @@ #ifdef RENDER_SNIPPET +#if PX_SUPPORT_OMNI_PVD #include #include "PxPhysicsAPI.h" @@ -81,4 +82,6 @@ void renderLoop() initPhysicsWithOmniPvd(); glutMainLoop(); } +#endif // PX_SUPPORT_OMNI_PVD + #endif diff --git a/physx/snippets/snippetpbdcloth/SnippetPBDClothRender.cpp b/physx/snippets/snippetpbdcloth/SnippetPBDClothRender.cpp index 0f6a1d2aa..9bb832d5f 100644 --- a/physx/snippets/snippetpbdcloth/SnippetPBDClothRender.cpp +++ b/physx/snippets/snippetpbdcloth/SnippetPBDClothRender.cpp @@ -67,14 +67,14 @@ void onBeforeRenderParticles() PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); - cudaContexManager->acquireContext(); + cudaContextManager->acquireContext(); - PxCudaContext* cudaContext = cudaContexManager->getCudaContext(); + PxCudaContext* cudaContext = cudaContextManager->getCudaContext(); cudaContext->memcpyDtoH(sPosBuffer.map(), CUdeviceptr(positions), sizeof(PxVec4) * numParticles); - cudaContexManager->releaseContext(); + cudaContextManager->releaseContext(); #if SHOW_SOLID_SDF_SLICE particleSystem->copySparseGridData(sSparseGridSolidSDFBufferD, PxSparseGridDataFlag::eGRIDCELL_SOLID_GRADIENT_AND_SDF); #endif @@ -95,12 +95,12 @@ void allocParticleBuffers() { PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); PxParticleClothBuffer* userBuffer = getUserClothBuffer(); PxU32 maxParticles = userBuffer->getMaxParticles(); - sPosBuffer.initialize(cudaContexManager); + sPosBuffer.initialize(cudaContextManager); sPosBuffer.allocate(maxParticles * sizeof(PxVec4)); } @@ -143,9 +143,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -162,8 +159,6 @@ void renderLoop() glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetpbdinflatable/SnippetPBDInflatableRender.cpp b/physx/snippets/snippetpbdinflatable/SnippetPBDInflatableRender.cpp index a46211dcd..8dbe48074 100644 --- a/physx/snippets/snippetpbdinflatable/SnippetPBDInflatableRender.cpp +++ b/physx/snippets/snippetpbdinflatable/SnippetPBDInflatableRender.cpp @@ -67,14 +67,14 @@ void onBeforeRenderParticles() PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); - cudaContexManager->acquireContext(); + cudaContextManager->acquireContext(); - PxCudaContext* cudaContext = cudaContexManager->getCudaContext(); + PxCudaContext* cudaContext = cudaContextManager->getCudaContext(); cudaContext->memcpyDtoH(sPosBuffer.map(), CUdeviceptr(positions), sizeof(PxVec4) * numParticles); - cudaContexManager->releaseContext(); + cudaContextManager->releaseContext(); #if SHOW_SOLID_SDF_SLICE particleSystem->copySparseGridData(sSparseGridSolidSDFBufferD, PxSparseGridDataFlag::eGRIDCELL_SOLID_GRADIENT_AND_SDF); #endif @@ -95,13 +95,13 @@ void allocParticleBuffers() { PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); PxParticleClothBuffer* userBuffer = getUserClothBuffer(); PxU32 maxParticles = userBuffer->getMaxParticles(); - sPosBuffer.initialize(cudaContexManager); + sPosBuffer.initialize(cudaContextManager); sPosBuffer.allocate(maxParticles * sizeof(PxVec4)); } @@ -145,9 +145,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -164,8 +161,6 @@ void renderLoop() glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetpbf/SnippetPBFRender.cpp b/physx/snippets/snippetpbf/SnippetPBFRender.cpp index 75ccc7b4f..abdc7b958 100644 --- a/physx/snippets/snippetpbf/SnippetPBFRender.cpp +++ b/physx/snippets/snippetpbf/SnippetPBFRender.cpp @@ -78,15 +78,15 @@ void renderParticles() PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); - cudaContexManager->acquireContext(); + cudaContextManager->acquireContext(); - PxCudaContext* cudaContext = cudaContexManager->getCudaContext(); + PxCudaContext* cudaContext = cudaContextManager->getCudaContext(); cudaContext->memcpyDtoH(sPosBuffer.map(), CUdeviceptr(positions), sizeof(PxVec4) * numParticles); cudaContext->memcpyDtoH(sDiffusePosLifeBuffer.map(), CUdeviceptr(diffusePositions), sizeof(PxVec4) * numDiffuseParticles); - cudaContexManager->releaseContext(); + cudaContextManager->releaseContext(); #if SHOW_SOLID_SDF_SLICE particleSystem->copySparseGridData(sSparseGridSolidSDFBufferD, PxSparseGridDataFlag::eGRIDCELL_SOLID_GRADIENT_AND_SDF); @@ -117,17 +117,17 @@ void allocParticleBuffers() { PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); PxParticleAndDiffuseBuffer* userBuffer = getParticleBuffer(); const PxU32 maxParticles = userBuffer->getMaxParticles(); const PxU32 maxDiffuseParticles = userBuffer->getMaxDiffuseParticles(); - sDiffusePosLifeBuffer.initialize(cudaContexManager); + sDiffusePosLifeBuffer.initialize(cudaContextManager); sDiffusePosLifeBuffer.allocate(maxDiffuseParticles * sizeof(PxVec4)); - sPosBuffer.initialize(cudaContexManager); + sPosBuffer.initialize(cudaContextManager); sPosBuffer.allocate(maxParticles * sizeof(PxVec4)); } @@ -171,9 +171,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -190,8 +187,6 @@ void renderLoop() glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetpbfmultimat/SnippetPBFMultiMatRender.cpp b/physx/snippets/snippetpbfmultimat/SnippetPBFMultiMatRender.cpp index ade5b67ce..5e2bffa27 100644 --- a/physx/snippets/snippetpbfmultimat/SnippetPBFMultiMatRender.cpp +++ b/physx/snippets/snippetpbfmultimat/SnippetPBFMultiMatRender.cpp @@ -118,11 +118,11 @@ void onBeforeRenderParticles() PxScene* scene; PxGetPhysics().getScenes(&scene, 1); - PxCudaContextManager* cudaContexManager = scene->getCudaContextManager(); + PxCudaContextManager* cudaContextManager = scene->getCudaContextManager(); - cudaContexManager->acquireContext(); + cudaContextManager->acquireContext(); - PxCudaContext* cudaContext = cudaContexManager->getCudaContext(); + PxCudaContext* cudaContext = cudaContextManager->getCudaContext(); cudaContext->memcpyDtoH(sPosBufferH->begin(), CUdeviceptr(positions), sizeof(PxVec4) * numParticles); cudaContext->memcpyDtoH(sVelBufferH->begin(), CUdeviceptr(vels), sizeof(PxVec4) * numParticles); cudaContext->memcpyDtoH(sPhasesH->begin(), CUdeviceptr(phases), sizeof(PxU32) * numParticles); @@ -130,7 +130,7 @@ void onBeforeRenderParticles() copyVec4ToVec3(*sPosBuffer3H, *sPosBufferH); mapVec4ToColor3(*sColorBuffer3H, *sVelBufferH, *sPhasesH); - cudaContexManager->releaseContext(); + cudaContextManager->releaseContext(); } } @@ -199,9 +199,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -217,8 +214,6 @@ void renderLoop() glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetpointdistancequery/SnippetPointDistanceQueryRender.cpp b/physx/snippets/snippetpointdistancequery/SnippetPointDistanceQueryRender.cpp index 3142c15b6..4b27fbdd9 100644 --- a/physx/snippets/snippetpointdistancequery/SnippetPointDistanceQueryRender.cpp +++ b/physx/snippets/snippetpointdistancequery/SnippetPointDistanceQueryRender.cpp @@ -34,7 +34,6 @@ #include "../snippetrender/SnippetRender.h" #include "../snippetrender/SnippetCamera.h" -#include "../snippetutils/SnippetUtils.h" using namespace physx; @@ -70,9 +69,9 @@ void renderCallback() static float time = 0.0f; time += 0.003f; - const PxQuat qx = SnippetUtils::getRotXQuat(time); - const PxQuat qy = SnippetUtils::getRotYQuat(time*1.7f); - const PxQuat qz = SnippetUtils::getRotZQuat(time*1.33f); + const PxQuat qx = PxGetRotXQuat(time); + const PxQuat qy = PxGetRotYQuat(time*1.7f); + const PxQuat qz = PxGetRotZQuat(time*1.33f); const PxTransform pose(PxVec3(0.0f), qx*qy*qz); Snippets::renderGeoms(1, &gh, &pose, false, color); diff --git a/physx/snippets/snippetquerysystemallqueries/SnippetQuerySystemAllQueries.cpp b/physx/snippets/snippetquerysystemallqueries/SnippetQuerySystemAllQueries.cpp index 95d5ea4ef..aca579d10 100644 --- a/physx/snippets/snippetquerysystemallqueries/SnippetQuerySystemAllQueries.cpp +++ b/physx/snippets/snippetquerysystemallqueries/SnippetQuerySystemAllQueries.cpp @@ -285,9 +285,9 @@ void CustomScene::updateObjects() pose.p.y = sinf(phase+time*1.17f)*amplitude; pose.p.x = cosf(phase+time*1.17f)*amplitude; - PxMat33 rotX; SnippetUtils::setRotX(rotX, time+coeff); - PxMat33 rotY; SnippetUtils::setRotY(rotY, time*1.17f+coeff); - PxMat33 rotZ; SnippetUtils::setRotZ(rotZ, time*0.33f+coeff); + PxMat33 rotX; PxSetRotX(rotX, time+coeff); + PxMat33 rotY; PxSetRotY(rotY, time*1.17f+coeff); + PxMat33 rotZ; PxSetRotZ(rotZ, time*0.33f+coeff); PxMat33 rot = rotX * rotY * rotZ; pose.q = PxQuat(rot); pose.q.normalize(); diff --git a/physx/snippets/snippetquerysystemcustomcompound/SnippetQuerySystemCustomCompound.cpp b/physx/snippets/snippetquerysystemcustomcompound/SnippetQuerySystemCustomCompound.cpp index 70884393b..ca157de00 100644 --- a/physx/snippets/snippetquerysystemcustomcompound/SnippetQuerySystemCustomCompound.cpp +++ b/physx/snippets/snippetquerysystemcustomcompound/SnippetQuerySystemCustomCompound.cpp @@ -617,9 +617,9 @@ void CustomScene::updateObjects() pose.p.y = sinf(phase+time*1.17f)*amplitude; pose.p.x = cosf(phase+time*1.17f)*amplitude; - PxMat33 rotX; SnippetUtils::setRotX(rotX, time+coeff); - PxMat33 rotY; SnippetUtils::setRotY(rotY, time*1.17f+coeff); - PxMat33 rotZ; SnippetUtils::setRotZ(rotZ, time*0.33f+coeff); + PxMat33 rotX; PxSetRotX(rotX, time+coeff); + PxMat33 rotY; PxSetRotY(rotY, time*1.17f+coeff); + PxMat33 rotZ; PxSetRotZ(rotZ, time*0.33f+coeff); PxMat33 rot = rotX * rotY * rotZ; pose.q = PxQuat(rot); pose.q.normalize(); diff --git a/physx/snippets/snippetrender/SnippetRender.cpp b/physx/snippets/snippetrender/SnippetRender.cpp index 057576864..bf23889a8 100644 --- a/physx/snippets/snippetrender/SnippetRender.cpp +++ b/physx/snippets/snippetrender/SnippetRender.cpp @@ -119,7 +119,7 @@ static void releaseVertexBuffer() } } -static void renderSoftBodyGeometry(const PxTetrahedronMesh& mesh, const PxArray& deformedPositionsInvMass) +static void renderSoftBodyGeometry(const PxTetrahedronMesh& mesh, const PxVec4* deformedPositionsInvMass) { const int tetFaces[4][3] = { {0,2,1}, {0,1,3}, {0,3,2}, {1,2,3} }; @@ -459,7 +459,7 @@ static void defaultMouseCallback(int button, int state, int x, int y) static void defaultKeyboardCallback(unsigned char key, int x, int y) { if(key==27) - exit(0); + glutLeaveMainLoop(); if (key == 110) //n gWireFrame = !gWireFrame; @@ -671,9 +671,7 @@ void setupDefault(const char* name, Camera* camera, KeyboardCallback kbcb, Rende setupDefaultRenderState(); enableVSync(true); -#if PX_LINUX_FAMILY - glutSetOption( GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS ); -#endif + glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS); gUserExitCB = excb; @@ -761,7 +759,7 @@ void print(const char* text) const PxVec3 shadowDir(0.0f, -0.7071067f, -0.7071067f); const PxReal shadowMat[] = { 1,0,0,0, -shadowDir.x / shadowDir.y,0,-shadowDir.z / shadowDir.y,0, 0,0,1,0, 0,0,0,1 }; -void renderSoftBody(PxSoftBody* softBody, const PxArray& deformedPositionsInvMass, bool shadows, const PxVec3& color) +void renderSoftBody(PxSoftBody* softBody, const PxVec4* deformedPositionsInvMass, bool shadows, const PxVec3& color) { PxShape* shape = softBody->getShape(); diff --git a/physx/snippets/snippetrender/SnippetRender.h b/physx/snippets/snippetrender/SnippetRender.h index 5f59005ad..8484d8694 100644 --- a/physx/snippets/snippetrender/SnippetRender.h +++ b/physx/snippets/snippetrender/SnippetRender.h @@ -109,7 +109,7 @@ namespace Snippets void initFPS(); void showFPS(int updateIntervalMS = 30, const char* info = NULL); - void renderSoftBody(physx::PxSoftBody* softBody, const physx::PxArray& deformedPositionsInvMass, bool shadows, const physx::PxVec3& color = physx::PxVec3(0.0f, 0.75f, 0.0f)); + void renderSoftBody(physx::PxSoftBody* softBody, const physx::PxVec4* deformedPositionsInvMass, bool shadows, const physx::PxVec3& color = physx::PxVec3(0.0f, 0.75f, 0.0f)); void renderActors(physx::PxRigidActor** actors, const physx::PxU32 numActors, bool shadows = false, const physx::PxVec3& color = physx::PxVec3(0.0f, 0.75f, 0.0f), TriggerRender* cb = NULL, bool changeColorForSleepingActors = true, bool wireframePass=true); // void renderGeoms(const physx::PxU32 nbGeoms, const physx::PxGeometry* geoms, const physx::PxTransform* poses, bool shadows, const physx::PxVec3& color); void renderGeoms(const physx::PxU32 nbGeoms, const physx::PxGeometryHolder* geoms, const physx::PxTransform* poses, bool shadows, const physx::PxVec3& color); diff --git a/physx/snippets/snippetsdf/SnippetSDF.cpp b/physx/snippets/snippetsdf/SnippetSDF.cpp index 814468755..472aebb65 100644 --- a/physx/snippets/snippetsdf/SnippetSDF.cpp +++ b/physx/snippets/snippetsdf/SnippetSDF.cpp @@ -95,8 +95,8 @@ static void addInstance(const PxTransform& transform, PxTriangleMesh* mesh) dyn->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD, true); PxShape* shape = PxRigidActorExt::createExclusiveShape(*dyn, geom, *gMaterial); - shape->setContactOffset(0.1f); - shape->setRestOffset(0.02f); + shape->setContactOffset(0.05f); + shape->setRestOffset(0.0f); PxRigidBodyExt::updateMassAndInertia(*dyn, 100.f); @@ -114,7 +114,7 @@ static void createBowls(PxCookingParams& params) PxReal maxEdgeLength = 1; - createBowl(triVerts, triIndices, PxVec3(0, 4.5, 0), 5.0f, maxEdgeLength); + createBowl(triVerts, triIndices, PxVec3(0, 4.5, 0), 6.0f, maxEdgeLength); PxTriangleMesh* mesh = createMesh(params, triVerts, triIndices, 0.05f); PxQuat rotate(PxIdentity); diff --git a/physx/snippets/snippetsdf/SnippetSDFRender.cpp b/physx/snippets/snippetsdf/SnippetSDFRender.cpp index c675f2eb6..e0962090c 100644 --- a/physx/snippets/snippetsdf/SnippetSDFRender.cpp +++ b/physx/snippets/snippetsdf/SnippetSDFRender.cpp @@ -76,9 +76,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -92,9 +89,7 @@ void renderLoop() Snippets::initFPS(); glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetserialization/SnippetSerialization.cpp b/physx/snippets/snippetserialization/SnippetSerialization.cpp index 179df3d96..e8084e5c3 100644 --- a/physx/snippets/snippetserialization/SnippetSerialization.cpp +++ b/physx/snippets/snippetserialization/SnippetSerialization.cpp @@ -29,6 +29,8 @@ // **************************************************************************** // This snippet illustrates the use of binary and xml serialization // +// Note: RepX/Xml serialization has been DEPRECATED. +// // It creates a chain of boxes and serializes them as two collections: // a collection with shared objects and a collection with actors and joints // which can be instantiated multiple times. @@ -56,7 +58,6 @@ static PxDefaultAllocator gAllocator; static PxDefaultErrorCallback gErrorCallback; static PxFoundation* gFoundation = NULL; static PxPhysics* gPhysics = NULL; -static PxCooking* gCooking = NULL; static PxDefaultCpuDispatcher* gDispatcher = NULL; static PxScene* gScene = NULL; static PxPvd* gPvd = NULL; @@ -148,7 +149,7 @@ void serializeObjects(PxOutputStream& sharedStream, PxOutputStream& actorStream) /** Deserialize shared data and use resulting collection to deserialize and instance actor collections */ -void deserializeObjects(PxInputData& sharedData, PxInputData& actorData) +void deserializeObjects(PxInputData& sharedData, PxInputData& actorData, const PxCookingParams& params) { PxSerializationRegistry* sr = PxSerialization::createSerializationRegistry(*gPhysics); @@ -162,7 +163,7 @@ void deserializeObjects(PxInputData& sharedData, PxInputData& actorData) } else { - sharedCollection = PxSerialization::createCollectionFromXml(sharedData, *gCooking, *sr); + sharedCollection = PxSerialization::createCollectionFromXml(sharedData, params, *sr); } } @@ -187,7 +188,7 @@ void deserializeObjects(PxInputData& sharedData, PxInputData& actorData) } else { - collection = PxSerialization::createCollectionFromXml(actorData, *gCooking, *sr, sharedCollection); + collection = PxSerialization::createCollectionFromXml(actorData, params, *sr, sharedCollection); } for (PxU32 o = 0; o < collection->getNbObjects(); o++) @@ -224,7 +225,6 @@ void initPhysics() gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL); gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd); - gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale())); PxInitExtensions(*gPhysics, gPvd); PxU32 numCores = SnippetUtils::getNbPhysicalCores(); @@ -260,7 +260,6 @@ void cleanupPhysics() PxCloseExtensions(); PX_RELEASE(gPhysics); // releases all objects - PX_RELEASE(gCooking); if(gPvd) { PxPvdTransport* transport = gPvd->getTransport(); @@ -290,7 +289,11 @@ int snippetMain(int, const char*const*) // Alternatively PxDefaultFileInputData could be used PxDefaultMemoryInputData sharedInputStream(sharedOutputStream.getData(), sharedOutputStream.getSize()); PxDefaultMemoryInputData actorInputStream(actorOutputStream.getData(), actorOutputStream.getSize()); - deserializeObjects(sharedInputStream, actorInputStream); + + PxTolerancesScale scale; + const PxCookingParams params(scale); + + deserializeObjects(sharedInputStream, actorInputStream, params); #ifdef RENDER_SNIPPET extern void renderLoop(); renderLoop(); diff --git a/physx/snippets/snippetsoftbody/SnippetSoftBody.cpp b/physx/snippets/snippetsoftbody/SnippetSoftBody.cpp index c44282e29..3dcff5be6 100644 --- a/physx/snippets/snippetsoftbody/SnippetSoftBody.cpp +++ b/physx/snippets/snippetsoftbody/SnippetSoftBody.cpp @@ -57,13 +57,12 @@ std::vector gSoftBodies; void addSoftBody(PxSoftBody* softBody, const PxFEMParameters& femParams, const PxFEMMaterial& /*femMaterial*/, const PxTransform& transform, const PxReal density, const PxReal scale, const PxU32 iterCount/*, PxMaterial* tetMeshMaterial*/) { - PxShape* shape = softBody->getShape(); - PxTetrahedronMeshGeometry tetMeshGeom; - shape->getTetrahedronMeshGeometry(tetMeshGeom); - PxTetrahedronMesh* colTetMesh = tetMeshGeom.tetrahedronMesh; - const PxU32 numVerts = colTetMesh->getNbVertices(); + PxVec4* simPositionInvMassPinned; + PxVec4* simVelocityPinned; + PxVec4* collPositionInvMassPinned; + PxVec4* restPositionPinned; - PxBuffer* positionInvMassBuf = gPhysics->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eHOST, gCudaContextManager); + PxSoftBodyExt::allocateAndInitializeHostMirror(*softBody, gCudaContextManager, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); const PxReal maxInvMassRatio = 50.f; @@ -71,13 +70,18 @@ void addSoftBody(PxSoftBody* softBody, const PxFEMParameters& femParams, const P //softBody->setMaterial(femMaterial); softBody->setSolverIterationCounts(iterCount); - PxSoftBodyExt::transform(*softBody, transform, scale); - PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio); - PxSoftBodyExt::commit(*softBody, PxSoftBodyData::eALL); + PxSoftBodyExt::transform(*softBody, transform, scale, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio, simPositionInvMassPinned); + PxSoftBodyExt::copyToDevice(*softBody, PxSoftBodyDataFlag::eALL, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); - SoftBody sBody(softBody, positionInvMassBuf); + SoftBody sBody(softBody, gCudaContextManager); gSoftBodies.push_back(sBody); + + PX_PINNED_HOST_FREE(gCudaContextManager, simPositionInvMassPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, simVelocityPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, collPositionInvMassPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, restPositionPinned); } static PxSoftBody* createSoftBody(const PxCookingParams& params, const PxArray& triVerts, const PxArray& triIndices, bool useCollisionMeshForSimulation = false) @@ -237,13 +241,15 @@ void cleanupPhysics(bool /*interactive*/) for (PxU32 i = 0; i < gSoftBodies.size(); i++) gSoftBodies[i].release(); gSoftBodies.clear(); + PX_RELEASE(gScene); PX_RELEASE(gDispatcher); PX_RELEASE(gPhysics); PxPvdTransport* transport = gPvd->getTransport(); gPvd->release(); transport->release(); - PxCloseExtensions(); + PxCloseExtensions(); + gCudaContextManager->release(); PX_RELEASE(gFoundation); diff --git a/physx/snippets/snippetsoftbody/SnippetSoftBody.h b/physx/snippets/snippetsoftbody/SnippetSoftBody.h index 2e336faed..68ec9978e 100644 --- a/physx/snippets/snippetsoftbody/SnippetSoftBody.h +++ b/physx/snippets/snippetsoftbody/SnippetSoftBody.h @@ -30,15 +30,19 @@ #define PHYSX_SNIPPET_SOFTBODY_H #include "PxPhysicsAPI.h" +#include "cudamanager/PxCudaContextManager.h" +#include "cudamanager/PxCudaContext.h" #include class SoftBody { public: - SoftBody(physx::PxSoftBody* softBody, physx::PxBuffer* positionInvMass) : + SoftBody(physx::PxSoftBody* softBody, physx::PxCudaContextManager* cudaContextManager) : mSoftBody(softBody), - mPositionInvMass(positionInvMass) - { } + mCudaContextManager(cudaContextManager) + { + mPositionsInvMass = PX_PINNED_HOST_ALLOC_T(physx::PxVec4, cudaContextManager, softBody->getCollisionMesh()->getNbVertices()); + } ~SoftBody() { @@ -48,27 +52,30 @@ class SoftBody { if (mSoftBody) mSoftBody->release(); - if (mPositionInvMass) - mPositionInvMass->release(); + if (mPositionsInvMass) + PX_PINNED_HOST_FREE(mCudaContextManager, mPositionsInvMass); } + void copyDeformedVerticesFromGPUAsync(CUstream stream) + { + physx::PxTetrahedronMesh* tetMesh = mSoftBody->getCollisionMesh(); + + physx::PxScopedCudaLock _lock(*mCudaContextManager); + mCudaContextManager->getCudaContext()->memcpyDtoHAsync(mPositionsInvMass, reinterpret_cast(mSoftBody->getPositionInvMassBufferD()), tetMesh->getNbVertices() * sizeof(physx::PxVec4), stream); + } void copyDeformedVerticesFromGPU() { - mSoftBody->readData(physx::PxSoftBodyData::ePOSITION_INVMASS, *mPositionInvMass); + physx::PxTetrahedronMesh* tetMesh = mSoftBody->getCollisionMesh(); - physx::PxTetrahedronMesh* mTetMesh = mSoftBody->getCollisionMesh(); - physx::PxVec4* positionsInvMass = static_cast(mPositionInvMass->map()); - - mPositionsInvMass.resize(mTetMesh->getNbVertices()); - memcpy(mPositionsInvMass.begin(), positionsInvMass, mTetMesh->getNbVertices() * sizeof(physx::PxVec4)); - - mPositionInvMass->unmap(); + physx::PxScopedCudaLock _lock(*mCudaContextManager); + mCudaContextManager->getCudaContext()->memcpyDtoH(mPositionsInvMass, reinterpret_cast(mSoftBody->getPositionInvMassBufferD()), tetMesh->getNbVertices() * sizeof(physx::PxVec4)); } - physx::PxArray mPositionsInvMass; + + physx::PxVec4* mPositionsInvMass; physx::PxSoftBody* mSoftBody; - physx::PxBuffer* mPositionInvMass; + physx::PxCudaContextManager* mCudaContextManager; }; #endif diff --git a/physx/snippets/snippetsoftbody/SnippetSoftBodyRender.cpp b/physx/snippets/snippetsoftbody/SnippetSoftBodyRender.cpp index 20cf664fc..3dd4d959d 100644 --- a/physx/snippets/snippetsoftbody/SnippetSoftBodyRender.cpp +++ b/physx/snippets/snippetsoftbody/SnippetSoftBodyRender.cpp @@ -82,9 +82,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -97,9 +94,7 @@ void renderLoop() initPhysics(true); glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachment.cpp b/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachment.cpp index baf4424c3..5d9f43052 100644 --- a/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachment.cpp +++ b/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachment.cpp @@ -73,26 +73,33 @@ void addSoftBody(PxSoftBody* softBody, const PxFEMParameters& femParams, PxFEMSo const PxTransform& transform, const PxReal density, const PxReal scale, const PxU32 iterCount/*, PxMaterial* tetMeshMaterial*/) { PxShape* shape = softBody->getShape(); - PxTetrahedronMeshGeometry tetMeshGeom; - shape->getTetrahedronMeshGeometry(tetMeshGeom); - PxTetrahedronMesh* colTetMesh = tetMeshGeom.tetrahedronMesh; - const PxU32 numVerts = colTetMesh->getNbVertices(); - PxBuffer* positionInvMassBuf = gPhysics->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eHOST, gCudaContextManager); + PxVec4* simPositionInvMassPinned; + PxVec4* simVelocityPinned; + PxVec4* collPositionInvMassPinned; + PxVec4* restPositionPinned; + PxSoftBodyExt::allocateAndInitializeHostMirror(*softBody, gCudaContextManager, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + const PxReal maxInvMassRatio = 50.f; softBody->setParameter(femParams); shape->setSoftBodyMaterials(&femMaterial, 1); softBody->setSolverIterationCounts(iterCount); - PxSoftBodyExt::transform(*softBody, transform, scale); - PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio); - PxSoftBodyExt::commit(*softBody, PxSoftBodyData::eALL); + PxSoftBodyExt::transform(*softBody, transform, scale, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio, simPositionInvMassPinned); + PxSoftBodyExt::copyToDevice(*softBody, PxSoftBodyDataFlag::eALL, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + - SoftBody sBody(softBody, positionInvMassBuf); + SoftBody sBody(softBody, gCudaContextManager); gSoftBodies.push_back(sBody); + + PX_PINNED_HOST_FREE(gCudaContextManager, simPositionInvMassPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, simVelocityPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, collPositionInvMassPinned); + PX_PINNED_HOST_FREE(gCudaContextManager, restPositionPinned); } static PxSoftBody* createSoftBody(const PxCookingParams& params, const PxArray& triVerts, const PxArray& triIndices, bool useCollisionMeshForSimulation = false) diff --git a/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachmentRender.cpp b/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachmentRender.cpp index 4a8a7d199..d2c4fc358 100644 --- a/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachmentRender.cpp +++ b/physx/snippets/snippetsoftbodyattachment/SnippetSoftBodyAttachmentRender.cpp @@ -82,9 +82,6 @@ void cleanup() void exitCallback(void) { -#if PX_WINDOWS - cleanup(); -#endif } } @@ -97,9 +94,7 @@ void renderLoop() initPhysics(true); glutMainLoop(); -#if PX_LINUX_FAMILY cleanup(); -#endif } #endif diff --git a/physx/snippets/snippetsplitsim/SnippetSplitSim.cpp b/physx/snippets/snippetsplitsim/SnippetSplitSim.cpp index dceab09e3..9f7d3033b 100644 --- a/physx/snippets/snippetsplitsim/SnippetSplitSim.cpp +++ b/physx/snippets/snippetsplitsim/SnippetSplitSim.cpp @@ -57,7 +57,6 @@ #include "PxPhysicsAPI.h" #include "../snippetcommon/SnippetPrint.h" #include "../snippetcommon/SnippetPVD.h" -#include "../snippetutils/SnippetUtils.h" //This will allow the split sim to overlap collision and render and game logic. #define OVERLAP_COLLISION_AND_RENDER_WITH_NO_LAG 1 @@ -83,20 +82,6 @@ static bool isFirstFrame = true; PxRigidDynamic* gKinematics[NB_KINE_Y][NB_KINE_X]; PxTransform gKinematicTargets[NB_KINE_Y][NB_KINE_X]; -PxQuat setRotY(PxMat33& m, const PxReal angle) -{ - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[2][2] = cos; - m[0][2] = -sin; - m[2][0] = sin; - - return PxQuat(m); -} - void createDynamics() { const PxU32 NbX = 8; @@ -116,11 +101,10 @@ void createDynamics() PX_UNUSED(boxShape); PX_UNUSED(sphereShape); PX_UNUSED(capsuleShape); - PxMat33 m; for(PxU32 j=0;jconnect(*transport,PxPvdInstrumentationFlag::eALL); - gPhysics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd); + gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd); gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.2f); diff --git a/physx/snippets/snippettrianglemeshcreate/SnippetTriangleMeshCreate.cpp b/physx/snippets/snippettrianglemeshcreate/SnippetTriangleMeshCreate.cpp index 870c6f2c7..dc378e4c7 100644 --- a/physx/snippets/snippettrianglemeshcreate/SnippetTriangleMeshCreate.cpp +++ b/physx/snippets/snippettrianglemeshcreate/SnippetTriangleMeshCreate.cpp @@ -43,7 +43,6 @@ static PxDefaultAllocator gAllocator; static PxDefaultErrorCallback gErrorCallback; static PxFoundation* gFoundation = NULL; static PxPhysics* gPhysics = NULL; -static PxCooking* gCooking = NULL; float rand(float loVal, float hiVal) { @@ -149,7 +148,8 @@ void createBV33TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 num meshDesc.triangles.data = indices; meshDesc.triangles.stride = 3 * sizeof(PxU32); - PxCookingParams params = gCooking->getParams(); + PxTolerancesScale scale; + PxCookingParams params(scale); // Create BVH33 midphase params.midphaseDesc = PxMeshMidPhase::eBVH33; @@ -175,14 +175,12 @@ void createBV33TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 num params.midphaseDesc.mBVH33Desc.meshSizePerformanceTradeOff = 0.55f; } - gCooking->setParams(params); - #if defined(PX_CHECKED) || defined(PX_DEBUG) // If DISABLE_CLEAN_MESH is set, the mesh is not cleaned during the cooking. // We should check the validity of provided triangles in debug/checked builds though. if (skipMeshCleanup) { - PX_ASSERT(gCooking->validateTriangleMesh(meshDesc)); + PX_ASSERT(PxValidateTriangleMesh(params, meshDesc)); } #endif // DEBUG @@ -193,12 +191,12 @@ void createBV33TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 num // The cooked mesh may either be saved to a stream for later loading, or inserted directly into PxPhysics. if (inserted) { - triMesh = gCooking->createTriangleMesh(meshDesc, gPhysics->getPhysicsInsertionCallback()); + triMesh = PxCreateTriangleMesh(params, meshDesc, gPhysics->getPhysicsInsertionCallback()); } else { PxDefaultMemoryOutputStream outBuffer; - gCooking->cookTriangleMesh(meshDesc, outBuffer); + PxCookTriangleMesh(params, meshDesc, outBuffer); PxDefaultMemoryInputData stream(outBuffer.getData(), outBuffer.getSize()); triMesh = gPhysics->createTriangleMesh(stream); @@ -239,7 +237,8 @@ void createBV34TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 num meshDesc.triangles.data = indices; meshDesc.triangles.stride = 3 * sizeof(PxU32); - PxCookingParams params = gCooking->getParams(); + PxTolerancesScale scale; + PxCookingParams params(scale); // Create BVH34 midphase params.midphaseDesc = PxMeshMidPhase::eBVH34; @@ -251,14 +250,12 @@ void createBV34TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 num // and worse cooking performance. Cooking time is better when more triangles per leaf are used. params.midphaseDesc.mBVH34Desc.numPrimsPerLeaf = numTrisPerLeaf; - gCooking->setParams(params); - #if defined(PX_CHECKED) || defined(PX_DEBUG) // If DISABLE_CLEAN_MESH is set, the mesh is not cleaned during the cooking. // We should check the validity of provided triangles in debug/checked builds though. if (skipMeshCleanup) { - PX_ASSERT(gCooking->validateTriangleMesh(meshDesc)); + PX_ASSERT(PxValidateTriangleMesh(params, meshDesc)); } #endif // DEBUG @@ -269,12 +266,12 @@ void createBV34TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 num // The cooked mesh may either be saved to a stream for later loading, or inserted directly into PxPhysics. if (inserted) { - triMesh = gCooking->createTriangleMesh(meshDesc, gPhysics->getPhysicsInsertionCallback()); + triMesh = PxCreateTriangleMesh(params, meshDesc, gPhysics->getPhysicsInsertionCallback()); } else { PxDefaultMemoryOutputStream outBuffer; - gCooking->cookTriangleMesh(meshDesc, outBuffer); + PxCookTriangleMesh(params, meshDesc, outBuffer); PxDefaultMemoryInputData stream(outBuffer.getData(), outBuffer.getSize()); triMesh = gPhysics->createTriangleMesh(stream); @@ -366,7 +363,6 @@ void initPhysics() { gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback); gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true); - gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale())); createTriangleMeshes(); } @@ -374,7 +370,6 @@ void initPhysics() void cleanupPhysics() { PX_RELEASE(gPhysics); - gCooking->release(); PX_RELEASE(gFoundation); printf("SnippetTriangleMeshCreate done.\n"); diff --git a/physx/snippets/snippettriggers/SnippetTriggers.cpp b/physx/snippets/snippettriggers/SnippetTriggers.cpp index 0936eebd8..8bf281268 100644 --- a/physx/snippets/snippettriggers/SnippetTriggers.cpp +++ b/physx/snippets/snippettriggers/SnippetTriggers.cpp @@ -172,10 +172,10 @@ static PxFilterFlags triggersUsingFilterCallback(PxFilterObjectAttributes /*attr class TriggersFilterCallback : public PxSimulationFilterCallback { - virtual PxFilterFlags pairFound(PxU32 /*pairID*/, - PxFilterObjectAttributes /*attributes0*/, PxFilterData /*filterData0*/, const PxActor* /*a0*/, const PxShape* s0, - PxFilterObjectAttributes /*attributes1*/, PxFilterData /*filterData1*/, const PxActor* /*a1*/, const PxShape* s1, - PxPairFlags& pairFlags) + virtual PxFilterFlags pairFound( PxU64 /*pairID*/, + PxFilterObjectAttributes /*attributes0*/, PxFilterData /*filterData0*/, const PxActor* /*a0*/, const PxShape* s0, + PxFilterObjectAttributes /*attributes1*/, PxFilterData /*filterData1*/, const PxActor* /*a1*/, const PxShape* s1, + PxPairFlags& pairFlags) PX_OVERRIDE { // printf("pairFound\n"); @@ -192,17 +192,15 @@ class TriggersFilterCallback : public PxSimulationFilterCallback return PxFilterFlags(); } - virtual void pairLost(PxU32 /*pairID*/, - PxFilterObjectAttributes /*attributes0*/, - PxFilterData /*filterData0*/, - PxFilterObjectAttributes /*attributes1*/, - PxFilterData /*filterData1*/, - bool /*objectRemoved*/) + virtual void pairLost( PxU64 /*pairID*/, + PxFilterObjectAttributes /*attributes0*/, PxFilterData /*filterData0*/, + PxFilterObjectAttributes /*attributes1*/, PxFilterData /*filterData1*/, + bool /*objectRemoved*/) PX_OVERRIDE { // printf("pairLost\n"); } - virtual bool statusChange(PxU32& /*pairID*/, PxPairFlags& /*pairFlags*/, PxFilterFlags& /*filterFlags*/) + virtual bool statusChange(PxU64& /*pairID*/, PxPairFlags& /*pairFlags*/, PxFilterFlags& /*filterFlags*/) PX_OVERRIDE { // printf("statusChange\n"); return false; @@ -211,22 +209,22 @@ class TriggersFilterCallback : public PxSimulationFilterCallback class ContactReportCallback: public PxSimulationEventCallback { - void onConstraintBreak(PxConstraintInfo* /*constraints*/, PxU32 /*count*/) + void onConstraintBreak(PxConstraintInfo* /*constraints*/, PxU32 /*count*/) PX_OVERRIDE { printf("onConstraintBreak\n"); } - void onWake(PxActor** /*actors*/, PxU32 /*count*/) + void onWake(PxActor** /*actors*/, PxU32 /*count*/) PX_OVERRIDE { printf("onWake\n"); } - void onSleep(PxActor** /*actors*/, PxU32 /*count*/) + void onSleep(PxActor** /*actors*/, PxU32 /*count*/) PX_OVERRIDE { printf("onSleep\n"); } - void onTrigger(PxTriggerPair* pairs, PxU32 count) + void onTrigger(PxTriggerPair* pairs, PxU32 count) PX_OVERRIDE { // printf("onTrigger: %d trigger pairs\n", count); while(count--) @@ -239,12 +237,12 @@ class ContactReportCallback: public PxSimulationEventCallback } } - void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) + void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) PX_OVERRIDE { printf("onAdvance\n"); } - void onContact(const PxContactPairHeader& /*pairHeader*/, const PxContactPair* pairs, PxU32 count) + void onContact(const PxContactPairHeader& /*pairHeader*/, const PxContactPair* pairs, PxU32 count) PX_OVERRIDE { // printf("onContact: %d pairs\n", count); @@ -441,6 +439,7 @@ void stepPhysics(bool /*interactive*/) if(gScene) { +// printf("Update...\n"); gScene->simulate(1.0f/60.0f); gScene->fetchResults(true); } diff --git a/physx/snippets/snippetutils/SnippetUtils.cpp b/physx/snippets/snippetutils/SnippetUtils.cpp index acb0617d1..f2bb040fa 100644 --- a/physx/snippets/snippetutils/SnippetUtils.cpp +++ b/physx/snippets/snippetutils/SnippetUtils.cpp @@ -55,63 +55,6 @@ struct UtilAllocator // since we're allocating internal classes here, make sure namespace SnippetUtils { - void setRotX(PxMat33& m, PxReal angle) - { - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[1][1] = m[2][2] = cos; - m[1][2] = sin; - m[2][1] = -sin; - } - - void setRotY(PxMat33& m, PxReal angle) - { - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[2][2] = cos; - m[0][2] = -sin; - m[2][0] = sin; - } - - void setRotZ(PxMat33& m, PxReal angle) - { - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[1][1] = cos; - m[0][1] = sin; - m[1][0] = -sin; - } - - PxQuat getRotXQuat(float angle) - { - PxMat33 m; - setRotX(m, angle); - return PxQuat(m); - } - - PxQuat getRotYQuat(float angle) - { - PxMat33 m; - setRotY(m, angle); - return PxQuat(m); - } - - PxQuat getRotZQuat(float angle) - { - PxMat33 m; - setRotZ(m, angle); - return PxQuat(m); - } - PxVec3 BasicRandom::unitRandomPt() { PxVec3 v; diff --git a/physx/snippets/snippetutils/SnippetUtils.h b/physx/snippets/snippetutils/SnippetUtils.h index 664c7ef99..eb5387a45 100644 --- a/physx/snippets/snippetutils/SnippetUtils.h +++ b/physx/snippets/snippetutils/SnippetUtils.h @@ -33,16 +33,6 @@ namespace physx { ///// - void setRotX(PxMat33& m, PxReal angle); - void setRotY(PxMat33& m, PxReal angle); - void setRotZ(PxMat33& m, PxReal angle); - - PxQuat getRotXQuat(float angle); - PxQuat getRotYQuat(float angle); - PxQuat getRotZQuat(float angle); - - ///// - class BasicRandom { public: diff --git a/physx/snippets/snippetvehicle2common/enginedrivetrain/EngineDrivetrain.h b/physx/snippets/snippetvehicle2common/enginedrivetrain/EngineDrivetrain.h index 393f27081..c7dda5800 100644 --- a/physx/snippets/snippetvehicle2common/enginedrivetrain/EngineDrivetrain.h +++ b/physx/snippets/snippetvehicle2common/enginedrivetrain/EngineDrivetrain.h @@ -165,6 +165,7 @@ class EngineDriveVehicle PxVehicleArrayData& wheelRigidBody1dStates, PxVehicleArrayData& wheelLocalPoses, const PxVehicleGearboxState*& gearState, + const PxReal*& throttle, PxVehiclePhysXActor*& physxActor) { axleDescription = &mBaseParams.axleDescription; @@ -176,6 +177,7 @@ class EngineDriveVehicle physxActor = &mPhysXState.physxActor; gearState = &mEngineDriveState.gearboxState; + throttle = &mCommandState.throttle; } virtual void getDataForEngineDriveCommandResponseComponent( diff --git a/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.cpp b/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.cpp index f6f05780c..29cc59205 100644 --- a/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.cpp +++ b/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.cpp @@ -39,8 +39,9 @@ void PhysXIntegrationParams::create const PxVec3& actorBoxShapeHalfExtents, const PxTransform& actorBoxShapeLocalPose) { physxRoadGeometryQueryParams.roadGeometryQueryType = PxVehiclePhysXRoadGeometryQueryType::eRAYCAST; - physxRoadGeometryQueryParams.filterData = queryFilterData; + physxRoadGeometryQueryParams.defaultFilterData = queryFilterData; physxRoadGeometryQueryParams.filterCallback = queryFilterCallback; + physxRoadGeometryQueryParams.filterDataEntries = NULL; for(PxU32 i = 0; i < axleDescription.nbWheels; i++) { diff --git a/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.h b/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.h index a519beb5c..1d6ce2852 100644 --- a/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.h +++ b/physx/snippets/snippetvehicle2common/physxintegration/PhysXIntegration.h @@ -157,6 +157,7 @@ class PhysXActorVehicle PxVehicleArrayData& wheelRigidBody1dStates, PxVehicleArrayData& wheelLocalPoses, const PxVehicleGearboxState*& gearState, + const PxReal*& throttle, PxVehiclePhysXActor*& physxActor) { axleDescription = &mBaseParams.axleDescription; @@ -168,6 +169,7 @@ class PhysXActorVehicle physxActor = &mPhysXState.physxActor; gearState = NULL; + throttle = &mCommandState.throttle; } virtual void getDataForPhysXConstraintComponent( diff --git a/physx/snippets/snippetvehicle2customization/CustomSuspension.cpp b/physx/snippets/snippetvehicle2customization/CustomSuspension.cpp index 7c399549d..45a07bb14 100644 --- a/physx/snippets/snippetvehicle2customization/CustomSuspension.cpp +++ b/physx/snippets/snippetvehicle2customization/CustomSuspension.cpp @@ -134,7 +134,7 @@ void CustomSuspensionVehicle::initComponentSequence(const bool addPhysXBeginEndC //In this example, we perform 3 updates of the suspensions, tires and wheels without recalculating //the plane underneath the wheel. This is useful for stability at low forward speeds and is //computationally cheaper than simulating the entire sequence. - mComponentSequence.beginSubstepGroup(3); + mComponentSequenceSubstepGroupHandle = mComponentSequence.beginSubstepGroup(3); //Update the suspension compression given the plane under each wheel. //Update the kinematic compliance from the compression state of each suspension. diff --git a/physx/source/common/src/CmConeLimitHelper.h b/physx/source/common/src/CmConeLimitHelper.h index 994924621..c15a5cb47 100644 --- a/physx/source/common/src/CmConeLimitHelper.h +++ b/physx/source/common/src/CmConeLimitHelper.h @@ -41,28 +41,28 @@ namespace physx { namespace Cm { - PX_FORCE_INLINE PxReal tanAdd(PxReal tan1, PxReal tan2) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal tanAdd(PxReal tan1, PxReal tan2) { - PX_ASSERT(PxAbs(1-tan1*tan2)>1e-6f); - return (tan1+tan2)/(1-tan1*tan2); + PX_ASSERT(PxAbs(1.0f-tan1*tan2)>1e-6f); + return (tan1+tan2)/(1.0f-tan1*tan2); } - PX_FORCE_INLINE float computeAxisAndError(const PxVec3& r, const PxVec3& d, const PxVec3& twistAxis, PxVec3& axis) + PX_CUDA_CALLABLE PX_FORCE_INLINE float computeAxisAndError(const PxVec3& r, const PxVec3& d, const PxVec3& twistAxis, PxVec3& axis) { // the point on the cone defined by the tanQ swing vector r // this code is equal to quatFromTanQVector(r).rotate(PxVec3(1.0f, 0.0f, 0.0f); - PxVec3 p(1.f,0,0); - PxReal r2 = r.dot(r), a = 1-r2, b = 1/(1+r2), b2 = b*b; - PxReal v1 = 2*a*b2; - PxVec3 v2(a, 2*r.z, -2*r.y); // a*p + 2*r.cross(p); - PxVec3 coneLine = v1 * v2 - p; // already normalized + const PxVec3 p(1.0f, 0.0f, 0.0f); + const PxReal r2 = r.dot(r), a = 1.0f - r2, b = 1.0f/(1.0f+r2), b2 = b*b; + const PxReal v1 = 2.0f * a * b2; + const PxVec3 v2(a, 2.0f * r.z, -2.0f * r.y); // a*p + 2*r.cross(p); + const PxVec3 coneLine = v1 * v2 - p; // already normalized // the derivative of coneLine in the direction d - PxReal rd = r.dot(d); - PxReal dv1 = -4*rd*(3-r2)*b2*b; - PxVec3 dv2(-2*rd, 2*d.z, -2*d.y); + const PxReal rd = r.dot(d); + const PxReal dv1 = -4.0f * rd * (3.0f - r2)*b2*b; + const PxVec3 dv2(-2.0f * rd, 2.0f * d.z, -2.0f * d.y); - PxVec3 coneNormal = v1 * dv2 + dv1 * v2; + const PxVec3 coneNormal = v1 * dv2 + dv1 * v2; axis = coneLine.cross(coneNormal)/coneNormal.magnitude(); return coneLine.cross(axis).dot(twistAxis); @@ -74,23 +74,23 @@ namespace Cm class ConeLimitHelper { public: - ConeLimitHelper(PxReal tanQSwingY, PxReal tanQSwingZ, PxReal tanQPadding) + PX_CUDA_CALLABLE ConeLimitHelper(PxReal tanQSwingY, PxReal tanQSwingZ, PxReal tanQPadding) : mTanQYMax(tanQSwingY), mTanQZMax(tanQSwingZ), mTanQPadding(tanQPadding) {} // whether the point is inside the (inwardly) padded cone - if it is, there's no limit // constraint - PX_FORCE_INLINE bool contains(const PxVec3& tanQSwing) const + PX_CUDA_CALLABLE PX_FORCE_INLINE bool contains(const PxVec3& tanQSwing) const { - PxReal tanQSwingYPadded = tanAdd(PxAbs(tanQSwing.y),mTanQPadding); - PxReal tanQSwingZPadded = tanAdd(PxAbs(tanQSwing.z),mTanQPadding); + const PxReal tanQSwingYPadded = tanAdd(PxAbs(tanQSwing.y),mTanQPadding); + const PxReal tanQSwingZPadded = tanAdd(PxAbs(tanQSwing.z),mTanQPadding); return PxSqr(tanQSwingYPadded/mTanQYMax)+PxSqr(tanQSwingZPadded/mTanQZMax) <= 1; } - PX_FORCE_INLINE PxVec3 clamp(const PxVec3& tanQSwing, PxVec3& normal) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 clamp(const PxVec3& tanQSwing, PxVec3& normal) const { - PxVec3 p = PxEllipseClamp(tanQSwing, PxVec3(0,mTanQYMax,mTanQZMax)); - normal = PxVec3(0, p.y/PxSqr(mTanQYMax), p.z/PxSqr(mTanQZMax)); + const PxVec3 p = PxEllipseClamp(tanQSwing, PxVec3(0.0f, mTanQYMax, mTanQZMax)); + normal = PxVec3(0.0f, p.y/PxSqr(mTanQYMax), p.z/PxSqr(mTanQZMax)); #ifdef PX_PARANOIA_ELLIPSE_CHECK PxReal err = PxAbs(PxSqr(p.y/mTanQYMax) + PxSqr(p.z/mTanQZMax) - 1); PX_ASSERT(err<1e-3); @@ -105,18 +105,18 @@ namespace Cm // limit (i.e. the image of the x axis), the error is the sine of the angular difference, // positive if the twist axis is inside the cone - bool getLimit(const PxQuat& swing, PxVec3& axis, PxReal& error) const + PX_CUDA_CALLABLE bool getLimit(const PxQuat& swing, PxVec3& axis, PxReal& error) const { - PX_ASSERT(swing.w>0); - PxVec3 twistAxis = swing.getBasisVector0(); - PxVec3 tanQSwing = PxVec3(0, PxTanHalf(swing.z,swing.w), -PxTanHalf(swing.y,swing.w)); + PX_ASSERT(swing.w>0.0f); + const PxVec3 twistAxis = swing.getBasisVector0(); + const PxVec3 tanQSwing = PxVec3(0.0f, PxTanHalf(swing.z,swing.w), -PxTanHalf(swing.y,swing.w)); if(contains(tanQSwing)) return false; PxVec3 normal, clamped = clamp(tanQSwing, normal); // rotation vector and ellipse normal - PxVec3 r(0,-clamped.z,clamped.y), d(0, -normal.z, normal.y); + const PxVec3 r(0.0f, -clamped.z, clamped.y), d(0.0f, -normal.z, normal.y); error = computeAxisAndError(r, d, twistAxis, axis); @@ -131,33 +131,21 @@ namespace Cm private: - PxReal mTanQYMax, mTanQZMax, mTanQPadding; }; class ConeLimitHelperTanLess { public: - ConeLimitHelperTanLess(PxReal swingY, PxReal swingZ, PxReal padding) - : mYMax(swingY), mZMax(swingZ), mPadding(padding) {} - - // whether the point is inside the (inwardly) padded cone - if it is, there's no limit - // constraint - PX_FORCE_INLINE bool contains(const PxVec3& swing) const - { - // padded current swing angles - PxReal swingYPadded = PxAbs(swing.y) + mPadding; - PxReal swingZPadded = PxAbs(swing.z) + mPadding; - // if angle is within ellipse defined by mYMax/mZMax - return PxSqr(swingYPadded/mYMax)+PxSqr(swingZPadded/mZMax) <= 1; - } + PX_CUDA_CALLABLE ConeLimitHelperTanLess(PxReal swingY, PxReal swingZ) + : mYMax(swingY), mZMax(swingZ) {} - PX_FORCE_INLINE PxVec3 clamp(const PxVec3& swing, PxVec3& normal) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 clamp(const PxVec3& swing, PxVec3& normal) const { // finds the closest point on the ellipse to a given point - PxVec3 p = PxEllipseClamp(swing, PxVec3(0,mYMax,mZMax)); + const PxVec3 p = PxEllipseClamp(swing, PxVec3(0.0f, mYMax, mZMax)); // normal to the point on ellipse - normal = PxVec3(0, p.y/PxSqr(mYMax), p.z/PxSqr(mZMax)); + normal = PxVec3(0.0f, p.y/PxSqr(mYMax), p.z/PxSqr(mZMax)); #ifdef PX_PARANOIA_ELLIPSE_CHECK PxReal err = PxAbs(PxSqr(p.y/mYMax) + PxSqr(p.z/mZMax) - 1); PX_ASSERT(err<1e-3); @@ -172,29 +160,25 @@ namespace Cm // limit (i.e. the image of the x axis), the error is the sine of the angular difference, // positive if the twist axis is inside the cone - bool getLimit(const PxQuat& swing, PxVec3& axis, PxReal& error) const + PX_CUDA_CALLABLE void getLimit(const PxQuat& swing, PxVec3& axis, PxReal& error) const { - PX_ASSERT(swing.w>0); - PxVec3 twistAxis = swing.getBasisVector0(); + PX_ASSERT(swing.w>0.0f); + const PxVec3 twistAxis = swing.getBasisVector0(); // get the angles from the swing quaternion - PxVec3 swingAngle(0.0f, 4 * PxAtan2(swing.y, 1 + swing.w), 4 * PxAtan2(swing.z, 1 + swing.w)); - if(contains(swingAngle)) - return false; + const PxVec3 swingAngle(0.0f, 4.0f * PxAtan2(swing.y, 1.0f + swing.w), 4.0f * PxAtan2(swing.z, 1.0f + swing.w)); PxVec3 normal, clamped = clamp(swingAngle, normal); // rotation vector and ellipse normal - PxVec3 r(0,PxTan(clamped.y/4),PxTan(clamped.z/4)), d(0, normal.y, normal.z); + const PxVec3 r(0.0f, PxTan(clamped.y/4.0f), PxTan(clamped.z/4.0f)), d(0.0f, normal.y, normal.z); error = computeAxisAndError(r, d, twistAxis, axis); - PX_ASSERT(PxAbs(axis.magnitude()-1)<1e-5f); - - return true; + PX_ASSERT(PxAbs(axis.magnitude()-1.0f)<1e-5f); } private: - PxReal mYMax, mZMax, mPadding; + PxReal mYMax, mZMax; }; } // namespace Cm diff --git a/physx/source/common/src/CmFlushPool.h b/physx/source/common/src/CmFlushPool.h index 1a2e91e06..04e3301a6 100644 --- a/physx/source/common/src/CmFlushPool.h +++ b/physx/source/common/src/CmFlushPool.h @@ -104,10 +104,8 @@ namespace Cm void clearNotThreadSafe(PxU32 spareChunkCount = sSpareChunkCount) { - PX_UNUSED(spareChunkCount); - //release memory not used previously - PxU32 targetSize = mChunkIndex+sSpareChunkCount; + PxU32 targetSize = mChunkIndex+spareChunkCount; while (mChunks.size() > targetSize) { PxU8* ptr = mChunks.popBack(); diff --git a/physx/source/common/src/CmPtrTable.h b/physx/source/common/src/CmPtrTable.h index 96f1f81bf..7c943b93f 100644 --- a/physx/source/common/src/CmPtrTable.h +++ b/physx/source/common/src/CmPtrTable.h @@ -70,13 +70,6 @@ class PtrTableStorageManager // one implication of this is that if we want to add or remove a pointer from unowned memory, we always realloc struct PX_PHYSX_COMMON_API PtrTable { -//= 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. -//================================================================================================== - PtrTable(); ~PtrTable(); diff --git a/physx/source/common/src/CmRefCountable.h b/physx/source/common/src/CmRefCountable.h index 755fe5a5e..5ca745df0 100644 --- a/physx/source/common/src/CmRefCountable.h +++ b/physx/source/common/src/CmRefCountable.h @@ -84,12 +84,6 @@ namespace Cm class RefCountable { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION RefCountable(const PxEMPTY) { PX_ASSERT(mRefCount == 1); } diff --git a/physx/source/common/src/CmTask.h b/physx/source/common/src/CmTask.h index d09e2afad..34aa599bc 100644 --- a/physx/source/common/src/CmTask.h +++ b/physx/source/common/src/CmTask.h @@ -267,6 +267,18 @@ namespace Cm T* mObj; }; + PX_FORCE_INLINE void startTask(Cm::Task* task, PxBaseTask* continuation) + { + if(continuation) + { + // PT: TODO: just make this a PxBaseTask function? + task->setContinuation(continuation); + task->removeReference(); + } + else + task->runInternal(); + } + } // namespace Cm } diff --git a/physx/source/common/src/CmTransformUtils.h b/physx/source/common/src/CmTransformUtils.h index 7d9df2bcd..7e3650731 100644 --- a/physx/source/common/src/CmTransformUtils.h +++ b/physx/source/common/src/CmTransformUtils.h @@ -73,6 +73,7 @@ namespace physx namespace Cm { +// PT: actor2World * shape2Actor PX_FORCE_INLINE void getStaticGlobalPoseAligned(const PxTransform& actor2World, const PxTransform& shape2Actor, PxTransform& outTransform) { using namespace aos; @@ -98,6 +99,7 @@ PX_FORCE_INLINE void getStaticGlobalPoseAligned(const PxTransform& actor2World, V4StoreA(V4SetW(v,w), &outTransform.q.x); } +// PT: body2World * body2Actor.getInverse() * shape2Actor PX_FORCE_INLINE void getDynamicGlobalPoseAligned(const PxTransform& body2World, const PxTransform& shape2Actor, const PxTransform& body2Actor, PxTransform& outTransform) { PX_ASSERT((size_t(&body2World)&15) == 0); diff --git a/physx/source/common/src/CmUtils.h b/physx/source/common/src/CmUtils.h index 25ed0f199..00c910d60 100644 --- a/physx/source/common/src/CmUtils.h +++ b/physx/source/common/src/CmUtils.h @@ -219,16 +219,15 @@ PX_INLINE void deletePxBase(T* object) #define PX_PADDING_16 0xcdcd #define PX_PADDING_32 0xcdcdcdcd +/** +Macro to instantiate a type for serialization testing. +Note: Only use PX_NEW_SERIALIZED once in a scope. +*/ #if PX_CHECKED - /** - Macro to instantiate a type for serialization testing. - Note: Only use PX_NEW_SERIALIZED once in a scope. - */ - #define PX_NEW_SERIALIZED(v,T) \ - void* _buf = physx::PxReflectionAllocator().allocate(sizeof(T),__FILE__,__LINE__); \ - PxMarkSerializedMemory(_buf, sizeof(T)); \ + #define PX_NEW_SERIALIZED(v,T) \ + void* _buf = physx::PxReflectionAllocator().allocate(sizeof(T), PX_FL); \ + PxMarkSerializedMemory(_buf, sizeof(T)); \ v = PX_PLACEMENT_NEW(_buf, T) - #else #define PX_NEW_SERIALIZED(v,T) v = PX_NEW(T) #endif diff --git a/physx/source/common/src/CmVisualization.cpp b/physx/source/common/src/CmVisualization.cpp index b52b41545..058c5bbac 100644 --- a/physx/source/common/src/CmVisualization.cpp +++ b/physx/source/common/src/CmVisualization.cpp @@ -31,6 +31,8 @@ using namespace physx; using namespace Cm; +static const PxU32 gLimitColor = PxU32(PxDebugColor::eARGB_YELLOW); + void Cm::visualizeJointFrames(PxRenderOutput& out, PxReal scale, const PxTransform& parent, const PxTransform& child) { if(scale==0.0f) @@ -41,26 +43,26 @@ void Cm::visualizeJointFrames(PxRenderOutput& out, PxReal scale, const PxTransfo out << child << PxDebugBasis(PxVec3(scale, scale, scale)); } -void Cm::visualizeLinearLimit(PxRenderOutput& out, PxReal scale, const PxTransform& t0, const PxTransform& /*t1*/, PxReal value, bool active) +void Cm::visualizeLinearLimit(PxRenderOutput& out, PxReal scale, const PxTransform& t0, const PxTransform& /*t1*/, PxReal value) { if(scale==0.0f) return; // debug circle is around z-axis, and we want it around x-axis PxTransform r(t0.p+value*t0.q.getBasisVector0(), t0.q*PxQuat(PxPi/2,PxVec3(0,1.f,0))); - out << (active ? PxDebugColor::eARGB_RED : PxDebugColor::eARGB_GREY); + out << gLimitColor; out << PxTransform(PxIdentity); out << PxDebugArrow(t0.p,r.p-t0.p); out << r << PxDebugCircle(20, scale*0.3f); } -void Cm::visualizeAngularLimit(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal lower, PxReal upper, bool active) +void Cm::visualizeAngularLimit(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal lower, PxReal upper) { if(scale==0.0f) return; - out << t << (active ? PxDebugColor::eARGB_RED : PxDebugColor::eARGB_GREY); + out << t << gLimitColor; out << PxRenderOutput::LINES << PxVec3(0) << PxVec3(0, PxCos(lower), PxSin(lower)) * scale @@ -73,12 +75,12 @@ void Cm::visualizeAngularLimit(PxRenderOutput& out, PxReal scale, const PxTransf out << PxVec3(0, PxCos(angle), PxSin(angle)) * scale; } -void Cm::visualizeLimitCone(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ, bool active) +void Cm::visualizeLimitCone(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ) { if(scale==0.0f) return; - out << t << (active ? PxDebugColor::eARGB_RED : PxDebugColor::eARGB_GREY); + out << t << gLimitColor; out << PxRenderOutput::LINES; PxVec3 prev(0,0,0); @@ -99,12 +101,12 @@ void Cm::visualizeLimitCone(PxRenderOutput& out, PxReal scale, const PxTransform } } -void Cm::visualizeDoubleCone(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal angle, bool active) +void Cm::visualizeDoubleCone(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal angle) { if(scale==0.0f) return; - out << t << (active ? PxDebugColor::eARGB_RED : PxDebugColor::eARGB_GREY); + out << t << gLimitColor; const PxReal height = PxTan(angle); diff --git a/physx/source/common/src/CmVisualization.h b/physx/source/common/src/CmVisualization.h index e556cf7c3..95feab087 100644 --- a/physx/source/common/src/CmVisualization.h +++ b/physx/source/common/src/CmVisualization.h @@ -52,28 +52,24 @@ namespace Cm PxReal scale, const PxTransform& t0, const PxTransform& t1, - PxReal value, - bool active); + PxReal value); PX_PHYSX_COMMON_API void visualizeAngularLimit(PxRenderOutput& out, PxReal scale, const PxTransform& t0, PxReal lower, - PxReal upper, - bool active); + PxReal upper); PX_PHYSX_COMMON_API void visualizeLimitCone(PxRenderOutput& out, PxReal scale, const PxTransform& t, PxReal ySwing, - PxReal zSwing, - bool active); + PxReal zSwing); PX_PHYSX_COMMON_API void visualizeDoubleCone(PxRenderOutput& out, PxReal scale, const PxTransform& t, - PxReal angle, - bool active); + PxReal angle); struct ConstraintImmediateVisualizer : public PxConstraintVisualizer { @@ -91,32 +87,32 @@ namespace Cm { } - virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) + virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) PX_OVERRIDE { Cm::visualizeJointFrames(mCmOutput, mFrameScale, parent, child); } - virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value, bool active) + virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value) PX_OVERRIDE { - Cm::visualizeLinearLimit(mCmOutput, mLimitScale, t0, t1, value, active); + Cm::visualizeLinearLimit(mCmOutput, mLimitScale, t0, t1, value); } - virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper, bool active) + virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper) PX_OVERRIDE { - Cm::visualizeAngularLimit(mCmOutput, mLimitScale, t0, lower, upper, active); + Cm::visualizeAngularLimit(mCmOutput, mLimitScale, t0, lower, upper); } - virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ, bool active) + virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ) PX_OVERRIDE { - Cm::visualizeLimitCone(mCmOutput, mLimitScale, t, tanQSwingY, tanQSwingZ, active); + Cm::visualizeLimitCone(mCmOutput, mLimitScale, t, tanQSwingY, tanQSwingZ); } - virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle, bool active) + virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle) PX_OVERRIDE { - Cm::visualizeDoubleCone(mCmOutput, mLimitScale, t, angle, active); + Cm::visualizeDoubleCone(mCmOutput, mLimitScale, t, angle); } - virtual void visualizeLine( const PxVec3& p0, const PxVec3& p1, PxU32 color) + virtual void visualizeLine( const PxVec3& p0, const PxVec3& p1, PxU32 color) PX_OVERRIDE { mCmOutput << color; mCmOutput.outputSegment(p0, p1); diff --git a/physx/source/compiler/cmake/CMakeLists.txt b/physx/source/compiler/cmake/CMakeLists.txt index 665561506..561cb271e 100644 --- a/physx/source/compiler/cmake/CMakeLists.txt +++ b/physx/source/compiler/cmake/CMakeLists.txt @@ -35,9 +35,9 @@ OPTION(PX_GENERATE_STATIC_LIBRARIES "Generate static libraries" OFF) OPTION(PX_EXPORT_LOWLEVEL_PDB "Export low level pdb's" OFF) IF(NOT DEFINED PHYSX_ROOT_DIR) - + STRING(REPLACE "\\" "/" BRD_TEMP $ENV{PHYSX_ROOT_DIR}) - + # This env variable is set by GenerateProjects.bat, and is no longer available when CMake rebuilds, so this stores it in the cache SET(PHYSX_ROOT_DIR ${BRD_TEMP} CACHE INTERNAL "Root of the PhysX source tree") @@ -49,20 +49,6 @@ IF(NOT EXISTS ${PHYSX_ROOT_DIR}) MESSAGE(FATAL_ERROR "PHYSX_ROOT_DIR environment variable wasn't set or was invalid.") ENDIF() -IF(NOT DEFINED CMAKEMODULES_VERSION) - SET(CMAKEMODULES_PATH $ENV{PM_CMakeModules_PATH} CACHE INTERNAL "Path to CMakeModules") - SET(CMAKEMODULES_NAME $ENV{PM_CMakeModules_NAME} CACHE INTERNAL "CMakeModules name") - SET(CMAKEMODULES_VERSION $ENV{PM_CMakeModules_VERSION} CACHE INTERNAL "CMakeModules version from generation batch") -ENDIF() - -#TODO: More elegance -IF(NOT EXISTS ${CMAKEMODULES_PATH}) - MESSAGE(FATAL_ERROR "Could not find ${CMAKEMODULES_PATH}") -ENDIF() - -SET(CMAKE_MODULE_PATH ${CMAKEMODULES_PATH}) - - MESSAGE("PhysX Build Platform: " ${TARGET_BUILD_PLATFORM}) MESSAGE("Using CXX Compiler: " ${CMAKE_CXX_COMPILER}) @@ -71,15 +57,15 @@ INCLUDE(NvidiaBuildOptions) IF(CMAKE_CONFIGURATION_TYPES) SET(CMAKE_CONFIGURATION_TYPES debug checked profile release) SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING - "Reset config to what we need" + "Reset config to what we need" FORCE) - + SET(CMAKE_SHARED_LINKER_FLAGS_CHECKED "") SET(CMAKE_SHARED_LINKER_FLAGS_PROFILE "") # Build PDBs for all configurations SET(CMAKE_SHARED_LINKER_FLAGS "/DEBUG") - + ENDIF() # Prevent failure due to command line limitations diff --git a/physx/source/compiler/cmake/LowLevel.cmake b/physx/source/compiler/cmake/LowLevel.cmake index 88a2f07b2..f50675e35 100644 --- a/physx/source/compiler/cmake/LowLevel.cmake +++ b/physx/source/compiler/cmake/LowLevel.cmake @@ -101,9 +101,7 @@ SET(LL_SOFTWARE_HEADERS ${LL_SOFTWARE_DIR}/include/PxsContactManager.h ${LL_SOFTWARE_DIR}/include/PxsContactManagerState.h ${LL_SOFTWARE_DIR}/include/PxsContext.h - ${LL_SOFTWARE_DIR}/include/PxsDefaultMemoryManager.h ${LL_SOFTWARE_DIR}/include/PxsHeapMemoryAllocator.h - ${LL_SOFTWARE_DIR}/include/PxsIncrementalConstraintPartitioning.h ${LL_SOFTWARE_DIR}/include/PxsIslandManagerTypes.h ${LL_SOFTWARE_DIR}/include/PxsIslandSim.h ${LL_SOFTWARE_DIR}/include/PxsKernelWrangler.h diff --git a/physx/source/compiler/cmake/LowLevelDynamics.cmake b/physx/source/compiler/cmake/LowLevelDynamics.cmake index 1a2625d6c..eec8b4f8b 100644 --- a/physx/source/compiler/cmake/LowLevelDynamics.cmake +++ b/physx/source/compiler/cmake/LowLevelDynamics.cmake @@ -118,10 +118,13 @@ SET(LLDYNAMICS_SOURCE ${LLDYNAMICS_BASE_DIR}/src/DySolverControlPF.h ${LLDYNAMICS_BASE_DIR}/src/DySolverCore.h ${LLDYNAMICS_BASE_DIR}/src/DySolverExt.h - ${LLDYNAMICS_BASE_DIR}/src/DySpatial.h ${LLDYNAMICS_BASE_DIR}/src/DyThreadContext.h ${LLDYNAMICS_BASE_DIR}/src/DyTGSDynamics.h ${LLDYNAMICS_BASE_DIR}/src/DyTGSContactPrep.h + ${LLDYNAMICS_BASE_DIR}/src/DyTGS.h + ${LLDYNAMICS_BASE_DIR}/src/DyPGS.h + ${LLDYNAMICS_BASE_DIR}/src/DySleep.h + ${LLDYNAMICS_BASE_DIR}/src/DySleep.cpp ) SOURCE_GROUP("src" FILES ${LLDYNAMICS_SOURCE}) diff --git a/physx/source/compiler/cmake/PhysX.cmake b/physx/source/compiler/cmake/PhysX.cmake index f7069c39b..a4b5717e3 100644 --- a/physx/source/compiler/cmake/PhysX.cmake +++ b/physx/source/compiler/cmake/PhysX.cmake @@ -53,14 +53,12 @@ SET(PHYSX_HEADERS ${PHYSX_ROOT_DIR}/include/PxArticulationTendonData.h ${PHYSX_ROOT_DIR}/include/PxAttachment.h ${PHYSX_ROOT_DIR}/include/PxBroadPhase.h - ${PHYSX_ROOT_DIR}/include/PxBuffer.h ${PHYSX_ROOT_DIR}/include/PxClient.h ${PHYSX_ROOT_DIR}/include/PxConeLimitedConstraint.h ${PHYSX_ROOT_DIR}/include/PxConstraint.h ${PHYSX_ROOT_DIR}/include/PxConstraintDesc.h ${PHYSX_ROOT_DIR}/include/PxContact.h ${PHYSX_ROOT_DIR}/include/PxContactModifyCallback.h - ${PHYSX_ROOT_DIR}/include/PxCustomParticleSystemSolverCallback.h ${PHYSX_ROOT_DIR}/include/PxDeletionListener.h ${PHYSX_ROOT_DIR}/include/PxFEMParameter.h ${PHYSX_ROOT_DIR}/include/PxFEMClothFlags.h @@ -99,10 +97,15 @@ SET(PHYSX_HEADERS ${PHYSX_ROOT_DIR}/include/PxSoftBodyFlag.h ${PHYSX_ROOT_DIR}/include/PxSparseGridParams.h ${PHYSX_ROOT_DIR}/include/PxVisualizationParameter.h + ${PHYSX_ROOT_DIR}/include/PxIsosurfaceExtraction.h + ${PHYSX_ROOT_DIR}/include/PxSmoothing.h + ${PHYSX_ROOT_DIR}/include/PxAnisotropy.h + ${PHYSX_ROOT_DIR}/include/PxParticleNeighborhoodProvider.h + ${PHYSX_ROOT_DIR}/include/PxArrayConverter.h + ${PHYSX_ROOT_DIR}/include/PxLineStripSkinning.h ) IF(NOT PX_GENERATE_SOURCE_DISTRO AND NOT PUBLIC_RELEASE) LIST(APPEND PHYSX_HEADERS - ${PHYSX_ROOT_DIR}/include/PxCustomParticleSystem.h ${PHYSX_ROOT_DIR}/include/PxFEMCloth.h ${PHYSX_ROOT_DIR}/include/PxFLIPParticleSystem.h ${PHYSX_ROOT_DIR}/include/PxGridParticleSystem.h @@ -206,7 +209,7 @@ SET(PHYSX_PVD_SOURCE ${PX_SOURCE_DIR}/PvdMetaDataBindingData.h ${PX_SOURCE_DIR}/PvdMetaDataPvdBinding.h ${PX_SOURCE_DIR}/PvdPhysicsClient.h - ${PX_SOURCE_DIR}/PvdTypeNames.h + ${PX_SOURCE_DIR}/PvdTypeNames.h ) SOURCE_GROUP(src\\pvd FILES ${PHYSX_PVD_SOURCE}) @@ -274,7 +277,7 @@ SET(PHYSX_CORE_SOURCE ${PX_SOURCE_DIR}/NpActorTemplate.h ${PX_SOURCE_DIR}/NpAggregate.h ${PX_SOURCE_DIR}/NpSoftBody.h - ${PX_SOURCE_DIR}/NpFEMCloth.h + ${PX_SOURCE_DIR}/NpFEMCloth.h ${PX_SOURCE_DIR}/NpParticleSystem.h ${PX_SOURCE_DIR}/NpHairSystem.h ${PX_SOURCE_DIR}/NpConnector.h @@ -310,17 +313,17 @@ ADD_LIBRARY(PhysX ${PHYSX_LIBTYPE} ${PHYSX_PVD_SOURCE} ${PHYSX_SOLVER_HEADERS} ${PHYSX_COLLISION_HEADERS} - + ${PHYSX_METADATA_HEADERS} ${PHYSX_METADATA_SOURCE} - + ${PHYSX_CORE_SOURCE} ${PHYSX_BUFFERING_SOURCE} ${PHYSX_IMMEDIATEMODE_SOURCE} ${PHYSX_MATERIALS_SOURCE} ${PHYSX_ARTICULATIONS_SOURCE} - - ${PHYSX_PLATFORM_SRC_FILES} + + ${PHYSX_PLATFORM_SRC_FILES} ) # Add the headers to the install @@ -334,7 +337,7 @@ INSTALL(FILES ${PHYSX_SOLVER_HEADERS} DESTINATION include/solver) # install the custom config file INSTALL(FILES ${PHYSX_ROOT_DIR}/include/PxConfig.h DESTINATION include) -TARGET_INCLUDE_DIRECTORIES(PhysX +TARGET_INCLUDE_DIRECTORIES(PhysX PRIVATE ${PHYSX_PLATFORM_INCLUDES} PRIVATE ${PHYSX_ROOT_DIR}/include @@ -344,9 +347,9 @@ TARGET_INCLUDE_DIRECTORIES(PhysX PRIVATE ${PHYSX_SOURCE_DIR}/physx/src PRIVATE ${PHYSX_SOURCE_DIR}/physx/src/device - PRIVATE ${PHYSX_SOURCE_DIR}/physxgpu/include - + + PRIVATE ${PHYSX_SOURCE_DIR}/geomutils/include PRIVATE ${PHYSX_SOURCE_DIR}/geomutils/src PRIVATE ${PHYSX_SOURCE_DIR}/geomutils/src/contact @@ -360,32 +363,36 @@ TARGET_INCLUDE_DIRECTORIES(PhysX PRIVATE ${PHYSX_SOURCE_DIR}/geomutils/src/hf PRIVATE ${PHYSX_SOURCE_DIR}/geomutils/src/pcm PRIVATE ${PHYSX_SOURCE_DIR}/geomutils/src/ccd - + PRIVATE ${PHYSX_SOURCE_DIR}/lowlevel/api/include PRIVATE ${PHYSX_SOURCE_DIR}/lowlevel/software/include PRIVATE ${PHYSX_SOURCE_DIR}/lowlevel/common/include/pipeline PRIVATE ${PHYSX_SOURCE_DIR}/lowlevel/common/include/utils PRIVATE ${PHYSX_SOURCE_DIR}/lowlevelaabb/include - + PRIVATE ${PHYSX_SOURCE_DIR}/lowleveldynamics/include PRIVATE ${PHYSX_SOURCE_DIR}/simulationcontroller/include PRIVATE ${PHYSX_SOURCE_DIR}/simulationcontroller/src - + PRIVATE ${PHYSX_SOURCE_DIR}/scenequery/include - + PRIVATE ${PHYSX_SOURCE_DIR}/physxmetadata/core/include PRIVATE ${PHYSX_SOURCE_DIR}/immediatemode/include PRIVATE ${PHYSX_SOURCE_DIR}/pvd/include - + + PRIVATE ${PHYSX_SOURCE_DIR}/gpucommon/include + PRIVATE ${PHYSX_SOURCE_DIR}/gpucommon/src/DX + PRIVATE ${PHYSX_SOURCE_DIR}/gpucommon/src/CUDA + PRIVATE ${PHYSX_SOURCE_DIR}/omnipvd PRIVATE ${PHYSX_ROOT_DIR}/pvdruntime/include ) -TARGET_COMPILE_DEFINITIONS(PhysX +TARGET_COMPILE_DEFINITIONS(PhysX # Common to all configurations PRIVATE ${PHYSX_COMPILE_DEFS} @@ -397,7 +404,7 @@ SET_TARGET_PROPERTIES(PhysX PROPERTIES ) IF(NV_USE_GAMEWORKS_OUTPUT_DIRS AND PHYSX_LIBTYPE STREQUAL "STATIC") - SET_TARGET_PROPERTIES(PhysX PROPERTIES + SET_TARGET_PROPERTIES(PhysX PROPERTIES ARCHIVE_OUTPUT_NAME_DEBUG "PhysX_static" ARCHIVE_OUTPUT_NAME_CHECKED "PhysX_static" ARCHIVE_OUTPUT_NAME_PROFILE "PhysX_static" @@ -406,7 +413,7 @@ IF(NV_USE_GAMEWORKS_OUTPUT_DIRS AND PHYSX_LIBTYPE STREQUAL "STATIC") ENDIF() IF(PHYSX_COMPILE_PDB_NAME_DEBUG) - SET_TARGET_PROPERTIES(PhysX PROPERTIES + SET_TARGET_PROPERTIES(PhysX PROPERTIES COMPILE_PDB_NAME_DEBUG "${PHYSX_COMPILE_PDB_NAME_DEBUG}" COMPILE_PDB_NAME_CHECKED "${PHYSX_COMPILE_PDB_NAME_CHECKED}" COMPILE_PDB_NAME_PROFILE "${PHYSX_COMPILE_PDB_NAME_PROFILE}" @@ -414,13 +421,13 @@ IF(PHYSX_COMPILE_PDB_NAME_DEBUG) ) ENDIF() -TARGET_LINK_LIBRARIES(PhysX +TARGET_LINK_LIBRARIES(PhysX PRIVATE ${PHYSX_PRIVATE_PLATFORM_LINKED_LIBS} PRIVATE PhysXPvdSDK PhysXCommon PhysXFoundation PUBLIC ${PHYSX_PLATFORM_LINKED_LIBS} ) -SET_TARGET_PROPERTIES(PhysX PROPERTIES +SET_TARGET_PROPERTIES(PhysX PROPERTIES LINK_FLAGS "${PHYSX_PLATFORM_LINK_FLAGS}" LINK_FLAGS_DEBUG "${PHYSX_PLATFORM_LINK_FLAGS_DEBUG}" LINK_FLAGS_CHECKED "${PHYSX_PLATFORM_LINK_FLAGS_CHECKED}" @@ -437,12 +444,12 @@ IF(PX_GENERATE_SOURCE_DISTRO) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_OMNIPVD_SOURCE}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_PVD_SOURCE}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_METADATA_HEADERS}) - LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_METADATA_SOURCE}) + LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_METADATA_SOURCE}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_CORE_SOURCE}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_BUFFERING_SOURCE}) - LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_IMMEDIATEMODE_SOURCE}) - LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_MATERIALS_SOURCE}) - LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_ARTICULATIONS_SOURCE}) + LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_IMMEDIATEMODE_SOURCE}) + LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_MATERIALS_SOURCE}) + LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_ARTICULATIONS_SOURCE}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_PLATFORM_SRC_FILES}) LIST(APPEND SOURCE_DISTRO_FILE_LIST ${PHYSX_SOLVER_HEADERS}) ENDIF() diff --git a/physx/source/compiler/cmake/PhysXCommon.cmake b/physx/source/compiler/cmake/PhysXCommon.cmake index 248fa22f5..a6426133d 100644 --- a/physx/source/compiler/cmake/PhysXCommon.cmake +++ b/physx/source/compiler/cmake/PhysXCommon.cmake @@ -295,11 +295,7 @@ SET(PHYSXCOMMON_GU_DISTANCE_SOURCE ${GU_SOURCE_DIR}/src/distance/GuDistancePointTetrahedron.cpp ${GU_SOURCE_DIR}/src/distance/GuDistancePointBox.h ${GU_SOURCE_DIR}/src/distance/GuDistancePointSegment.h - ${GU_SOURCE_DIR}/src/distance/GuDistancePointTriangle.h - ${GU_SOURCE_DIR}/src/distance/GuDistancePointTriangleSIMD.h - ${GU_SOURCE_DIR}/src/distance/GuDistanceSegmentSegmentSIMD.h ${GU_SOURCE_DIR}/src/distance/GuDistanceSegmentTriangle.h - ${GU_SOURCE_DIR}/src/distance/GuDistanceSegmentTriangleSIMD.h ${GU_SOURCE_DIR}/src/distance/GuDistancePointTetrahedron.h ) SOURCE_GROUP(geomutils\\src\\distance FILES ${PHYSXCOMMON_GU_DISTANCE_SOURCE}) @@ -356,7 +352,6 @@ SET(PHYSXCOMMON_GU_INTERSECTION_SOURCE ${GU_SOURCE_DIR}/src/intersection/GuIntersectionEdgeEdge.h ${GU_SOURCE_DIR}/src/intersection/GuIntersectionRay.h ${GU_SOURCE_DIR}/src/intersection/GuIntersectionRayBox.h - ${GU_SOURCE_DIR}/src/intersection/GuIntersectionRayBoxSIMD.h ${GU_SOURCE_DIR}/src/intersection/GuIntersectionRayCapsule.h ${GU_SOURCE_DIR}/src/intersection/GuIntersectionRayPlane.h ${GU_SOURCE_DIR}/src/intersection/GuIntersectionRaySphere.h @@ -396,6 +391,7 @@ SET(PHYSXCOMMON_GU_MESH_SOURCE ${GU_SOURCE_DIR}/src/mesh/GuBV32.cpp ${GU_SOURCE_DIR}/src/mesh/GuBV32Build.cpp ${GU_SOURCE_DIR}/src/mesh/GuTetrahedronMesh.cpp + ${GU_SOURCE_DIR}/src/mesh/GuTetrahedronMeshUtils.cpp ${GU_SOURCE_DIR}/src/mesh/GuBV32.h ${GU_SOURCE_DIR}/src/mesh/GuBV32Build.h ${GU_SOURCE_DIR}/src/mesh/GuBV4.h @@ -434,6 +430,7 @@ SET(PHYSXCOMMON_GU_MESH_SOURCE ${GU_SOURCE_DIR}/src/mesh/GuTriangleMeshRTree.h ${GU_SOURCE_DIR}/src/mesh/GuTetrahedron.h ${GU_SOURCE_DIR}/src/mesh/GuTetrahedronMesh.h + ${GU_SOURCE_DIR}/src/mesh/GuTetrahedronMeshUtils.h ) SOURCE_GROUP(geomutils\\src\\mesh FILES ${PHYSXCOMMON_GU_MESH_SOURCE}) diff --git a/physx/source/compiler/cmake/PhysXExtensions.cmake b/physx/source/compiler/cmake/PhysXExtensions.cmake index df33098f6..4b5d25f87 100644 --- a/physx/source/compiler/cmake/PhysXExtensions.cmake +++ b/physx/source/compiler/cmake/PhysXExtensions.cmake @@ -78,9 +78,13 @@ SET(PHYSX_EXTENSIONS_SOURCE ) #TODO, create a propper define for whether GPU features are enabled or not! -IF ((PUBLIC_RELEASE OR PX_GENERATE_GPU_PROJECTS) AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) +IF ((PUBLIC_RELEASE OR PX_GENERATE_GPU_PROJECTS) AND (NOT CMAKE_CROSSCOMPILING)) LIST(APPEND PHYSX_EXTENSIONS_SOURCE "${LL_SOURCE_DIR}/ExtParticleExt.cpp") LIST(APPEND PHYSX_EXTENSIONS_SOURCE "${LL_SOURCE_DIR}/ExtParticleClothCooker.cpp") + + IF(NOT PX_GENERATE_SOURCE_DISTRO AND NOT PUBLIC_RELEASE) + LIST(APPEND PHYSX_EXTENSIONS_SOURCE "${LL_SOURCE_DIR}/ExtFEMClothExt.cpp") + ENDIF() ENDIF() SOURCE_GROUP(src FILES ${PHYSX_EXTENSIONS_SOURCE}) @@ -198,10 +202,19 @@ SET(PHYSX_EXTENSIONS_HEADERS ${PHYSX_ROOT_DIR}/include/extensions/PxSamplingExt.h ) + + #TODO, create a propper define for whether GPU features are enabled or not! -IF ((PUBLIC_RELEASE OR PX_GENERATE_GPU_PROJECTS) AND (CMAKE_SIZEOF_VOID_P EQUAL 8)) +IF ((PUBLIC_RELEASE OR PX_GENERATE_GPU_PROJECTS) AND (NOT CMAKE_CROSSCOMPILING)) LIST(APPEND PHYSX_EXTENSIONS_HEADERS "${PHYSX_ROOT_DIR}/include/extensions/PxParticleClothCooker.h") LIST(APPEND PHYSX_EXTENSIONS_HEADERS "${PHYSX_ROOT_DIR}/include/extensions/PxParticleExt.h") + + IF(NOT PX_GENERATE_SOURCE_DISTRO AND NOT PUBLIC_RELEASE) + LIST(APPEND PHYSX_EXTENSIONS_HEADERS + ${PHYSX_ROOT_DIR}/include/extensions/PxFEMClothExt.h + ) +ENDIF() + ENDIF() SOURCE_GROUP(include FILES ${PHYSX_EXTENSIONS_HEADERS}) diff --git a/physx/source/compiler/cmake/SimulationController.cmake b/physx/source/compiler/cmake/SimulationController.cmake index b1ff286f5..cb24d1d16 100644 --- a/physx/source/compiler/cmake/SimulationController.cmake +++ b/physx/source/compiler/cmake/SimulationController.cmake @@ -42,6 +42,7 @@ SET(SIMULATIONCONTROLLER_HEADERS ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScArticulationJointCore.h ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScArticulationSensor.h ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScBodyCore.h + ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScBroadphase.h ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScConstraintCore.h ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScIterators.h ${SIMULATIONCONTROLLER_BASE_DIR}/include/ScPhysics.h @@ -77,6 +78,7 @@ SET(SIMULATIONCONTROLLER_SOURCE ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScArticulationTendonSim.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScArticulationSensorSim.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScArticulationSensorSim.h + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScBroadphase.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScSoftBodyCore.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScSoftBodySim.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScSoftBodySim.h @@ -87,6 +89,8 @@ SET(SIMULATIONCONTROLLER_SOURCE ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScFEMClothSim.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScFEMClothShapeSim.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScFEMClothShapeSim.h + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScFiltering.cpp + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScFiltering.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScParticleSystemCore.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScParticleSystemSim.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScParticleSystemSim.h @@ -104,15 +108,10 @@ SET(SIMULATIONCONTROLLER_SOURCE ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScBodyCore.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScBodySim.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScBodySim.h + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintBreakage.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintCore.cpp - ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintGroupNode.cpp - ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintGroupNode.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintInteraction.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintInteraction.h - ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintProjectionManager.cpp - ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintProjectionManager.h - ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintProjectionTree.cpp - ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintProjectionTree.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintSim.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScConstraintSim.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScContactReportBuffer.h @@ -126,6 +125,7 @@ SET(SIMULATIONCONTROLLER_SOURCE ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScInteraction.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScInteractionFlags.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScIterators.cpp + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScKinematics.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScMetaData.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScNPhaseCore.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScNPhaseCore.h @@ -155,6 +155,9 @@ SET(SIMULATIONCONTROLLER_SOURCE ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScTriggerInteraction.cpp ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScTriggerInteraction.h ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScTriggerPairs.h + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScVisualize.cpp + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScSleep.cpp + ${SIMULATIONCONTROLLER_BASE_DIR}/src/ScPipeline.cpp ) SOURCE_GROUP(src FILES ${SIMULATIONCONTROLLER_SOURCE}) diff --git a/physx/source/compiler/cmake/linux/CMakeLists.txt b/physx/source/compiler/cmake/linux/CMakeLists.txt index b0a509a35..885e43285 100644 --- a/physx/source/compiler/cmake/linux/CMakeLists.txt +++ b/physx/source/compiler/cmake/linux/CMakeLists.txt @@ -32,15 +32,12 @@ SET(CLANG_WARNINGS "-ferror-limit=0 -Wall -Wextra -Werror -Wstrict-aliasing=2 -W -Wno-atomic-implicit-seq-cst \ -Wno-c++98-compat-pedantic \ -Wno-cast-align \ - -Wno-cast-qual \ -Wno-conversion \ -Wno-covered-switch-default \ -Wno-deprecated \ - -Wno-disabled-macro-expansion \ -Wno-documentation-deprecated-sync \ -Wno-documentation-unknown-command \ -Wno-exit-time-destructors \ - -Wno-error=undefined-func-template \ -Wno-extra-semi-stmt \ -Wno-float-equal \ -Wno-format-nonliteral \ @@ -49,24 +46,19 @@ SET(CLANG_WARNINGS "-ferror-limit=0 -Wall -Wextra -Werror -Wstrict-aliasing=2 -W -Wno-implicit-fallthrough \ -Wno-inconsistent-missing-destructor-override \ -Wno-inconsistent-missing-override \ - -Wno-invalid-noreturn \ -Wno-missing-noreturn \ -Wno-missing-prototypes \ -Wno-missing-variable-declarations \ - -Wno-nested-anon-types \ -Wno-newline-eof \ -Wno-non-virtual-dtor \ -Wno-old-style-cast \ -Wno-padded \ -Wno-reserved-id-macro \ - -Wno-return-type-c-linkage \ -Wno-shadow \ - -Wno-shift-sign-overflow \ -Wno-suggest-destructor-override \ -Wno-suggest-override \ -Wno-switch-enum \ -Wno-undef \ - -Wno-undefined-func-template \ -Wno-undefined-reinterpret-cast \ -Wno-unknown-pragmas \ -Wno-unknown-warning-option \ @@ -80,6 +72,8 @@ SET(CLANG_WARNINGS "-ferror-limit=0 -Wall -Wextra -Werror -Wstrict-aliasing=2 -W -Wno-weak-template-vtables \ -Wno-weak-vtables \ -Wno-zero-as-null-pointer-constant \ + -Wno-reserved-identifier \ + -Wno-undefined-func-template \ ") @@ -105,15 +99,20 @@ ELSE() -Wno-pragmas\ -Wno-uninitialized\ -Wno-unused-function\ + -Wno-stringop-overflow\ ") SET(AARCH64_FLAGS "") ENDIF() IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # using Clang - SET(PHYSX_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fstrict-aliasing ${AARCH64_FLAGS} ${CLANG_WARNINGS}" CACHE INTERNAL "PhysX CXX") + IF ("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "10.0.0") + SET(PHYSX_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fstrict-aliasing -fvisibility=hidden ${AARCH64_FLAGS} ${CLANG_WARNINGS}" CACHE INTERNAL "PhysX CXX") + ELSE() + SET(PHYSX_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fstrict-aliasing -fvisibility=hidden -ffp-exception-behavior=maytrap ${AARCH64_FLAGS} ${CLANG_WARNINGS}" CACHE INTERNAL "PhysX CXX") + ENDIF() ELSEIF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - SET(PHYSX_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fno-strict-aliasing ${AARCH64_FLAGS} ${GCC_WARNINGS}" CACHE INTERNAL "PhysX CXX") + SET(PHYSX_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fno-strict-aliasing -fvisibility=hidden ${AARCH64_FLAGS} ${GCC_WARNINGS}" CACHE INTERNAL "PhysX CXX") ENDIF() # Build debug info for all configurations @@ -143,7 +142,7 @@ IF(${CMAKE_CROSSCOMPILING} AND CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64") ELSE() SET(PX_SUPPORT_OMNI_PVD_FLAG "PX_SUPPORT_OMNI_PVD=1") ENDIF() -SET(PHYSX_LINUX_COMPILE_DEFS "${CUDA_FLAG};${PHYSX_AUTOBUILD};${PUBLIC_RELEASE_FLAG};${FEATURES_UNDER_CONSTRUCTION_FLAG}" CACHE INTERNAL "Base PhysX preprocessor definitions") +SET(PHYSX_LINUX_COMPILE_DEFS "${PHYSX_AUTOBUILD};${PUBLIC_RELEASE_FLAG};${FEATURES_UNDER_CONSTRUCTION_FLAG}" CACHE INTERNAL "Base PhysX preprocessor definitions") SET(PHYSX_LINUX_DEBUG_COMPILE_DEFS "NDEBUG;PX_DEBUG=1;PX_CHECKED=1;${NVTX_FLAG};PX_SUPPORT_PVD=1;${PX_SUPPORT_OMNI_PVD_FLAG}" CACHE INTERNAL "Debug PhysX preprocessor definitions") SET(PHYSX_LINUX_CHECKED_COMPILE_DEFS "NDEBUG;PX_CHECKED=1;${NVTX_FLAG};PX_SUPPORT_PVD=1;${PX_SUPPORT_OMNI_PVD_FLAG}" CACHE INTERNAL "Checked PhysX preprocessor definitions") SET(PHYSX_LINUX_PROFILE_COMPILE_DEFS "NDEBUG;PX_PROFILE=1;${NVTX_FLAG};PX_SUPPORT_PVD=1;${PX_SUPPORT_OMNI_PVD_FLAG}" CACHE INTERNAL "Profile PhysX preprocessor definitions") @@ -189,9 +188,6 @@ ELSE() INCLUDE(PhysXCommon.cmake) INCLUDE(PhysXCooking.cmake) INCLUDE(PhysXExtensions.cmake) -IF(NOT ${CMAKE_CROSSCOMPILING} AND NOT PUBLIC_RELEASE) - INCLUDE(PhysXGPUExtensions.cmake) -ENDIF() INCLUDE(PhysXVehicle.cmake) INCLUDE(PhysXVehicle2.cmake) INCLUDE(SceneQuery.cmake) @@ -206,9 +202,6 @@ ENDIF() SET_PROPERTY(TARGET PhysXCommon PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXCooking PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXExtensions PROPERTY FOLDER "PhysX SDK") -IF(NOT ${CMAKE_CROSSCOMPILING} AND NOT PUBLIC_RELEASE) - SET_PROPERTY(TARGET PhysXGPUExtensions PROPERTY FOLDER "PhysX SDK") -ENDIF() SET_PROPERTY(TARGET PhysXVehicle PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXVehicle2 PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET LowLevel PROPERTY FOLDER "PhysX SDK") @@ -221,11 +214,9 @@ ENDIF() SET_PROPERTY(TARGET PhysXTask PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXFoundation PROPERTY FOLDER "PhysX SDK") -IF(NOT ${CMAKE_CROSSCOMPILING} AND NOT PUBLIC_RELEASE) - SET(PHYSXDISTRO_LIBS PhysXFoundation PhysX PhysXCharacterKinematic PhysXPvdSDK PhysXCommon PhysXCooking PhysXExtensions PhysXVehicle PhysXVehicle2 PhysXGPUExtensions) -ELSE() + SET(PHYSXDISTRO_LIBS PhysXFoundation PhysX PhysXCharacterKinematic PhysXPvdSDK PhysXCommon PhysXCooking PhysXExtensions PhysXVehicle PhysXVehicle2) -ENDIF() + INSTALL( TARGETS ${PHYSXDISTRO_LIBS} diff --git a/physx/source/compiler/cmake/linux/PhysX.cmake b/physx/source/compiler/cmake/linux/PhysX.cmake index fba10f54a..805570bc2 100644 --- a/physx/source/compiler/cmake/linux/PhysX.cmake +++ b/physx/source/compiler/cmake/linux/PhysX.cmake @@ -30,6 +30,7 @@ SET(PHYSX_GPU_HEADERS ${PHYSX_ROOT_DIR}/include/gpu/PxGpu.h + ${PHYSX_ROOT_DIR}/include/gpu/PxPhysicsGpu.h ) SOURCE_GROUP(include\\gpu FILES ${PHYSX_GPU_HEADERS}) diff --git a/physx/source/compiler/cmake/modules/ConfigureFileMT.cmake b/physx/source/compiler/cmake/modules/ConfigureFileMT.cmake new file mode 100644 index 000000000..94b747f8e --- /dev/null +++ b/physx/source/compiler/cmake/modules/ConfigureFileMT.cmake @@ -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. + +# A simple wrapper around configure_file to try to make it multi-thread safe with a file lock. +FUNCTION(Configure_File_MT IN_TEMPLATE OUTPUT_FILENAME) + + FILE(LOCK ${OUTPUT_FILENAME}.lock + GUARD FUNCTION + RESULT_VARIABLE LOCK_RESULT + TIMEOUT 30) + + IF (NOT LOCK_RESULT EQUAL 0) + MESSAGE(WARNING "Failed to lock file ${OUTPUT_FILENAME} for output ERROR: ${LOCK_RESULT}") + return() + ENDIF() + + CONFIGURE_FILE("${IN_TEMPLATE}" "${OUTPUT_FILENAME}" @ONLY) + + FILE(LOCK ${OUTPUT_FILENAME}.lock RELEASE) + +ENDFUNCTION() \ No newline at end of file diff --git a/physx/source/compiler/cmake/modules/GetCompilerAndPlatform.cmake b/physx/source/compiler/cmake/modules/GetCompilerAndPlatform.cmake new file mode 100644 index 000000000..e598c6ea1 --- /dev/null +++ b/physx/source/compiler/cmake/modules/GetCompilerAndPlatform.cmake @@ -0,0 +1,142 @@ +## 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. + +FUNCTION(CompilerDumpVersion _OUTPUT_VERSION) + + EXEC_PROGRAM(${CMAKE_CXX_COMPILER} + ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion + OUTPUT_VARIABLE COMPILER_VERSION + ) + STRING(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" + COMPILER_VERSION ${COMPILER_VERSION}) + + SET(${_OUTPUT_VERSION} ${COMPILER_VERSION}) +ENDFUNCTION() + +FUNCTION(GetCompiler _ret) + SET(COMPILER_SUFFIX "UNKNOWN") + + IF(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" + OR CMAKE_CXX_COMPILER MATCHES "icl" + OR CMAKE_CXX_COMPILER MATCHES "icpc") + IF(WIN32) + SET (COMPILER_SUFFIX "iw") + ELSE() + SET (COMPILER_SUFFIX "il") + ENDIF() + ELSEIF (GHSMULTI) + SET(COMPILER_SUFFIX "ghs") + ELSEIF(MSVC_VERSION GREATER_EQUAL 1930) + SET(COMPILER_SUFFIX "vc143") + ELSEIF (MSVC_VERSION GREATER_EQUAL 1920) + SET(COMPILER_SUFFIX "vc142") + ELSEIF (MSVC_VERSION GREATER_EQUAL 1910) + SET(COMPILER_SUFFIX "vc141") + ELSEIF (MSVC14) + SET(COMPILER_SUFFIX "vc140") + ELSEIF (MSVC12) + SET(COMPILER_SUFFIX "vc120") + ELSEIF (MSVC11) + SET(COMPILER_SUFFIX "vc110") + ELSEIF (MSVC10) + SET(COMPILER_SUFFIX "vc100") + ELSEIF (MSVC90) + SET(COMPILER_SUFFIX "vc90") + ELSEIF (MSVC80) + SET(COMPILER_SUFFIX "vc80") + ELSEIF (MSVC71) + SET(COMPILER_SUFFIX "vc71") + ELSEIF (MSVC70) # Good luck! + SET(COMPILER_SUFFIX "vc7") # yes, this is correct + ELSEIF (MSVC60) # Good luck! + SET(COMPILER_SUFFIX "vc6") # yes, this is correct + ELSEIF (BORLAND) + SET(COMPILER_SUFFIX "bcb") + ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + SET(COMPILER_SUFFIX "sw") + ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "XL") + SET(COMPILER_SUFFIX "xlc") + ELSEIF (MINGW) + CompilerDumpVersion(_COMPILER_VERSION) + SET(COMPILER_SUFFIX "mgw${_COMPILER_VERSION}") + ELSEIF (UNIX) + IF (CMAKE_COMPILER_IS_GNUCXX) + CompilerDumpVersion(_COMPILER_VERSION) + IF(APPLE) + # on Mac OS X/Darwin is "xgcc". + SET(COMPILER_SUFFIX "xgcc${_COMPILER_VERSION}") + ELSE() + SET(COMPILER_SUFFIX "gcc${_COMPILER_VERSION}") + ENDIF() + ENDIF() + ELSE() + # add clang! + SET(COMPILER_SUFFIX "") + ENDIF() + + SET(${_ret} ${COMPILER_SUFFIX} PARENT_SCOPE) +ENDFUNCTION() + +FUNCTION(GetStaticCRTString _ret) + IF(NOT TARGET_BUILD_PLATFORM STREQUAL "windows") + return() + ENDIF() + + IF (NV_USE_STATIC_WINCRT) + SET(CRT_STRING "mt") + ELSE() + SET(CRT_STRING "md") + ENDIF() + + SET(${_ret} ${CRT_STRING} PARENT_SCOPE) +ENDFUNCTION() + +FUNCTION (GetPlatformBinName PLATFORM_BIN_NAME LIBPATH_SUFFIX) + SET(RETVAL "UNKNOWN") + + GetCompiler(COMPILER) + + IF(TARGET_BUILD_PLATFORM STREQUAL "windows") + GetStaticCRTString(CRT_STRING) + SET(RETVAL "win.x86_${LIBPATH_SUFFIX}.${COMPILER}.${CRT_STRING}") + ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "mac") + SET(RETVAL "mac.x86_${LIBPATH_SUFFIX}") + ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "switch") + IF (${CMAKE_GENERATOR_PLATFORM} STREQUAL "NX32") + SET(RETVAL "switch32") + ELSEIF (${CMAKE_GENERATOR_PLATFORM} STREQUAL "NX64") + SET(RETVAL "switch64") + ENDIF() + ELSEIF(TARGET_BUILD_PLATFORM STREQUAL "linux") + IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64") + SET(RETVAL "linux.clang") + ELSEIF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64") + SET(RETVAL "linux.aarch64") + ENDIF() + ENDIF() + + SET(${PLATFORM_BIN_NAME} ${RETVAL} PARENT_SCOPE) +ENDFUNCTION() diff --git a/physx/source/compiler/cmake/modules/NvidiaBuildOptions.cmake b/physx/source/compiler/cmake/modules/NvidiaBuildOptions.cmake new file mode 100644 index 000000000..1a3bf5271 --- /dev/null +++ b/physx/source/compiler/cmake/modules/NvidiaBuildOptions.cmake @@ -0,0 +1,250 @@ +## 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. + +# Define the options up front + +OPTION(NV_APPEND_CONFIG_NAME "Append config (DEBUG, CHECKED, PROFILE or '' for release) to outputted binaries." OFF) +OPTION(NV_USE_GAMEWORKS_OUTPUT_DIRS "Use new GameWorks folder structure for binary output." ON) +OPTION(NV_USE_STATIC_WINCRT "Use the statically linked windows CRT" OFF) +OPTION(NV_USE_DEBUG_WINCRT "Use the debug version of the CRT" OFF) +OPTION(NV_FORCE_64BIT_SUFFIX "Force a 64 bit suffix for platforms that don't register properly." OFF) +OPTION(NV_FORCE_32BIT_SUFFIX "Force a 32 bit suffix for platforms that don't register properly." OFF) + +INCLUDE(SetOutputPaths) + + +IF(NV_USE_GAMEWORKS_OUTPUT_DIRS) + + IF(NV_FORCE_32BIT_SUFFIX AND NV_FORCE_64BIT_SUFFIX) + MESSAGE(FATAL_ERROR "Cannot specify both NV_FORCE_64BIT_SUFFIX and NV_FORCE_32BIT_SUFFIX. Choose one.") + ENDIF() + + IF(SUPPRESS_SUFFIX) + MESSAGE("Suppressing binary suffixes.") + SET(LIBPATH_SUFFIX "NONE") + # Set default exe suffix. Unset on platforms that don't need it. Include underscore since it's optional + SET(EXE_SUFFIX "") + ELSEIF(NV_FORCE_32BIT_SUFFIX) + MESSAGE("Forcing binary suffixes to 32 bit.") + SET(LIBPATH_SUFFIX "32") + # Set default exe suffix. Unset on platforms that don't need it. Include underscore since it's optional + SET(EXE_SUFFIX "_32") + ELSEIF(NV_FORCE_64BIT_SUFFIX) + MESSAGE("Forcing binary suffixes to 64 bit.") + SET(LIBPATH_SUFFIX "64") + # Set default exe suffix. Unset on platforms that don't need it. Include underscore since it's optional + SET(EXE_SUFFIX "_64") + ELSE() + # New bitness suffix + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(LIBPATH_SUFFIX "64") + # Set default exe suffix. Unset on platforms that don't need it. Include underscore since it's optional + SET(EXE_SUFFIX "_64") + ELSE() + SET(LIBPATH_SUFFIX "32") + # Set default exe suffix. Unset on platforms that don't need it. Include underscore since it's optional + SET(EXE_SUFFIX "_32") + ENDIF() + ENDIF() + + IF (NOT DEFINED PX_OUTPUT_LIB_DIR) + MESSAGE(FATAL_ERROR "When using the GameWorks output structure you must specify PX_OUTPUT_LIB_DIR as the base") + ENDIF() + + IF (NOT DEFINED PX_OUTPUT_BIN_DIR) + MESSAGE(FATAL_ERROR "When using the GameWorks output structure you must specify PX_OUTPUT_BIN_DIR as the base") + ENDIF() + + # Set the WINCRT_DEBUG and WINCRT_NDEBUG variables for use in project compile settings + # Really only relevant to windows + + SET(DISABLE_ITERATOR_DEBUGGING "/D \"_HAS_ITERATOR_DEBUGGING=0\" /D \"_ITERATOR_DEBUG_LEVEL=0\"") + SET(DISABLE_ITERATOR_DEBUGGING_CUDA "-D_HAS_ITERATOR_DEBUGGING=0 -D_ITERATOR_DEBUG_LEVEL=0") + SET(CRT_DEBUG_FLAG "/D \"_DEBUG\"") + SET(CRT_NDEBUG_FLAG "/D \"NDEBUG\"") + + # Need a different format for CUDA + SET(CUDA_DEBUG_FLAG "-DNDEBUG ${DISABLE_ITERATOR_DEBUGGING_CUDA}") + SET(CUDA_NDEBUG_FLAG "-DNDEBUG") + + SET(CUDA_CRT_COMPILE_OPTIONS_NDEBUG "") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "") + + + IF(NV_USE_STATIC_WINCRT) + SET(WINCRT_NDEBUG "/MT ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_NDEBUG "/MT") + + IF (NV_USE_DEBUG_WINCRT) + SET(CUDA_DEBUG_FLAG "-D_DEBUG") + SET(WINCRT_DEBUG "/MTd ${CRT_DEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MTd") + ELSE() + SET(WINCRT_DEBUG "/MT ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MT") + ENDIF() + ELSE() + SET(WINCRT_NDEBUG "/MD ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}") + SET(CUDA_CRT_COMPILE_OPTIONS_NDEBUG "/MD") + + IF(NV_USE_DEBUG_WINCRT) + SET(CUDA_DEBUG_FLAG "-D_DEBUG") + SET(WINCRT_DEBUG "/MDd ${CRT_DEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MDd") + ELSE() + SET(WINCRT_DEBUG "/MD ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MD") + ENDIF() + ENDIF() + + INCLUDE(GetCompilerAndPlatform) + + GetPlatformBinName(PLATFORM_BIN_NAME ${LIBPATH_SUFFIX}) + + + SET(PX_ROOT_LIB_DIR "bin/${PLATFORM_BIN_NAME}" CACHE INTERNAL "Relative root of the lib output directory") + SET(PX_ROOT_EXE_DIR "bin/${PLATFORM_BIN_NAME}" CACHE INTERNAL "Relative root dir of the exe output directory") + + IF (NOT DEFINED PX_OUTPUT_ARCH) # platforms with fixed arch like ps4 dont need to have arch defined + SET(EXE_SUFFIX "") + ENDIF() + + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/debug" ) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/profile" ) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/checked" ) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/release" ) + + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/debug" ) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/profile" ) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/checked" ) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${PX_OUTPUT_LIB_DIR}/${PX_ROOT_LIB_DIR}/release" ) + + # RFC 108, we're doing EXEs as the special case since there will be presumable be less of those. + SET(PX_EXE_OUTPUT_DIRECTORY_DEBUG "${PX_OUTPUT_BIN_DIR}/${PX_ROOT_EXE_DIR}/debug" CACHE INTERNAL "Directory to put debug exes in") + SET(PX_EXE_OUTPUT_DIRECTORY_PROFILE "${PX_OUTPUT_BIN_DIR}/${PX_ROOT_EXE_DIR}/profile" CACHE INTERNAL "Directory to put profile exes in") + SET(PX_EXE_OUTPUT_DIRECTORY_CHECKED "${PX_OUTPUT_BIN_DIR}/${PX_ROOT_EXE_DIR}/checked" CACHE INTERNAL "Directory to put checked exes in") + SET(PX_EXE_OUTPUT_DIRECTORY_RELEASE "${PX_OUTPUT_BIN_DIR}/${PX_ROOT_EXE_DIR}/release" CACHE INTERNAL "Directory to put release exes in") + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG} ) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE} ) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED} ) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE} ) + + +ELSE() + # old bitness suffix + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(LIBPATH_SUFFIX "x64") + ELSE() + SET(LIBPATH_SUFFIX "x86") + ENDIF() + + SET(DISABLE_ITERATOR_DEBUGGING "/D \"_HAS_ITERATOR_DEBUGGING=0\" /D \"_ITERATOR_DEBUG_LEVEL=0\"") + SET(DISABLE_ITERATOR_DEBUGGING_CUDA "-D_HAS_ITERATOR_DEBUGGING=0 -D_ITERATOR_DEBUG_LEVEL=0") + SET(CRT_DEBUG_FLAG "/D \"_DEBUG\"") + SET(CRT_NDEBUG_FLAG "/D \"NDEBUG\"") + + # Need a different format for CUDA + SET(CUDA_DEBUG_FLAG "-DNDEBUG ${DISABLE_ITERATOR_DEBUGGING_CUDA}") + SET(CUDA_NDEBUG_FLAG "-DNDEBUG") + + SET(CUDA_CRT_COMPILE_OPTIONS_NDEBUG "") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "") + + IF(NV_USE_STATIC_WINCRT) + SET(WINCRT_NDEBUG "/MT ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_NDEBUG "/MT") + + IF (NV_USE_DEBUG_WINCRT) + SET(CUDA_DEBUG_FLAG "-D_DEBUG") + SET(WINCRT_DEBUG "/MTd ${CRT_DEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MTd") + ELSE() + SET(WINCRT_DEBUG "/MT ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MT") + ENDIF() + ELSE() + SET(WINCRT_NDEBUG "/MD ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}") + SET(CUDA_CRT_COMPILE_OPTIONS_NDEBUG "/MD") + + IF(NV_USE_DEBUG_WINCRT) + SET(CUDA_DEBUG_FLAG "-D_DEBUG") + SET(WINCRT_DEBUG "/MDd ${CRT_DEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MDd") + ELSE() + SET(WINCRT_DEBUG "/MD ${DISABLE_ITERATOR_DEBUGGING} ${CRT_NDEBUG_FLAG}" CACHE INTERNAL "Windows CRT build setting") + SET(CUDA_CRT_COMPILE_OPTIONS_DEBUG "/MD") + ENDIF() + ENDIF() + + IF(DEFINED PX_OUTPUT_EXE_DIR) + SetExeOutputPath(${PX_OUTPUT_EXE_DIR}) + ENDIF() + IF(DEFINED PX_OUTPUT_DLL_DIR) + SetDllOutputPath(${PX_OUTPUT_DLL_DIR}) + ENDIF() + IF(DEFINED PX_OUTPUT_LIB_DIR) + SetLibOutputPath(${PX_OUTPUT_LIB_DIR}) + ENDIF() + # All EXE/DLL/LIB output will be overwritten if PX_OUTPUT_ALL_DIR is defined + IF(DEFINED PX_OUTPUT_ALL_DIR) + SetSingleOutputPath(${PX_OUTPUT_ALL_DIR}) + ENDIF() +ENDIF() + +IF(NV_APPEND_CONFIG_NAME) + SET(CMAKE_DEBUG_POSTFIX "DEBUG_${LIBPATH_SUFFIX}") + SET(CMAKE_PROFILE_POSTFIX "PROFILE_${LIBPATH_SUFFIX}") + SET(CMAKE_CHECKED_POSTFIX "CHECKED_${LIBPATH_SUFFIX}") + SET(CMAKE_RELEASE_POSTFIX "_${LIBPATH_SUFFIX}") +ELSE() + IF (DEFINED PX_OUTPUT_ARCH) # platforms with fixed arch like ps4 dont need to have arch defined, then dont add bitness + SET(CMAKE_DEBUG_POSTFIX "_${LIBPATH_SUFFIX}") + SET(CMAKE_PROFILE_POSTFIX "_${LIBPATH_SUFFIX}") + SET(CMAKE_CHECKED_POSTFIX "_${LIBPATH_SUFFIX}") + SET(CMAKE_RELEASE_POSTFIX "_${LIBPATH_SUFFIX}") + ENDIF() +ENDIF() + +# Can no longer just use LIBPATH_SUFFIX since it depends on build type +IF(CMAKE_CL_64) + SET(RESOURCE_LIBPATH_SUFFIX "x64") +ELSE(CMAKE_CL_64) + SET(RESOURCE_LIBPATH_SUFFIX "x86") +ENDIF(CMAKE_CL_64) + + +# removes characters from the version string and leaves just numbers +FUNCTION(StripPackmanVersion IN_VERSION _OUTPUT_VERSION) + + STRING(REGEX REPLACE "([^0-9.])" "" + OUT_VERSION ${IN_VERSION}) + + STRING(REPLACE ".." "." + OUT_V2 ${OUT_VERSION}) + + SET(${_OUTPUT_VERSION} ${OUT_V2} PARENT_SCOPE) +ENDFUNCTION(StripPackmanVersion) \ No newline at end of file diff --git a/physx/source/compiler/cmake/modules/SetOutputPaths.cmake b/physx/source/compiler/cmake/modules/SetOutputPaths.cmake new file mode 100644 index 000000000..b1c178f5b --- /dev/null +++ b/physx/source/compiler/cmake/modules/SetOutputPaths.cmake @@ -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. + +FUNCTION(SetOutputPaths + OUTPUT_EXE_DIR + OUTPUT_DLL_DIR + OUTPUT_LIB_DIR) + + SET(EXE_DIR ${OUTPUT_EXE_DIR}) + SET(DLL_DIR ${OUTPUT_DLL_DIR}) + SET(LIB_DIR ${OUTPUT_LIB_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIB_DIR}) + +ENDFUNCTION(SetOutputPaths) + +FUNCTION(SetExeOutputPath OUTPUT_EXE_DIR) + + SET(EXE_DIR ${OUTPUT_EXE_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXE_DIR} PARENT_SCOPE) + +ENDFUNCTION(SetExeOutputPath) + +FUNCTION(SetDllOutputPath OUTPUT_DLL_DIR) + + SET(DLL_DIR ${OUTPUT_DLL_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DLL_DIR}/${ARGV1} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE ${DLL_DIR}/${ARGV2} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED ${DLL_DIR}/${ARGV3} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DLL_DIR}/${ARGV4} PARENT_SCOPE) + +ENDFUNCTION(SetDllOutputPath) + +FUNCTION(SetLibOutputPath OUTPUT_LIB_DIR) + + SET(LIB_DIR ${OUTPUT_LIB_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_DIR}/${ARGV1} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE ${LIB_DIR}/${ARGV2} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED ${LIB_DIR}/${ARGV3} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_DIR}/${ARGV4} PARENT_SCOPE) + + SET(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIB_DIR}) + +ENDFUNCTION(SetLibOutputPath) + +FUNCTION(SetSingleOutputPath OUTPUT_ALL_DIR) + + SET(EXE_DIR ${OUTPUT_ALL_DIR}) + SET(DLL_DIR ${OUTPUT_ALL_DIR}) + SET(LIB_DIR ${OUTPUT_ALL_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIB_DIR}) + +ENDFUNCTION(SetSingleOutputPath) + diff --git a/physx/source/compiler/cmake/modules/linux/LinuxAarch64.cmake b/physx/source/compiler/cmake/modules/linux/LinuxAarch64.cmake new file mode 100644 index 000000000..cbdd581f3 --- /dev/null +++ b/physx/source/compiler/cmake/modules/linux/LinuxAarch64.cmake @@ -0,0 +1,41 @@ +## 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. + +set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(TARGET_ABI "linux-gnu") +set(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu) + +set(CMAKE_C_COMPILER aarch64-${TARGET_ABI}-gcc) +set(CMAKE_CXX_COMPILER aarch64-${TARGET_ABI}-g++) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + +find_program(GCC_LOCATION ${CMAKE_C_COMPILER}) +if(NOT GCC_LOCATION) + message(FATAL_ERROR "Failed to find ${CMAKE_C_COMPILER}") +endif() diff --git a/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.aarch64-unknown-linux-gnueabihf.cmake b/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.aarch64-unknown-linux-gnueabihf.cmake new file mode 100644 index 000000000..904fc2176 --- /dev/null +++ b/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.aarch64-unknown-linux-gnueabihf.cmake @@ -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. + +IF(NOT $ENV{PM_PACKAGES_ROOT} EQUAL "") + # See https://stackoverflow.com/a/53635241 - CMake needs this for cross-compiling + # see also: https://cmake.org/cmake/help/latest/module/CMakeForceCompiler.html + # and https://cmake.org/cmake/help/latest/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.html + SET(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + + SET(LINUX_ROOT $ENV{PM_CLANGCROSSCOMPILE_PATH}/aarch64-unknown-linux-gnueabi) + STRING(REGEX REPLACE "\\\\" "/" LINUX_ROOT ${LINUX_ROOT}) + + MESSAGE(STATUS "LINUX_ROOT is '${LINUX_ROOT}'") + SET(ARCHITECTURE_TRIPLE aarch64-unknown-linux-gnueabi) + SET(CMAKE_SYSTEM_PROCESSOR aarch64) + + SET(CMAKE_CROSSCOMPILING TRUE) + SET(CMAKE_SYSTEM_NAME Linux) + SET(CMAKE_SYSTEM_VERSION 1) + + # sysroot + SET(CMAKE_SYSROOT ${LINUX_ROOT}) + + SET(CMAKE_LIBRARY_ARCHITECTURE ${ARCHITECTURE_TRIPLE}) + + # specify the cross compiler + SET(CMAKE_C_COMPILER ${CMAKE_SYSROOT}/bin/clang.exe) + SET(CMAKE_C_COMPILER_TARGET ${ARCHITECTURE_TRIPLE}) + + SET(CMAKE_CXX_COMPILER ${CMAKE_SYSROOT}/bin/clang++.exe) + SET(CMAKE_CXX_COMPILER_TARGET ${ARCHITECTURE_TRIPLE}) + + SET(CMAKE_FIND_ROOT_PATH ${LINUX_ROOT}) +ELSE() + MESSAGE("PM_PACKAGES_ROOT variable not defined!") +ENDIF() + + diff --git a/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.arm-unknown-linux-gnueabihf.cmake b/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.arm-unknown-linux-gnueabihf.cmake new file mode 100644 index 000000000..f4e55773d --- /dev/null +++ b/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.arm-unknown-linux-gnueabihf.cmake @@ -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. + +IF(NOT $ENV{LINUX_ROOT} EQUAL "") + SET(CMAKE_SYSTEM_NAME Linux) + + # FIXME: fix Linux toolchains to support architectures + SET(LINUX_ROOT $ENV{UE_SDKS_ROOT}/HostWin64/Linux_x64/arm-unknown-linux-gnueabihf_v5_clang-3.5.0-ld-2.23.1-glibc-2.13/toolchain) + STRING(REGEX REPLACE "\\\\" "/" LINUX_ROOT ${LINUX_ROOT}) + + message (STATUS "LINUX_ROOT is '${LINUX_ROOT}'") + SET(ARCHITECTURE_TRIPLE arm-unknown-linux-gnueabihf) + SET(CMAKE_SYSTEM_PROCESSOR aarch64) + + SET(CMAKE_CROSSCOMPILING TRUE) + SET(CMAKE_SYSTEM_NAME Linux) + SET(CMAKE_SYSTEM_VERSION 1) + + # sysroot + SET(CMAKE_SYSROOT ${LINUX_ROOT}) + + SET(CMAKE_LIBRARY_ARCHITECTURE ${ARCHITECTURE_TRIPLE}) + + # specify the cross compiler + SET(CMAKE_C_COMPILER ${CMAKE_SYSROOT}/bin/clang.exe) + SET(CMAKE_C_COMPILER_TARGET ${ARCHITECTURE_TRIPLE}) + SET(CMAKE_C_FLAGS "-target ${ARCHITECTURE_TRIPLE} --sysroot ${LINUX_ROOT} ") + + SET(CMAKE_CXX_COMPILER ${CMAKE_SYSROOT}/bin/clang++.exe) + SET(CMAKE_CXX_COMPILER_TARGET ${ARCHITECTURE_TRIPLE}) + SET(CMAKE_CXX_FLAGS "-target ${ARCHITECTURE_TRIPLE} --sysroot ${LINUX_ROOT} ") + + SET(CMAKE_FIND_ROOT_PATH ${LINUX_ROOT}) + #set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) # hoping to force it to use ar + #set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + #set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +ELSE() + MESSAGE("LINUX_ROOT environment variable not defined!") +ENDIF() + + diff --git a/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.x86_64-unknown-linux-gnu.cmake b/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.x86_64-unknown-linux-gnu.cmake new file mode 100644 index 000000000..a157cc914 --- /dev/null +++ b/physx/source/compiler/cmake/modules/linux/LinuxCrossToolchain.x86_64-unknown-linux-gnu.cmake @@ -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. + +IF(NOT $ENV{PM_PACKAGES_ROOT} EQUAL "") + # See https://stackoverflow.com/a/53635241 - CMake needs this for cross-compiling + # see also: https://cmake.org/cmake/help/latest/module/CMakeForceCompiler.html + # and https://cmake.org/cmake/help/latest/variable/CMAKE_TRY_COMPILE_TARGET_TYPE.html + SET(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") + + SET(LINUX_ROOT $ENV{PM_CLANGCROSSCOMPILE_PATH}/x86_64-unknown-linux-gnu) + STRING(REGEX REPLACE "\\\\" "/" LINUX_ROOT ${LINUX_ROOT}) + + MESSAGE(STATUS "LINUX_ROOT is '${LINUX_ROOT}'") + SET(ARCHITECTURE_TRIPLE x86_64-unknown-linux-gnu) + SET(CMAKE_SYSTEM_PROCESSOR x86_64) + + SET(CMAKE_CROSSCOMPILING TRUE) + SET(CMAKE_SYSTEM_NAME Linux) + SET(CMAKE_SYSTEM_VERSION 1) + + # sysroot + SET(CMAKE_SYSROOT ${LINUX_ROOT}) + + SET(CMAKE_LIBRARY_ARCHITECTURE ${ARCHITECTURE_TRIPLE}) + + # specify the cross compiler + SET(CMAKE_C_COMPILER ${CMAKE_SYSROOT}/bin/clang.exe) + SET(CMAKE_C_COMPILER_TARGET ${ARCHITECTURE_TRIPLE}) + + SET(CMAKE_CXX_COMPILER ${CMAKE_SYSROOT}/bin/clang++.exe) + SET(CMAKE_CXX_COMPILER_TARGET ${ARCHITECTURE_TRIPLE}) + + SET(CMAKE_FIND_ROOT_PATH ${LINUX_ROOT}) +ELSE() + MESSAGE("PM_PACKAGES_ROOT variable not defined!") +ENDIF() + + diff --git a/physx/source/compiler/cmake/windows/CMakeLists.txt b/physx/source/compiler/cmake/windows/CMakeLists.txt index 7124e8448..ceae730bf 100644 --- a/physx/source/compiler/cmake/windows/CMakeLists.txt +++ b/physx/source/compiler/cmake/windows/CMakeLists.txt @@ -93,7 +93,7 @@ ELSE() SET(NVTX_FLAG "PX_NVTX=0") ENDIF() -SET(PHYSX_WINDOWS_COMPILE_DEFS "WIN32;${WIN64_FLAG};${SCALAR_MATH_FLAG};${CUDA_FLAG};_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;${PHYSX_AUTOBUILD};${PUBLIC_RELEASE_FLAG};${FEATURES_UNDER_CONSTRUCTION_FLAG}" CACHE INTERNAL "Base PhysX preprocessor definitions") +SET(PHYSX_WINDOWS_COMPILE_DEFS "WIN32;${WIN64_FLAG};${SCALAR_MATH_FLAG};_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;${PHYSX_AUTOBUILD};${PUBLIC_RELEASE_FLAG};${FEATURES_UNDER_CONSTRUCTION_FLAG}" CACHE INTERNAL "Base PhysX preprocessor definitions") IF(CMAKE_CL_64) SET(PX_SUPPORT_OMNI_PVD_FLAG "PX_SUPPORT_OMNI_PVD=1") @@ -112,7 +112,7 @@ IF(PX_COPY_EXTERNAL_DLL OR PUBLIC_RELEASE) ENDIF() IF(NOT PHYSX_SLN_FREEGLUT_PATH) - SET(PHYSX_SLN_FREEGLUT_PATH "$ENV{PM_freeglut_PATH}/bin/" CACHE INTERNAL "PhysX glut32 copy path") + SET(PHYSX_SLN_FREEGLUT_PATH "$ENV{PM_freeglut_PATH}/bin/" CACHE INTERNAL "PhysX freeglut copy path") ENDIF() IF(CMAKE_CL_64) @@ -130,11 +130,6 @@ IF(PX_COPY_EXTERNAL_DLL OR PUBLIC_RELEASE) FILE(COPY ${PHYSX_SLN_PHYSXDEVICE_PATH}/PhysXDevice.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_PROFILE}) FILE(COPY ${PHYSX_SLN_PHYSXDEVICE_PATH}/PhysXDevice.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_RELEASE}) FILE(COPY ${PHYSX_SLN_PHYSXDEVICE_PATH}/PhysXDevice.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_CHECKED}) - - FILE(COPY ${PHYSX_SLN_FREEGLUT_PATH}/win32/freeglutd.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_DEBUG}) - FILE(COPY ${PHYSX_SLN_FREEGLUT_PATH}/win32/freeglut.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_PROFILE}) - FILE(COPY ${PHYSX_SLN_FREEGLUT_PATH}/win32/freeglut.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_RELEASE}) - FILE(COPY ${PHYSX_SLN_FREEGLUT_PATH}/win32/freeglut.dll DESTINATION ${PX_EXE_OUTPUT_DIRECTORY_CHECKED}) ENDIF() ENDIF() # for public release we copy the dlls for GPU other platforms so we dont keep duplicates around the repository @@ -171,9 +166,6 @@ ELSE() INCLUDE(PhysXCommon.cmake) INCLUDE(PhysXCooking.cmake) INCLUDE(PhysXExtensions.cmake) -IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT PUBLIC_RELEASE) - INCLUDE(PhysXGpuExtensions.cmake) -ENDIF() INCLUDE(PhysXVehicle.cmake) INCLUDE(PhysXVehicle2.cmake) INCLUDE(SceneQuery.cmake) @@ -188,9 +180,6 @@ ENDIF() SET_PROPERTY(TARGET PhysXCommon PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXCooking PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXExtensions PROPERTY FOLDER "PhysX SDK") -IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT PUBLIC_RELEASE) - SET_PROPERTY(TARGET PhysXGPUExtensions PROPERTY FOLDER "PhysX SDK") -ENDIF() SET_PROPERTY(TARGET PhysXVehicle PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXVehicle2 PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET LowLevel PROPERTY FOLDER "PhysX SDK") @@ -203,19 +192,12 @@ ENDIF() SET_PROPERTY(TARGET PhysXTask PROPERTY FOLDER "PhysX SDK") SET_PROPERTY(TARGET PhysXFoundation PROPERTY FOLDER "PhysX SDK") -IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT PUBLIC_RELEASE) - IF(PX_GENERATE_STATIC_LIBRARIES) - SET(PHYSXDISTRO_LIBS PhysXFoundation PhysX PhysXCharacterKinematic PhysXPvdSDK PhysXCommon PhysXCooking PhysXExtensions PhysXGPUExtensions PhysXVehicle PhysXVehicle2) - ELSE() - SET(PHYSXDISTRO_LIBS PhysXFoundation PhysX PhysXCharacterKinematic PhysXPvdSDK PhysXCommon PhysXCooking PhysXExtensions PhysXGPUExtensions PhysXVehicle PhysXVehicle2 PhysXTask) - ENDIF() -ELSE() + IF(PX_GENERATE_STATIC_LIBRARIES) SET(PHYSXDISTRO_LIBS PhysXFoundation PhysX PhysXCharacterKinematic PhysXPvdSDK PhysXCommon PhysXCooking PhysXExtensions PhysXVehicle PhysXVehicle2) ELSE() SET(PHYSXDISTRO_LIBS PhysXFoundation PhysX PhysXCharacterKinematic PhysXPvdSDK PhysXCommon PhysXCooking PhysXExtensions PhysXVehicle PhysXVehicle2 PhysXTask) ENDIF() -ENDIF() INSTALL( TARGETS ${PHYSXDISTRO_LIBS} diff --git a/physx/source/compiler/cmake/windows/PhysX.cmake b/physx/source/compiler/cmake/windows/PhysX.cmake index 855e2f839..8ba5202fb 100644 --- a/physx/source/compiler/cmake/windows/PhysX.cmake +++ b/physx/source/compiler/cmake/windows/PhysX.cmake @@ -40,6 +40,7 @@ SET(PHYSX_PLATFORM_INCLUDES SET(PHYSX_GPU_HEADERS ${PHYSX_ROOT_DIR}/include/gpu/PxGpu.h + ${PHYSX_ROOT_DIR}/include/gpu/PxPhysicsGpu.h ) SOURCE_GROUP(include\\gpu FILES ${PHYSX_GPU_HEADERS}) @@ -56,8 +57,8 @@ SET(PHYSX_COMMON_WINDOWS_HEADERS SOURCE_GROUP(include\\common\\windows FILES ${PHYSX_COMMON_WINDOWS_HEADERS}) SET(PHYSX_RESOURCE - ${PHYSX_SOURCE_DIR}/compiler/resource_${RESOURCE_LIBPATH_SUFFIX}/PhysX.rc - ${PHYSX_SOURCE_DIR}/compiler/resource_${RESOURCE_LIBPATH_SUFFIX}/resource.h + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/PhysX.rc + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/resource.h ) SOURCE_GROUP(resource FILES ${PHYSX_RESOURCE}) diff --git a/physx/source/compiler/cmake/windows/PhysXCommon.cmake b/physx/source/compiler/cmake/windows/PhysXCommon.cmake index 7b5695795..68ecdb639 100644 --- a/physx/source/compiler/cmake/windows/PhysXCommon.cmake +++ b/physx/source/compiler/cmake/windows/PhysXCommon.cmake @@ -41,7 +41,9 @@ SET(PHYSXCOMMON_WINDOWS_SOURCE SOURCE_GROUP(common\\src\\windows FILES ${PHYSXCOMMON_WINDOWS_SOURCE}) SET(PHYSXCOMMON_RESOURCE - ${PHYSX_SOURCE_DIR}/compiler/resource_${RESOURCE_LIBPATH_SUFFIX}/PhysXCommon.rc) + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/PhysXCommon.rc + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/resource.h +) SOURCE_GROUP(resource FILES ${PHYSXCOMMON_RESOURCE}) SET(PXCOMMON_PLATFORM_SRC_FILES diff --git a/physx/source/compiler/cmake/windows/PhysXCooking.cmake b/physx/source/compiler/cmake/windows/PhysXCooking.cmake index 35c4695a1..70e4e96c1 100644 --- a/physx/source/compiler/cmake/windows/PhysXCooking.cmake +++ b/physx/source/compiler/cmake/windows/PhysXCooking.cmake @@ -51,7 +51,8 @@ SET(PHYSX_COOKING_WINDOWS_SOURCE SOURCE_GROUP(src\\windows FILES ${PHYSX_COOKING_WINDOWS_SOURCE}) SET(PHYSX_COOKING_RESOURCE - ${PHYSX_SOURCE_DIR}/compiler/resource_${RESOURCE_LIBPATH_SUFFIX}/PhysXCooking.rc + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/PhysXCooking.rc + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/resource.h ) SOURCE_GROUP(resource FILES ${PHYSX_COOKING_RESOURCE}) diff --git a/physx/source/compiler/cmake/windows/PhysXFoundation.cmake b/physx/source/compiler/cmake/windows/PhysXFoundation.cmake index 5ac09df20..7286ac042 100644 --- a/physx/source/compiler/cmake/windows/PhysXFoundation.cmake +++ b/physx/source/compiler/cmake/windows/PhysXFoundation.cmake @@ -48,7 +48,8 @@ SOURCE_GROUP(include\\windows FILES ${PHYSXFOUNDATION_PLATFORM_HEADERS}) SET(PHYSXFOUNDATION_RESOURCE_FILE - ${PHYSX_SOURCE_DIR}/compiler/resource_${RESOURCE_LIBPATH_SUFFIX}/PhysXFoundation.rc + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/PhysXFoundation.rc + ${PHYSX_SOURCE_DIR}/compiler/windows/resource/resource.h ) SOURCE_GROUP(resource FILES ${PHYSXFOUNDATION_RESOURCE_FILE}) diff --git a/physx/source/compiler/resource_x64/PhysXCooking.rc b/physx/source/compiler/windows/resource/PhysX.rc similarity index 73% rename from physx/source/compiler/resource_x64/PhysXCooking.rc rename to physx/source/compiler/windows/resource/PhysX.rc index 28760e68f..2987bc1a7 100644 --- a/physx/source/compiler/resource_x64/PhysXCooking.rc +++ b/physx/source/compiler/windows/resource/PhysX.rc @@ -10,7 +10,6 @@ #include "windows.h" - ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -53,8 +52,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,0 - PRODUCTVERSION 5,1,1,0 + FILEVERSION RC_PHYSX_VER + PRODUCTVERSION RC_PHYSX_VER FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,14 +68,14 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "CompanyName", "NVIDIA Corporation" - VALUE "FileDescription", "PhysXCooking 64bit Dynamic Link Library" - VALUE "FileVersion", "5.1.1.0" - VALUE "InternalName", "PhysXCooking_64" - VALUE "LegalCopyright", "Copyright (C) 2021 NVIDIA Corporation" - VALUE "OriginalFilename", "PhysXCooking_64.dll" - VALUE "ProductName", "PhysX" - VALUE "ProductVersion", "5.1.1.0" + VALUE "CompanyName", RC_COMPANY_NAME_STR + VALUE "FileDescription", "PhysX " RC_PTR_STR "bit Dynamic Link Library" + VALUE "FileVersion", RC_PHYSX_VER_STR + VALUE "InternalName", "PhysX_" RC_PTR_STR + VALUE "LegalCopyright", RC_LEGAL_COPYRIGHT_STR + VALUE "OriginalFilename", "PhysX_" RC_PTR_STR ".dll" + VALUE "ProductName", RC_PRODUCT_NAME_STR + VALUE "ProductVersion", RC_PHYSX_VER_STR END END BLOCK "VarFileInfo" diff --git a/physx/source/compiler/resource_x64/PhysXCommon.rc b/physx/source/compiler/windows/resource/PhysXCommon.rc similarity index 73% rename from physx/source/compiler/resource_x64/PhysXCommon.rc rename to physx/source/compiler/windows/resource/PhysXCommon.rc index 214e688a4..128f9f899 100644 --- a/physx/source/compiler/resource_x64/PhysXCommon.rc +++ b/physx/source/compiler/windows/resource/PhysXCommon.rc @@ -52,8 +52,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,0 - PRODUCTVERSION 5,1,1,0 + FILEVERSION RC_PHYSX_VER + PRODUCTVERSION RC_PHYSX_VER FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,14 +68,14 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "CompanyName", "NVIDIA Corporation" - VALUE "FileDescription", "PhysXCommon 64bit Dynamic Link Library" - VALUE "FileVersion", "5.1.1.0" - VALUE "InternalName", "PhysXCommon_64" - VALUE "LegalCopyright", "Copyright (C) 2021 NVIDIA Corporation" - VALUE "OriginalFilename", "PhysXCommon_64.dll" - VALUE "ProductName", "PhysX" - VALUE "ProductVersion", "5.1.1.0" + VALUE "CompanyName", RC_COMPANY_NAME_STR + VALUE "FileDescription", "PhysXCommon " RC_PTR_STR "bit Dynamic Link Library" + VALUE "FileVersion", RC_PHYSX_VER_STR + VALUE "InternalName", "PhysXCommon_" RC_PTR_STR + VALUE "LegalCopyright", RC_LEGAL_COPYRIGHT_STR + VALUE "OriginalFilename", "PhysXCommon_" RC_PTR_STR ".dll" + VALUE "ProductName", RC_PRODUCT_NAME_STR + VALUE "ProductVersion", RC_PHYSX_VER_STR END END BLOCK "VarFileInfo" diff --git a/physx/source/compiler/resource_x64/PhysX.rc b/physx/source/compiler/windows/resource/PhysXCooking.rc similarity index 73% rename from physx/source/compiler/resource_x64/PhysX.rc rename to physx/source/compiler/windows/resource/PhysXCooking.rc index 81d23d6c1..61123a1f4 100644 --- a/physx/source/compiler/resource_x64/PhysX.rc +++ b/physx/source/compiler/windows/resource/PhysXCooking.rc @@ -10,6 +10,7 @@ #include "windows.h" + ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS @@ -52,8 +53,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,1,0 - PRODUCTVERSION 5,1,1,0 + FILEVERSION RC_PHYSX_VER + PRODUCTVERSION RC_PHYSX_VER FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -68,14 +69,14 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "CompanyName", "NVIDIA Corporation" - VALUE "FileDescription", "PhysX 64bit Dynamic Link Library" - VALUE "FileVersion", "5.1.1.0" - VALUE "InternalName", "PhysX_64" - VALUE "LegalCopyright", "Copyright (C) 2021 NVIDIA Corporation" - VALUE "OriginalFilename", "PhysX_64.dll" - VALUE "ProductName", "PhysX" - VALUE "ProductVersion", "5.1.1.0" + VALUE "CompanyName", RC_COMPANY_NAME_STR + VALUE "FileDescription", "PhysXCooking " RC_PTR_STR "bit Dynamic Link Library" + VALUE "FileVersion", RC_PHYSX_VER_STR + VALUE "InternalName", "PhysXCooking_" RC_PTR_STR + VALUE "LegalCopyright", RC_LEGAL_COPYRIGHT_STR + VALUE "OriginalFilename", "PhysXCooking_" RC_PTR_STR ".dll" + VALUE "ProductName", RC_PRODUCT_NAME_STR + VALUE "ProductVersion", RC_PHYSX_VER_STR END END BLOCK "VarFileInfo" diff --git a/physx/source/compiler/resource_x64/PhysXFoundation.rc b/physx/source/compiler/windows/resource/PhysXFoundation.rc similarity index 86% rename from physx/source/compiler/resource_x64/PhysXFoundation.rc rename to physx/source/compiler/windows/resource/PhysXFoundation.rc index ff8b694e958c9df3e404f8d62c16acee33481c91..c42bf07eaaa4dba3a87d48457b6b51fb7dff7119 100644 GIT binary patch delta 425 zcmaE$v`KlxBX;p124{wNh5!Z+hDe5Bh6o@#jKP&5X!3h@Wt?&oIm9=cahzjRg=ltW z@MrJ^8sW&`2Q(xeNIC-fu0U2WLkQ5QLQdhy7dSa4J8<(&4&ic>R$@?KfLRNahp7XK zDovitRW1*cLvs>L9g=x|;yBDgQo}cS54Vyw#7rNctK5OE^8uO#a&-XEy+I6~Krs)X sOR>6_#{;i>=kxeOLm>cYl0SnBLnzQ>kXiUb!Gc$b7+-F#<9);o0Jk4jKmY&$ delta 293 zcmdm_{6J~LBX(X>1|0@NC^neU~p#0XDDJQ z0F#LfB@CHBRvv>A1J`6nF7e54I0YuBak(*@F_=s~&Q&g~#9+#x2ebr&4N%mzaXYXB z)uD*7@hJH#f$b<@s07-R$&k*F0klPdK?5kN38ak}41m}W$RfpEIXn?yH{Iv)pS*-y Uff?rB99|(alloc.allocate(sizeof(Foundation), "Foundation", __FILE__, __LINE__)); + gInstance = reinterpret_cast(alloc.allocate(sizeof(Foundation), "Foundation", PX_FL)); - if(mInstance) + if(gInstance) { - PX_PLACEMENT_NEW(mInstance, Foundation)(errc, alloc); + PX_PLACEMENT_NEW(gInstance, Foundation)(errc, alloc); - PX_ASSERT(mInstance->mRefCount == 0); - mInstance->mRefCount = 1; + PX_ASSERT(gInstance->mRefCount == 0); + gInstance->mRefCount = 1; // skip 0 which marks uninitialized timestaps in PX_WARN_ONCE mWarnOnceTimestap = (mWarnOnceTimestap == PX_MAX_U32) ? 1 : mWarnOnceTimestap + 1; - return mInstance; + return gInstance; } else { - errc.reportError(PxErrorCode::eINTERNAL_ERROR, "Memory allocation for foundation object failed.", __FILE__, - __LINE__); + errc.reportError(PxErrorCode::eINTERNAL_ERROR, "Memory allocation for foundation object failed.", PX_FL); } } else { - errc.reportError(PxErrorCode::eINVALID_OPERATION, - "Foundation object exists already. Only one instance per process can be created.", __FILE__, - __LINE__); + errc.reportError(PxErrorCode::eINVALID_OPERATION, "Foundation object exists already. Only one instance per process can be created.", PX_FL); } return 0; @@ -167,41 +165,40 @@ Foundation* Foundation::createInstance(PxU32 version, PxErrorCallback& errc, PxA void Foundation::destroyInstance() { - PX_ASSERT(mInstance != NULL); + PX_ASSERT(gInstance); - if(mInstance->mRefCount == 1) + if(gInstance->mRefCount == 1) { - PxAllocatorCallback& alloc = mInstance->getAllocatorCallback(); - mInstance->~Foundation(); - alloc.deallocate(mInstance); - mInstance = 0; + PxAllocatorCallback& alloc = gInstance->getAllocatorCallback(); + gInstance->~Foundation(); + alloc.deallocate(gInstance); + gInstance = NULL; } else { - mInstance->error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, - "Foundation destruction failed due to pending module references. Close/release all depending " - "modules first."); + gInstance->error(PxErrorCode::eINVALID_OPERATION, PX_FL, + "Foundation destruction failed due to pending module references. Close/release all depending modules first."); } } void Foundation::incRefCount() { - PX_ASSERT(mInstance != NULL); + PX_ASSERT(gInstance); - if(mInstance->mRefCount > 0) - mInstance->mRefCount++; + if(gInstance->mRefCount > 0) + gInstance->mRefCount++; else - mInstance->error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Foundation: Invalid registration detected."); + gInstance->error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Foundation: Invalid registration detected."); } void Foundation::decRefCount() { - PX_ASSERT(mInstance != NULL); + PX_ASSERT(gInstance); - if(mInstance->mRefCount > 0) - mInstance->mRefCount--; + if(gInstance->mRefCount > 0) + gInstance->mRefCount--; else - mInstance->error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "Foundation: Invalid deregistration detected."); + gInstance->error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Foundation: Invalid deregistration detected."); } void Foundation::release() @@ -211,19 +208,18 @@ void Foundation::release() PxU32 Foundation::getRefCount() { - return mInstance->mRefCount; + return gInstance->mRefCount; } -Foundation* Foundation::mInstance = NULL; PxU32 Foundation::mWarnOnceTimestap = 0; -void Foundation::registerAllocationListener(physx::PxAllocationListener& listener) +void Foundation::registerAllocationListener(PxAllocationListener& listener) { Mutex::ScopedLock lock(mListenerMutex); mBroadcastingAllocator.registerListener(listener); } -void Foundation::deregisterAllocationListener(physx::PxAllocationListener& listener) +void Foundation::deregisterAllocationListener(PxAllocationListener& listener) { Mutex::ScopedLock lock(mListenerMutex); mBroadcastingAllocator.deregisterListener(listener); @@ -241,68 +237,73 @@ void Foundation::deregisterErrorCallback(PxErrorCallback& callback) mBroadcastingError.deregisterListener(callback); } -physx::PxProfilerCallback* gProfilerCallback = NULL; - -} // namespace physx +PxFoundation* PxCreateFoundation(PxU32 version, PxAllocatorCallback& allocator, PxErrorCallback& errorCallback) +{ + return Foundation::createInstance(version, errorCallback, allocator); +} -physx::PxFoundation* PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator, - physx::PxErrorCallback& errorCallback) +void PxSetFoundationInstance(PxFoundation& foundation) { - return physx::Foundation::createInstance(version, errorCallback, allocator); + Foundation::setInstance(static_cast(foundation)); } -void PxSetFoundationInstance(physx::PxFoundation& foundation) +PxAllocatorCallback* PxGetAllocatorCallback() { - physx::Foundation::setInstance(static_cast(foundation)); + return &gInstance->getAllocatorCallback(); } -physx::PxAllocatorCallback* PxGetAllocatorCallback() +PxAllocatorCallback* PxGetBroadcastAllocator(bool* reportAllocationNames) { - return &physx::Foundation::getInstance().getAllocatorCallback(); + PX_ASSERT(gInstance); + if(reportAllocationNames) + *reportAllocationNames = gInstance->mReportAllocationNames; + + return &gInstance->getBroadcastAllocator(); } -physx::PxAllocatorCallback* PxGetBroadcastAllocator() +PxErrorCallback* PX_CALL_CONV PxGetErrorCallback() { - return &physx::Foundation::getInstance().getBroadcastAllocator(); + return &gInstance->getErrorCallback(); } -physx::PxErrorCallback* PX_CALL_CONV PxGetErrorCallback() +PxErrorCallback* PX_CALL_CONV PxGetBroadcastError() { - return &physx::Foundation::getInstance().getErrorCallback(); + return &gInstance->getInternalErrorCallback(); } -physx::PxErrorCallback* PX_CALL_CONV PxGetBroadcastError() +PxFoundation& PxGetFoundation() { - return &physx::Foundation::getInstance().getInternalErrorCallback(); + PX_ASSERT(gInstance); + return *gInstance; } -physx::PxFoundation& PxGetFoundation() +PxFoundation* PxIsFoundationValid() { - return physx::Foundation::getInstance(); + return gInstance; } -physx::PxProfilerCallback* PxGetProfilerCallback() +PxProfilerCallback* PxGetProfilerCallback() { - return physx::gProfilerCallback; + return gProfilerCallback; } -void PxSetProfilerCallback(physx::PxProfilerCallback* profiler) +void PxSetProfilerCallback(PxProfilerCallback* profiler) { - physx::gProfilerCallback = profiler; + gProfilerCallback = profiler; } -physx::PxU32 PxGetWarnOnceTimeStamp() +PxU32 PxGetWarnOnceTimeStamp() { - return physx::Foundation::getWarnOnceTimestamp(); + return Foundation::getWarnOnceTimestamp(); } void PxDecFoundationRefCount() { - physx::Foundation::decRefCount(); + Foundation::decRefCount(); } void PxIncFoundationRefCount() { - physx::Foundation::incRefCount(); + Foundation::incRefCount(); } diff --git a/physx/source/foundation/FdFoundation.h b/physx/source/foundation/FdFoundation.h index bbb49c973..3661100c0 100644 --- a/physx/source/foundation/FdFoundation.h +++ b/physx/source/foundation/FdFoundation.h @@ -61,7 +61,6 @@ class PX_FOUNDATION_API Foundation : public PxFoundation, public PxUserAllocated // factory // note, you MUST eventually call release if createInstance returned true! static Foundation* createInstance(PxU32 version, PxErrorCallback& errc, PxAllocatorCallback& alloc); - static Foundation& getInstance(); static void setInstance(Foundation& foundation); void release(); static void incRefCount(); // this call requires a foundation object to exist already @@ -130,7 +129,7 @@ class PX_FOUNDATION_API Foundation : public PxFoundation, public PxUserAllocated } // End allocations - private: + //private: static void destroyInstance(); Foundation(PxErrorCallback& errc, PxAllocatorCallback& alloc); @@ -153,7 +152,6 @@ class PX_FOUNDATION_API Foundation : public PxFoundation, public PxUserAllocated Mutex mListenerMutex; - static Foundation* mInstance; PxU32 mRefCount; static PxU32 mWarnOnceTimestap; }; @@ -161,10 +159,7 @@ class PX_FOUNDATION_API Foundation : public PxFoundation, public PxUserAllocated #pragma warning(pop) #endif -PX_INLINE Foundation& getFoundation() -{ - return Foundation::getInstance(); -} +Foundation& getFoundation(); } // namespace physx diff --git a/physx/source/foundation/FdMathUtils.cpp b/physx/source/foundation/FdMathUtils.cpp index 9a8f73c29..1e2614ef7 100644 --- a/physx/source/foundation/FdMathUtils.cpp +++ b/physx/source/foundation/FdMathUtils.cpp @@ -175,35 +175,6 @@ PxVec3 physx::PxOptimizeBoundingBox(PxMat33& basis) return magnitude; } -PxQuat physx::PxSlerp(const PxReal t, const PxQuat& left, const PxQuat& right) -{ - const PxReal quatEpsilon = (PxReal(1.0e-8f)); - - PxReal cosine = left.dot(right); - PxReal sign = PxReal(1); - if(cosine < 0) - { - cosine = -cosine; - sign = PxReal(-1); - } - - PxReal sine = PxReal(1) - cosine * cosine; - - if(sine >= quatEpsilon * quatEpsilon) - { - sine = PxSqrt(sine); - const PxReal angle = PxAtan2(sine, cosine); - const PxReal i_sin_angle = PxReal(1) / sine; - - const PxReal leftw = PxSin(angle * (PxReal(1) - t)) * i_sin_angle; - const PxReal rightw = PxSin(angle * t) * i_sin_angle * sign; - - return left * leftw + right * rightw; - } - - return left; -} - void physx::PxIntegrateTransform(const PxTransform& curTrans, const PxVec3& linvel, const PxVec3& angvel, PxReal timeStep, PxTransform& result) { diff --git a/physx/source/foundation/unix/FdUnixSocket.cpp b/physx/source/foundation/unix/FdUnixSocket.cpp index fd8425e38..75a8af4cc 100644 --- a/physx/source/foundation/unix/FdUnixSocket.cpp +++ b/physx/source/foundation/unix/FdUnixSocket.cpp @@ -157,9 +157,9 @@ bool SocketImpl::connect(const char* host, uint16_t port, uint32_t timeout) pfd.events = POLLOUT; const int pollResult = ::poll(&pfd, 1, timeout /*milliseconds*/); - const bool timeout = (pollResult == 0); - const bool error = (pollResult < 0); // an error inside poll happened. Can check error with `errno` variable. - if(timeout || error) + const bool pollTimeout = (pollResult == 0); + const bool pollError = (pollResult < 0); // an error inside poll happened. Can check error with `errno` variable. + if(pollTimeout || pollError) { disconnect(); return false; diff --git a/physx/source/foundation/windows/FdWindowsPrintString.cpp b/physx/source/foundation/windows/FdWindowsPrintString.cpp index 879c27543..9865c9abb 100644 --- a/physx/source/foundation/windows/FdWindowsPrintString.cpp +++ b/physx/source/foundation/windows/FdWindowsPrintString.cpp @@ -28,10 +28,7 @@ #include "foundation/PxString.h" #include -#pragma warning(push) -#pragma warning(disable : 4668) //'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives' -#include -#pragma warning(pop) +#include "foundation/windows/PxWindowsInclude.h" #include #include diff --git a/physx/source/foundation/windows/FdWindowsSocket.cpp b/physx/source/foundation/windows/FdWindowsSocket.cpp index beef504a1..28bfccc49 100644 --- a/physx/source/foundation/windows/FdWindowsSocket.cpp +++ b/physx/source/foundation/windows/FdWindowsSocket.cpp @@ -116,10 +116,6 @@ void SocketImpl::setBlockingInternal(SOCKET socket, bool blocking) ioctlsocket(socket, FIONBIO, (u_long*)&mode); } -#ifdef PX_VC11 -#pragma warning(push) -#pragma warning(disable : 4548) // for FD_SET on vc11 only -#endif bool SocketImpl::connect(const char* host, uint16_t port, uint32_t timeout) { if(!mSocketLayerIntialized) @@ -152,27 +148,33 @@ bool SocketImpl::connect(const char* host, uint16_t port, uint32_t timeout) setBlockingInternal(mSocket, false); ::connect(mSocket, (sockaddr*)&socketAddress, sizeof(socketAddress)); - // Setup select function call to monitor the connect call. - fd_set writefs; - fd_set exceptfs; - FD_ZERO(&writefs); - FD_ZERO(&exceptfs); -#pragma warning(push) -#pragma warning(disable : 4127 4548) - FD_SET(mSocket, &writefs); - FD_SET(mSocket, &exceptfs); -#pragma warning(pop) - timeval timeout_; - timeout_.tv_sec = long(timeout / 1000); - timeout_.tv_usec = long(((timeout % 1000) * 1000)); - int selret = ::select(1, NULL, &writefs, &exceptfs, &timeout_); - int excepted = FD_ISSET(mSocket, &exceptfs); - int canWrite = FD_ISSET(mSocket, &writefs); - if(selret != 1 || excepted || !canWrite) + + // Setup poll function call to monitor the connect call. + // By querying for POLLOUT we're checking if the socket is + // ready for writing. + WSAPOLLFD pfd; + pfd.fd = mSocket; + pfd.events = POLLOUT; + const int pollResult = WSAPoll(&pfd, 1, timeout /*milliseconds*/); + + const bool pollTimeout = (pollResult == 0); + const bool pollError = (pollResult == SOCKET_ERROR); // an error inside poll happened. Can check error with `WSAGetLastError`. + if(pollTimeout || pollError) { disconnect(); return false; } + else + { + PX_ASSERT(pollResult == 1); + // check that event was precisely POLLOUT and not anything else (e.g., errors, hang-up) + bool test = (pfd.revents & POLLOUT) && !(pfd.revents & (~POLLOUT)); + if(!test) + { + disconnect(); + return false; + } + } setBlockingInternal(mSocket, mIsBlocking); @@ -181,9 +183,6 @@ bool SocketImpl::connect(const char* host, uint16_t port, uint32_t timeout) mHost = host; return true; } -#ifdef PX_VC11 -#pragma warning(pop) -#endif bool SocketImpl::listen(uint16_t port) { diff --git a/physx/source/geomutils/include/GuDistancePointTriangle.h b/physx/source/geomutils/include/GuDistancePointTriangle.h index 8dd312354..ce6c505da 100644 --- a/physx/source/geomutils/include/GuDistancePointTriangle.h +++ b/physx/source/geomutils/include/GuDistancePointTriangle.h @@ -31,6 +31,7 @@ #include "foundation/PxVec3.h" #include "common/PxPhysXCommonConfig.h" +#include "foundation/PxVecMath.h" namespace physx { @@ -99,11 +100,8 @@ namespace Gu PX_PHYSX_COMMON_API PxVec3 closestPtPointTriangle(const PxVec3& p, const PxVec3& a, const PxVec3& b, const PxVec3& c, float& s, float& t); PX_FORCE_INLINE PxReal distancePointTriangleSquared(const PxVec3& point, - const PxVec3& triangleOrigin, - const PxVec3& triangleEdge0, - const PxVec3& triangleEdge1, - PxReal* param0=NULL, - PxReal* param1=NULL) + const PxVec3& triangleOrigin, const PxVec3& triangleEdge0, const PxVec3& triangleEdge1, + PxReal* param0=NULL, PxReal* param1=NULL) { const PxVec3 pt0 = triangleEdge0 + triangleOrigin; const PxVec3 pt1 = triangleEdge1 + triangleOrigin; @@ -116,8 +114,14 @@ namespace Gu return (cp - point).magnitudeSquared(); } + PX_PHYSX_COMMON_API aos::FloatV distancePointTriangleSquared( const aos::Vec3VArg point, + const aos::Vec3VArg a, + const aos::Vec3VArg b, + const aos::Vec3VArg c, + aos::FloatV& u, + aos::FloatV& v, + aos::Vec3V& closestP); } // namespace Gu - } #endif diff --git a/physx/source/geomutils/include/GuDistanceSegmentSegment.h b/physx/source/geomutils/include/GuDistanceSegmentSegment.h index f70d709f2..49927cd5e 100644 --- a/physx/source/geomutils/include/GuDistanceSegmentSegment.h +++ b/physx/source/geomutils/include/GuDistanceSegmentSegment.h @@ -31,6 +31,7 @@ #include "common/PxPhysXCommonConfig.h" #include "GuSegment.h" +#include "foundation/PxVecMath.h" namespace physx { @@ -57,8 +58,19 @@ namespace Gu s, t); } -} // namespace Gu + PX_PHYSX_COMMON_API aos::FloatV distanceSegmentSegmentSquared( const aos::Vec3VArg p1, const aos::Vec3VArg d1, const aos::Vec3VArg p2, const aos::Vec3VArg d2, + aos::FloatV& param0, + aos::FloatV& param1); + + // This function do four segment segment closest point test in one go + aos::Vec4V distanceSegmentSegmentSquared4( const aos::Vec3VArg p, const aos::Vec3VArg d, + const aos::Vec3VArg p02, const aos::Vec3VArg d02, + const aos::Vec3VArg p12, const aos::Vec3VArg d12, + const aos::Vec3VArg p22, const aos::Vec3VArg d22, + const aos::Vec3VArg p32, const aos::Vec3VArg d32, + aos::Vec4V& s, aos::Vec4V& t); +} // namespace Gu } #endif diff --git a/physx/source/geomutils/include/GuOverlapTests.h b/physx/source/geomutils/include/GuOverlapTests.h index ae1d176ed..84a8abec4 100644 --- a/physx/source/geomutils/include/GuOverlapTests.h +++ b/physx/source/geomutils/include/GuOverlapTests.h @@ -87,9 +87,6 @@ namespace Gu // PT: retrieves the overlap function table (for access by external non-Gu modules) PX_PHYSX_COMMON_API const GeomOverlapTable* getOverlapFuncTable(); - // dynamic registration of height fields - PX_PHYSX_COMMON_API void registerHeightFields(); - PX_FORCE_INLINE bool overlap( const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1, const GeomOverlapTable* PX_RESTRICT overlapFuncs, PxOverlapThreadContext* threadContext) diff --git a/physx/source/geomutils/src/GuAABBPruner.cpp b/physx/source/geomutils/src/GuAABBPruner.cpp index d46906cbe..b20289c64 100644 --- a/physx/source/geomutils/src/GuAABBPruner.cpp +++ b/physx/source/geomutils/src/GuAABBPruner.cpp @@ -339,10 +339,9 @@ void AABBPruner::commit() if(!mAABBTree || !mIncrementalRebuild) { -#if PX_CHECKED if(!mIncrementalRebuild && mAABBTree) PxGetFoundation().error(PxErrorCode::ePERF_WARNING, PX_FL, "SceneQuery static AABB Tree rebuilt, because a shape attached to a static actor was added, removed or moved, and PxSceneQueryDesc::staticStructure is set to eSTATIC_AABB_TREE."); -#endif + fullRebuildAABBTree(); return; } diff --git a/physx/source/geomutils/src/GuBVH.cpp b/physx/source/geomutils/src/GuBVH.cpp index f5a0b8207..30f0a5272 100644 --- a/physx/source/geomutils/src/GuBVH.cpp +++ b/physx/source/geomutils/src/GuBVH.cpp @@ -278,12 +278,6 @@ void BVH::onRefCountZero() ::onRefCountZero(this, mMeshFactory, false, "PxBVH::release: double deletion detected!"); } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/** - * Query Implementation - */ -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - namespace { struct BVHTree @@ -296,88 +290,8 @@ namespace const BVHNode* mRootNode; const PxU32* mIndices; }; - - struct BVHCallback - { - BVHCallback(PxU32* hits, PxU32 numMaxHits): - mHits (hits), - mNbMaxHits (numMaxHits), - mCurrentHitsCount (0) - { - } - - PX_FORCE_INLINE bool invoke(PxReal&, PxU32 payload) - { - mHits[mCurrentHitsCount++] = payload; - if(mCurrentHitsCount == mNbMaxHits) - return false; - return true; - } - - PxU32* mHits; - PxU32 mNbMaxHits; - PxU32 mCurrentHitsCount; - }; - - struct BVHOverlapCallback - { - BVHOverlapCallback(PxU32* hits, PxU32 numMaxHits): - mHits (hits), - mNbMaxHits (numMaxHits), - mCurrentHitsCount (0) - { - } - - PX_FORCE_INLINE bool invoke(PxU32 payload) - { - mHits[mCurrentHitsCount++] = payload; - if(mCurrentHitsCount == mNbMaxHits) - return false; - return true; - } - - PxU32* mHits; - PxU32 mNbMaxHits; - PxU32 mCurrentHitsCount; - const PxU32* mVolumes; - }; } -PxU32 BVH::raycast(const PxVec3& origin, const PxVec3& unitDir, PxReal maxDist, PxU32 maxHits, PxU32* PX_RESTRICT rayHits) const -{ - BVHCallback cbk(rayHits, maxHits); - if(mData.mIndices) - AABBTreeRaycast()(mData.mBounds, BVHTree(mData), origin, unitDir, maxDist, PxVec3(0.0f), cbk); - else - AABBTreeRaycast()(mData.mBounds, BVHTree(mData), origin, unitDir, maxDist, PxVec3(0.0f), cbk); - - return cbk.mCurrentHitsCount; -} - -PxU32 BVH::sweep(const PxBounds3& aabb, const PxVec3& unitDir, PxReal maxDist, PxU32 maxHits, PxU32* PX_RESTRICT sweepHits) const -{ - BVHCallback cbk(sweepHits, maxHits); - if(mData.mIndices) - AABBTreeRaycast()(mData.mBounds, BVHTree(mData), aabb.getCenter(), unitDir, maxDist, aabb.getExtents(), cbk); - else - AABBTreeRaycast()(mData.mBounds, BVHTree(mData), aabb.getCenter(), unitDir, maxDist, aabb.getExtents(), cbk); - - return cbk.mCurrentHitsCount; -} - -PxU32 BVH::overlap(const PxBounds3& aabb, PxU32 maxHits, PxU32* PX_RESTRICT overlapHits) const -{ - BVHOverlapCallback cbk(overlapHits, maxHits); - const AABBAABBTest test(aabb); - if(mData.mIndices) - AABBTreeOverlap()(mData.mBounds, BVHTree(mData), test, cbk); - else - AABBTreeOverlap()(mData.mBounds, BVHTree(mData), test, cbk); - - return cbk.mCurrentHitsCount; -} - - namespace { struct RaycastAdapter diff --git a/physx/source/geomutils/src/GuBVH.h b/physx/source/geomutils/src/GuBVH.h index 55b09eaf6..cf7529148 100644 --- a/physx/source/geomutils/src/GuBVH.h +++ b/physx/source/geomutils/src/GuBVH.h @@ -103,27 +103,23 @@ namespace Gu void release(); // PxBVH - virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, float distance, RaycastCallback& cb, PxGeometryQueryFlags flags) const /*override*/; - virtual bool overlap(const PxGeometry& geom, const PxTransform& pose, OverlapCallback& cb, PxGeometryQueryFlags flags) const /*override*/; - virtual bool sweep(const PxGeometry& geom, const PxTransform& pose, const PxVec3& unitDir, float distance, RaycastCallback& cb, PxGeometryQueryFlags flags) const /*override*/; - virtual bool cull(PxU32 nbPlanes, const PxPlane* planes, OverlapCallback& cb, PxGeometryQueryFlags flags) const /*override*/; + virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, float distance, RaycastCallback& cb, PxGeometryQueryFlags flags) const PX_OVERRIDE; + virtual bool overlap(const PxGeometry& geom, const PxTransform& pose, OverlapCallback& cb, PxGeometryQueryFlags flags) const PX_OVERRIDE; + virtual bool sweep(const PxGeometry& geom, const PxTransform& pose, const PxVec3& unitDir, float distance, RaycastCallback& cb, PxGeometryQueryFlags flags) const PX_OVERRIDE; + virtual bool cull(PxU32 nbPlanes, const PxPlane* planes, OverlapCallback& cb, PxGeometryQueryFlags flags) const PX_OVERRIDE; - virtual PxU32 raycast(const PxVec3& origin, const PxVec3& unitDir, PxReal maxDist, PxU32 maxHits, PxU32* PX_RESTRICT rayHits) const /*override*/; - virtual PxU32 sweep(const PxBounds3& aabb, const PxVec3& unitDir, PxReal maxDist, PxU32 maxHits, PxU32* PX_RESTRICT sweepHits) const /*override*/; - virtual PxU32 overlap(const PxBounds3& aabb, PxU32 maxHits, PxU32* PX_RESTRICT overlapHits) const /*override*/; + virtual PxU32 getNbBounds() const PX_OVERRIDE { return mData.mNbIndices; } + virtual const PxBounds3* getBounds() const PX_OVERRIDE { return mData.mBounds.getBounds(); } - virtual PxU32 getNbBounds() const /*override*/ { return mData.mNbIndices; } - virtual const PxBounds3* getBounds() const /*override*/ { return mData.mBounds.getBounds(); } + virtual void refit() PX_OVERRIDE; + virtual bool updateBounds(PxU32 boundsIndex, const PxBounds3& newBounds) PX_OVERRIDE; + virtual void partialRefit() PX_OVERRIDE; - virtual void refit() /*override*/; - virtual bool updateBounds(PxU32 boundsIndex, const PxBounds3& newBounds) /*override*/; - virtual void partialRefit() /*override*/; - - virtual bool traverse(TraversalCallback& cb) const /*override*/; + virtual bool traverse(TraversalCallback& cb) const PX_OVERRIDE; //~PxBVH // Cm::RefCountable - virtual void onRefCountZero() /*override*/; + virtual void onRefCountZero() PX_OVERRIDE; //~Cm::RefCountable PX_FORCE_INLINE const BVHNode* getNodes() const { return mData.mNodes; } diff --git a/physx/source/geomutils/src/GuCookingSDF.cpp b/physx/source/geomutils/src/GuCookingSDF.cpp index ad8cd30a6..e502940fa 100644 --- a/physx/source/geomutils/src/GuCookingSDF.cpp +++ b/physx/source/geomutils/src/GuCookingSDF.cpp @@ -105,6 +105,30 @@ namespace physx return z * (width) * (height)+y * (width)+x; } + void convert16To32Bits(PxSimpleTriangleMesh mesh, PxArray& indices32) + { + indices32.resize(3 * mesh.triangles.count); + if (mesh.flags & PxMeshFlag::e16_BIT_INDICES) + { + // conversion; 16 bit index -> 32 bit index & stride + PxU32* dest = indices32.begin(); + const PxU32* pastLastDest = indices32.begin() + 3 * mesh.triangles.count; + const PxU8* source = reinterpret_cast(mesh.triangles.data); + while (dest < pastLastDest) + { + const PxU16 * trig16 = reinterpret_cast(source); + *dest++ = trig16[0]; + *dest++ = trig16[1]; + *dest++ = trig16[2]; + source += mesh.triangles.stride; + } + } + else + { + immediateCooking::gatherStrided(mesh.triangles.data, indices32.begin(), mesh.triangles.count, sizeof(PxU32) * 3, mesh.triangles.stride); + } + } + static bool createSDFSparse(PxTriangleMeshDesc& desc, PxSDFDesc& sdfDesc, PxArray& sdf, PxArray& sdfDataSubgrids, PxArray& sdfSubgridsStartSlots) { @@ -169,8 +193,30 @@ namespace physx PxReal subgridsMinSdfValue, subgridsMaxSdfValue; PxArray denseSdf; { + PxArray indices32; + PxArray vertices; + const PxVec3* verticesPtr = NULL; + bool baseMeshSpecified = sdfDesc.baseMesh.triangles.data && sdfDesc.baseMesh.points.data; + if (baseMeshSpecified) + { + convert16To32Bits(sdfDesc.baseMesh, indices32); + + if (sdfDesc.baseMesh.points.stride != sizeof(PxVec3)) + { + vertices.resize(sdfDesc.baseMesh.points.count); + immediateCooking::gatherStrided(sdfDesc.baseMesh.points.data, vertices.begin(), sdfDesc.baseMesh.points.count, sizeof(PxVec3), sdfDesc.baseMesh.points.stride); + verticesPtr = vertices.begin(); + } + else + verticesPtr = reinterpret_cast(sdfDesc.baseMesh.points.data); + } + PxArray sparseSdf; - Gu::SDFUsingWindingNumbersSparse(&mesh.m_positions[0], &mesh.m_indices[0], mesh.m_indices.size(), dx, dy, dz, + Gu::SDFUsingWindingNumbersSparse( + baseMeshSpecified ? verticesPtr : &mesh.m_positions[0], + baseMeshSpecified ? indices32.begin() : &mesh.m_indices[0], + baseMeshSpecified ? indices32.size() : mesh.m_indices.size(), + dx, dy, dz, meshLower, meshLower + PxVec3(static_cast(dx), static_cast(dy), static_cast(dz)) * spacing, narrowBandThickness, sdfDesc.subgridSize, sdf, sdfSubgridsStartSlots, sparseSdf, denseSdf, subgridsMinSdfValue, subgridsMaxSdfValue, 16); diff --git a/physx/source/geomutils/src/GuGeometryChecks.h b/physx/source/geomutils/src/GuGeometryChecks.h index f61fc8ed9..d7ab2a5df 100644 --- a/physx/source/geomutils/src/GuGeometryChecks.h +++ b/physx/source/geomutils/src/GuGeometryChecks.h @@ -88,7 +88,9 @@ namespace physx } } +#if !defined(__CUDACC__) // the shape structure relies on punning capsules and spheres PX_COMPILE_TIME_ASSERT(PX_OFFSET_OF(physx::PxCapsuleGeometry, radius) == PX_OFFSET_OF(physx::PxSphereGeometry, radius)); +#endif #endif diff --git a/physx/source/geomutils/src/GuGeometryQuery.cpp b/physx/source/geomutils/src/GuGeometryQuery.cpp index 9086908be..d165040f0 100644 --- a/physx/source/geomutils/src/GuGeometryQuery.cpp +++ b/physx/source/geomutils/src/GuGeometryQuery.cpp @@ -200,7 +200,7 @@ PxU32 PxGeometryQuery::raycast( const PxVec3& rayOrigin, const PxVec3& rayDir, /////////////////////////////////////////////////////////////////////////////// -bool pointConvexDistance(PxVec3& normal_, PxVec3& closestPoint_, PxReal& sqDistance, const PxVec3& pt, const ConvexMesh* convexMesh, const PxMeshScale& meshScale, const PxTransform& convexPose); +bool pointConvexDistance(PxVec3& normal_, PxVec3& closestPoint_, PxReal& sqDistance, const PxVec3& pt, const ConvexMesh* convexMesh, const PxMeshScale& meshScale, const PxTransform32& convexPose); PxReal PxGeometryQuery::pointDistance(const PxVec3& point, const PxGeometry& geom, const PxTransform& pose, PxVec3* closestPoint, PxU32* closestIndex, PxGeometryQueryFlags queryFlags) { @@ -274,9 +274,11 @@ PxReal PxGeometryQuery::pointDistance(const PxVec3& point, const PxGeometry& geo { const PxConvexMeshGeometry& convexGeom = static_cast(geom); + const PxTransform32 poseA(pose); + PxVec3 normal, cp; PxReal sqDistance; - const bool intersect = pointConvexDistance(normal, cp, sqDistance, point, static_cast(convexGeom.convexMesh), convexGeom.scale, pose); + const bool intersect = pointConvexDistance(normal, cp, sqDistance, point, static_cast(convexGeom.convexMesh), convexGeom.scale, poseA); if(!intersect && closestPoint) *closestPoint = cp; return sqDistance; @@ -313,17 +315,6 @@ void PxGeometryQuery::computeGeomBounds(PxBounds3& bounds, const PxGeometry& geo PX_ASSERT(bounds.isValid()); } -PxBounds3 PxGeometryQuery::getWorldBounds(const PxGeometry& geom, const PxTransform& pose, float inflation) -{ - PX_SIMD_GUARD; - PX_CHECK_AND_RETURN_VAL(pose.isValid(), "PxGeometryQuery::getWorldBounds(): pose is not valid.", PxBounds3::empty()); - - PxBounds3 bounds; - Gu::computeBounds(bounds, geom, pose, 0.0f, inflation); - PX_ASSERT(bounds.isValid()); - return bounds; -} - /////////////////////////////////////////////////////////////////////////////// extern GeomMTDFunc gGeomMTDMethodTable[][PxGeometryType::eGEOMETRY_COUNT]; @@ -336,11 +327,14 @@ bool PxGeometryQuery::computePenetration( PxVec3& mtd, PxF32& depth, PX_CHECK_AND_RETURN_VAL(pose0.isValid(), "PxGeometryQuery::computePenetration(): pose0 is not valid.", false); PX_CHECK_AND_RETURN_VAL(pose1.isValid(), "PxGeometryQuery::computePenetration(): pose1 is not valid.", false); + const PxTransform32 pose0A(pose0); + const PxTransform32 pose1A(pose1); + if(geom0.getType() > geom1.getType()) { GeomMTDFunc mtdFunc = gGeomMTDMethodTable[geom1.getType()][geom0.getType()]; PX_ASSERT(mtdFunc); - if(!mtdFunc(mtd, depth, geom1, pose1, geom0, pose0)) + if(!mtdFunc(mtd, depth, geom1, pose1A, geom0, pose0A)) return false; mtd = -mtd; return true; @@ -349,7 +343,7 @@ bool PxGeometryQuery::computePenetration( PxVec3& mtd, PxF32& depth, { GeomMTDFunc mtdFunc = gGeomMTDMethodTable[geom0.getType()][geom1.getType()]; PX_ASSERT(mtdFunc); - return mtdFunc(mtd, depth, geom0, pose0, geom1, pose1); + return mtdFunc(mtd, depth, geom0, pose0A, geom1, pose1A); } } @@ -417,7 +411,7 @@ bool PxGeometryQuery::generateTriangleContacts(const PxGeometry& geom, const PxT PCMPolygonalBox polyBox(box.halfExtents); polyBox.getPolygonalData(&polyData); - Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); SupportLocalImpl boxMap(boxV, boxTransform, identity, identity, true); Gu::PCMConvexVsMeshContactGeneration contactGeneration(contactDist, replaceBreakingThreshold, boxTransform, meshTransform, multiManifold, contactBuffer0, polyData, &boxMap, &deferredContacts, idtScaling, true, true, NULL); diff --git a/physx/source/geomutils/src/GuGjkQuery.cpp b/physx/source/geomutils/src/GuGjkQuery.cpp index abaf712e2..d1073fe2a 100644 --- a/physx/source/geomutils/src/GuGjkQuery.cpp +++ b/physx/source/geomutils/src/GuGjkQuery.cpp @@ -164,7 +164,7 @@ struct PointConvexV : ConvexV Vec3V zero; PointConvexV() : ConvexV(Gu::ConvexType::eCUSTOM) { - zero = V3LoadU(PxVec3(0)); + zero = V3Zero(); setMinMargin(FLoad(0.001f)); setSweepMargin(FLoad(0.001f)); } diff --git a/physx/source/geomutils/src/GuMTD.cpp b/physx/source/geomutils/src/GuMTD.cpp index 5deb2350d..1c1afd98e 100644 --- a/physx/source/geomutils/src/GuMTD.cpp +++ b/physx/source/geomutils/src/GuMTD.cpp @@ -110,7 +110,7 @@ static PX_FORCE_INLINE bool ContactSphereBox(const PxVec3& sphereOrigin, PxReal sphereRadius, const PxVec3& boxExtents, // const PxcCachedTransforms& boxCacheTransform, - const PxTransform& boxTransform, + const PxTransform32& boxTransform, PxVec3& point, PxVec3& normal, PxReal& separation, @@ -230,7 +230,7 @@ static bool computeMTD_SphereBox(PxVec3& mtd, PxF32& depth, const Sphere& sphere { PxVec3 point; if(!ContactSphereBox( sphere.center, sphere.radius, - box.extents, PxTransform(box.center, PxQuat(box.rot)), + box.extents, PxTransform32(box.center, PxQuat(box.rot)), point, mtd, depth, 0.0f)) return false; depth = validateDepth(-depth); @@ -470,7 +470,7 @@ static bool computeMTD_BoxBox(PxVec3& _mtd, PxF32& _depth, const Box& box0, cons using namespace physx::aos; -bool pointConvexDistance(PxVec3& normal_, PxVec3& closestPoint_, PxReal& sqDistance, const PxVec3& pt, const ConvexMesh* convexMesh, const PxMeshScale& meshScale, const PxTransform& convexPose) +bool pointConvexDistance(PxVec3& normal_, PxVec3& closestPoint_, PxReal& sqDistance, const PxVec3& pt, const ConvexMesh* convexMesh, const PxMeshScale& meshScale, const PxTransform32& convexPose) { const PxTransform transform0(pt); @@ -516,7 +516,7 @@ bool pointConvexDistance(PxVec3& normal_, PxVec3& closestPoint_, PxReal& sqDista return intersect; } -static bool computeMTD_SphereConvex(PxVec3& mtd, PxF32& depth, const Sphere& sphere, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose) +static bool computeMTD_SphereConvex(PxVec3& mtd, PxF32& depth, const Sphere& sphere, const PxConvexMeshGeometry& convexGeom, const PxTransform32& convexPose) { PxReal d2; const ConvexMesh* convexMesh = static_cast(convexGeom.convexMesh); @@ -559,7 +559,7 @@ static bool internalComputeMTD_CapsuleConvex(const CapsuleV& capsule, const bool PolygonalData polyData; getPCMConvexData(convexHullV, idtScale, polyData); - PxU8 buff[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff[sizeof(SupportLocalImpl)]); SupportLocal* map = (idtScale ? static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(static_cast(convexHullV), transf1, convexHullV.vertex2Shape, convexHullV.shape2Vertex, idtScale)) : static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(convexHullV, transf1, convexHullV.vertex2Shape, convexHullV.shape2Vertex, idtScale))); @@ -567,7 +567,7 @@ static bool internalComputeMTD_CapsuleConvex(const CapsuleV& capsule, const bool return computeMTD(capsule, polyData, map, penetrationDepth, normal); } -static bool computeMTD_CapsuleConvex(PxVec3& mtd, PxF32& depth, const Capsule& capsule, const PxTransform& capsulePose, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose) +static bool computeMTD_CapsuleConvex(PxVec3& mtd, PxF32& depth, const Capsule& capsule, const PxTransform32& capsulePose, const PxConvexMeshGeometry& convexGeom, const PxTransform32& convexPose) { const FloatV capsuleHalfHeight = FLoad(capsule.length()*0.5f); const FloatV capsuleRadius = FLoad(capsule.radius); @@ -621,10 +621,10 @@ static bool internalComputeMTD_BoxConvex(const PxVec3 halfExtents, const BoxV& b PolygonalData polyData1; getPCMConvexData(convexHullV, idtScale, polyData1); - Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); SupportLocalImpl map0(box, transf0, identity, identity, true); - PxU8 buff[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff[sizeof(SupportLocalImpl)]); SupportLocal* map1 = (idtScale ? static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(static_cast(convexHullV), transf1, convexHullV.vertex2Shape, convexHullV.shape2Vertex, idtScale)) : static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(convexHullV, transf1, convexHullV.vertex2Shape, convexHullV.shape2Vertex, idtScale))); @@ -632,7 +632,7 @@ static bool internalComputeMTD_BoxConvex(const PxVec3 halfExtents, const BoxV& b return computeMTD(polyData0, polyData1, &map0, map1, penetrationDepth, normal); } -static bool computeMTD_BoxConvex(PxVec3& mtd, PxF32& depth, const Box& box, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose) +static bool computeMTD_BoxConvex(PxVec3& mtd, PxF32& depth, const Box& box, const PxConvexMeshGeometry& convexGeom, const PxTransform32& convexPose) { const Vec3V zeroV = V3Zero(); const PxTransform boxPose = box.getTransform(); @@ -678,8 +678,8 @@ static bool internalComputeMTD_ConvexConvex(const bool idtScale0, const bool idt getPCMConvexData(convexHullV0, idtScale0, polyData0); getPCMConvexData(convexHullV1, idtScale1, polyData1); - PxU8 buff0[sizeof(SupportLocalImpl)]; - PxU8 buff1[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff0[sizeof(SupportLocalImpl)]); + PX_ALIGN(16, PxU8 buff1[sizeof(SupportLocalImpl)]); SupportLocal* map0 = (idtScale0 ? static_cast(PX_PLACEMENT_NEW(buff0, SupportLocalImpl)(static_cast(convexHullV0), transf0, convexHullV0.vertex2Shape, convexHullV0.shape2Vertex, idtScale0)) : static_cast(PX_PLACEMENT_NEW(buff0, SupportLocalImpl)(convexHullV0, transf0, convexHullV0.vertex2Shape, convexHullV0.shape2Vertex, idtScale0))); @@ -691,7 +691,7 @@ static bool internalComputeMTD_ConvexConvex(const bool idtScale0, const bool idt } /////////////////////////////////////////////////////////////////////////////// -static bool computeMTD_ConvexConvex(PxVec3& mtd, PxF32& depth, const PxConvexMeshGeometry& convexGeom0, const PxTransform& convexPose0, const PxConvexMeshGeometry& convexGeom1, const PxTransform& convexPose1) +static bool computeMTD_ConvexConvex(PxVec3& mtd, PxF32& depth, const PxConvexMeshGeometry& convexGeom0, const PxTransform32& convexPose0, const PxConvexMeshGeometry& convexGeom1, const PxTransform32& convexPose1) { using namespace aos; @@ -783,7 +783,7 @@ static bool computeMTD_PlaneCapsule(PxVec3& mtd, PxF32& depth, const PxPlane& pl return true; } -static bool computeMTD_PlaneConvex(PxVec3& mtd, PxF32& depth, const PxPlane& plane, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose) +static bool computeMTD_PlaneConvex(PxVec3& mtd, PxF32& depth, const PxPlane& plane, const PxConvexMeshGeometry& convexGeom, const PxTransform32& convexPose) { const ConvexMesh* convexMesh = static_cast(convexGeom.convexMesh); PxU32 nbVerts = convexMesh->getNbVerts(); @@ -841,22 +841,22 @@ static bool processContacts(PxVec3& mtd, PxF32& depth, const PxU32 nbContacts, c return nbContacts!=0; } -static bool computeMTD_SphereMesh(PxVec3& mtd, PxF32& depth, const Sphere& sphere, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_SphereMesh(PxVec3& mtd, PxF32& depth, const Sphere& sphere, const PxTriangleMeshGeometry& meshGeom, const PxTransform32& meshPose) { Cache cache; PxContactBuffer contactBuffer; contactBuffer.reset(); - if(!contactSphereMesh(PxSphereGeometry(sphere.radius), meshGeom, PxTransform(sphere.center), meshPose, NarrowPhaseParams(0.0f, 0.0f, 1.0f), cache, contactBuffer, NULL)) + if(!contactSphereMesh(PxSphereGeometry(sphere.radius), meshGeom, PxTransform32(sphere.center), meshPose, NarrowPhaseParams(0.0f, 0.0f, 1.0f), cache, contactBuffer, NULL)) return false; return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_CapsuleMesh(PxVec3& mtd, PxF32& depth, const Capsule& capsule, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_CapsuleMesh(PxVec3& mtd, PxF32& depth, const Capsule& capsule, const PxTriangleMeshGeometry& meshGeom, const PxTransform32& meshPose) { PxReal halfHeight; - const PxTransform capsuleTransform = PxTransformFromSegment(capsule.p0, capsule.p1, &halfHeight); + const PxTransform32 capsuleTransform(PxTransformFromSegment(capsule.p0, capsule.p1, &halfHeight)); Cache cache; PxContactBuffer contactBuffer; @@ -868,9 +868,9 @@ static bool computeMTD_CapsuleMesh(PxVec3& mtd, PxF32& depth, const Capsule& cap return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_BoxMesh(PxVec3& mtd, PxF32& depth, const Box& box, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_BoxMesh(PxVec3& mtd, PxF32& depth, const Box& box, const PxTriangleMeshGeometry& meshGeom, const PxTransform32& meshPose) { - const PxTransform boxPose(box.center, PxQuat(box.rot)); + const PxTransform32 boxPose(box.center, PxQuat(box.rot)); Cache cache; PxContactBuffer contactBuffer; @@ -882,7 +882,7 @@ static bool computeMTD_BoxMesh(PxVec3& mtd, PxF32& depth, const Box& box, const return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_ConvexMesh(PxVec3& mtd, PxF32& depth, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_ConvexMesh(PxVec3& mtd, PxF32& depth, const PxConvexMeshGeometry& convexGeom, const PxTransform32& convexPose, const PxTriangleMeshGeometry& meshGeom, const PxTransform32& meshPose) { Cache cache; PxContactBuffer contactBuffer; @@ -894,13 +894,13 @@ static bool computeMTD_ConvexMesh(PxVec3& mtd, PxF32& depth, const PxConvexMeshG return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_SphereHeightField(PxVec3& mtd, PxF32& depth, const Sphere& sphere, const PxHeightFieldGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_SphereHeightField(PxVec3& mtd, PxF32& depth, const Sphere& sphere, const PxHeightFieldGeometry& meshGeom, const PxTransform32& meshPose) { Cache cache; PxContactBuffer contactBuffer; contactBuffer.reset(); - const PxTransform spherePose(sphere.center); + const PxTransform32 spherePose(sphere.center); if(!contactSphereHeightfield(PxSphereGeometry(sphere.radius), meshGeom, spherePose, meshPose, NarrowPhaseParams(0.0f, 0.0f, 1.0f), cache, contactBuffer, NULL)) return false; @@ -908,10 +908,10 @@ static bool computeMTD_SphereHeightField(PxVec3& mtd, PxF32& depth, const Sphere return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_CapsuleHeightField(PxVec3& mtd, PxF32& depth, const Capsule& capsule, const PxHeightFieldGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_CapsuleHeightField(PxVec3& mtd, PxF32& depth, const Capsule& capsule, const PxHeightFieldGeometry& meshGeom, const PxTransform32& meshPose) { PxReal halfHeight; - const PxTransform capsuleTransform = PxTransformFromSegment(capsule.p0, capsule.p1, &halfHeight); + const PxTransform32 capsuleTransform(PxTransformFromSegment(capsule.p0, capsule.p1, &halfHeight)); Cache cache; PxContactBuffer contactBuffer; @@ -923,9 +923,9 @@ static bool computeMTD_CapsuleHeightField(PxVec3& mtd, PxF32& depth, const Capsu return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_BoxHeightField(PxVec3& mtd, PxF32& depth, const Box& box, const PxHeightFieldGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_BoxHeightField(PxVec3& mtd, PxF32& depth, const Box& box, const PxHeightFieldGeometry& meshGeom, const PxTransform32& meshPose) { - const PxTransform boxPose(box.center, PxQuat(box.rot)); + const PxTransform32 boxPose(box.center, PxQuat(box.rot)); Cache cache; PxContactBuffer contactBuffer; @@ -937,7 +937,7 @@ static bool computeMTD_BoxHeightField(PxVec3& mtd, PxF32& depth, const Box& box, return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_ConvexHeightField(PxVec3& mtd, PxF32& depth, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose, const PxHeightFieldGeometry& meshGeom, const PxTransform& meshPose) +static bool computeMTD_ConvexHeightField(PxVec3& mtd, PxF32& depth, const PxConvexMeshGeometry& convexGeom, const PxTransform32& convexPose, const PxHeightFieldGeometry& meshGeom, const PxTransform32& meshPose) { Cache cache; PxContactBuffer contactBuffer; @@ -949,7 +949,7 @@ static bool computeMTD_ConvexHeightField(PxVec3& mtd, PxF32& depth, const PxConv return processContacts(mtd, depth, contactBuffer.count, contactBuffer.contacts); } -static bool computeMTD_CustomGeometry(PxVec3& mtd, PxF32& depth, const PxCustomGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1) +static bool computeMTD_CustomGeometry(PxVec3& mtd, PxF32& depth, const PxCustomGeometry& geom0, const PxTransform32& pose0, const PxGeometry& geom1, const PxTransform32& pose1) { Cache cache; PxContactBuffer contactBuffer; diff --git a/physx/source/geomutils/src/GuMTD.h b/physx/source/geomutils/src/GuMTD.h index 1340217ad..f1817c387 100644 --- a/physx/source/geomutils/src/GuMTD.h +++ b/physx/source/geomutils/src/GuMTD.h @@ -30,6 +30,7 @@ #define GU_MTD_H #include "foundation/PxVec3.h" +#include "foundation/PxTransform.h" #include "geometry/PxGeometry.h" namespace physx @@ -45,9 +46,9 @@ namespace Gu // \param[in] geom1 second geometry object // \param[in] pose1 pose of second geometry object // \param[in] cache optional cached data for triggers - #define GU_MTD_FUNC_PARAMS PxVec3& mtd, PxF32& depth, \ - const PxGeometry& geom0, const PxTransform& pose0, \ - const PxGeometry& geom1, const PxTransform& pose1 + #define GU_MTD_FUNC_PARAMS PxVec3& mtd, PxF32& depth, \ + const PxGeometry& geom0, const PxTransform32& pose0, \ + const PxGeometry& geom1, const PxTransform32& pose1 // PT: function pointer for Geom-indexed MTD functions // See GU_MTD_FUNC_PARAMS for function parameters details. diff --git a/physx/source/geomutils/src/GuOverlapTests.cpp b/physx/source/geomutils/src/GuOverlapTests.cpp index 55168792b..e81fd462a 100644 --- a/physx/source/geomutils/src/GuOverlapTests.cpp +++ b/physx/source/geomutils/src/GuOverlapTests.cpp @@ -395,6 +395,7 @@ static bool GeomOverlapCallback_PlaneConvex(GU_OVERLAP_FUNC_PARAMS) ConvexMesh* cm = static_cast(convexGeom.convexMesh); //find plane normal in shape space of convex: + // PT:: tag: scalar transform*transform const PxTransform plane2convex = pose1.getInverse().transform(pose0); const PxPlane shapeSpacePlane = getPlane(plane2convex); @@ -593,17 +594,6 @@ static bool GeomOverlapCallback_NotSupported(GU_OVERLAP_FUNC_PARAMS) return false; } -static bool GeomOverlapCallback_HeightfieldUnregistered(GU_OVERLAP_FUNC_PARAMS) -{ - PX_UNUSED(threadContext); - PX_UNUSED(cache); - PX_UNUSED(geom0); - PX_UNUSED(geom1); - PX_UNUSED(pose0); - PX_UNUSED(pose1); - return PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Height Field Overlap test called with height fields unregistered "); -} - bool GeomOverlapCallback_SphereMesh (GU_OVERLAP_FUNC_PARAMS); bool GeomOverlapCallback_CapsuleMesh (GU_OVERLAP_FUNC_PARAMS); bool GeomOverlapCallback_BoxMesh (GU_OVERLAP_FUNC_PARAMS); @@ -631,77 +621,77 @@ GeomOverlapTable gGeomOverlapMethodTable[] = { //PxGeometryType::eSPHERE { - GeomOverlapCallback_SphereSphere, //PxGeometryType::eSPHERE - GeomOverlapCallback_SpherePlane, //PxGeometryType::ePLANE - GeomOverlapCallback_SphereCapsule, //PxGeometryType::eCAPSULE - GeomOverlapCallback_SphereBox, //PxGeometryType::eBOX - GeomOverlapCallback_SphereConvex, //PxGeometryType::eCONVEXMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM - GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH - GeomOverlapCallback_SphereMesh, //PxGeometryType::eTRIANGLEMESH - GeomOverlapCallback_HeightfieldUnregistered, //PxGeometryType::eHEIGHTFIELD - GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM - GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM + GeomOverlapCallback_SphereSphere, //PxGeometryType::eSPHERE + GeomOverlapCallback_SpherePlane, //PxGeometryType::ePLANE + GeomOverlapCallback_SphereCapsule, //PxGeometryType::eCAPSULE + GeomOverlapCallback_SphereBox, //PxGeometryType::eBOX + GeomOverlapCallback_SphereConvex, //PxGeometryType::eCONVEXMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM + GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH + GeomOverlapCallback_SphereMesh, //PxGeometryType::eTRIANGLEMESH + GeomOverlapCallback_SphereHeightfield, //PxGeometryType::eHEIGHTFIELD + GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM + GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::ePLANE { - 0, //PxGeometryType::eSPHERE - GeomOverlapCallback_NotSupported, //PxGeometryType::ePLANE - GeomOverlapCallback_PlaneCapsule, //PxGeometryType::eCAPSULE - GeomOverlapCallback_PlaneBox, //PxGeometryType::eBOX - GeomOverlapCallback_PlaneConvex, //PxGeometryType::eCONVEXMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM - GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::eTRIANGLEMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::eHEIGHTFIELD - GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM - GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + GeomOverlapCallback_NotSupported, //PxGeometryType::ePLANE + GeomOverlapCallback_PlaneCapsule, //PxGeometryType::eCAPSULE + GeomOverlapCallback_PlaneBox, //PxGeometryType::eBOX + GeomOverlapCallback_PlaneConvex, //PxGeometryType::eCONVEXMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM + GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::eTRIANGLEMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::eHEIGHTFIELD + GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM + GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::eCAPSULE { - 0, //PxGeometryType::eSPHERE - 0, //PxGeometryType::ePLANE - GeomOverlapCallback_CapsuleCapsule, //PxGeometryType::eCAPSULE - GeomOverlapCallback_CapsuleBox, //PxGeometryType::eBOX - GeomOverlapCallback_CapsuleConvex, //PxGeometryType::eCONVEXMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM - GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH - GeomOverlapCallback_CapsuleMesh, //PxGeometryType::eTRIANGLEMESH - GeomOverlapCallback_HeightfieldUnregistered, //PxGeometryType::eHEIGHTFIELD - GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM - GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + 0, //PxGeometryType::ePLANE + GeomOverlapCallback_CapsuleCapsule, //PxGeometryType::eCAPSULE + GeomOverlapCallback_CapsuleBox, //PxGeometryType::eBOX + GeomOverlapCallback_CapsuleConvex, //PxGeometryType::eCONVEXMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM + GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH + GeomOverlapCallback_CapsuleMesh, //PxGeometryType::eTRIANGLEMESH + GeomOverlapCallback_CapsuleHeightfield, //PxGeometryType::eHEIGHTFIELD + GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM + GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::eBOX { - 0, //PxGeometryType::eSPHERE - 0, //PxGeometryType::ePLANE - 0, //PxGeometryType::eCAPSULE - GeomOverlapCallback_BoxBox, //PxGeometryType::eBOX - GeomOverlapCallback_BoxConvex, //PxGeometryType::eCONVEXMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM - GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH - GeomOverlapCallback_BoxMesh, //PxGeometryType::eTRIANGLEMESH - GeomOverlapCallback_HeightfieldUnregistered, //PxGeometryType::eHEIGHTFIELD - GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM - GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + 0, //PxGeometryType::ePLANE + 0, //PxGeometryType::eCAPSULE + GeomOverlapCallback_BoxBox, //PxGeometryType::eBOX + GeomOverlapCallback_BoxConvex, //PxGeometryType::eCONVEXMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM + GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH + GeomOverlapCallback_BoxMesh, //PxGeometryType::eTRIANGLEMESH + GeomOverlapCallback_BoxHeightfield, //PxGeometryType::eHEIGHTFIELD + GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM + GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::eCONVEXMESH { - 0, //PxGeometryType::eSPHERE - 0, //PxGeometryType::ePLANE - 0, //PxGeometryType::eCAPSULE - 0, //PxGeometryType::eBOX - GeomOverlapCallback_ConvexConvex, //PxGeometryType::eCONVEXMESH - GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM - GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH - GeomOverlapCallback_ConvexMesh, //PxGeometryType::eTRIANGLEMESH //not used: mesh always uses swept method for midphase. - GeomOverlapCallback_HeightfieldUnregistered, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this - GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM - GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + 0, //PxGeometryType::ePLANE + 0, //PxGeometryType::eCAPSULE + 0, //PxGeometryType::eBOX + GeomOverlapCallback_ConvexConvex, //PxGeometryType::eCONVEXMESH + GeomOverlapCallback_NotSupported, //PxGeometryType::ePARTICLESYSTEM + GeomOverlapCallback_NotSupported, //PxGeometryType::eTETRAHEDRONMESH + GeomOverlapCallback_ConvexMesh, //PxGeometryType::eTRIANGLEMESH //not used: mesh always uses swept method for midphase. + GeomOverlapCallback_ConvexHeightfield, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + GeomOverlapCallback_NotSupported, //PxGeometryType::eHAIRSYSTEM + GeomOverlapCallback_CustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::ePARTICLESYSTEM @@ -801,15 +791,3 @@ const GeomOverlapTable* Gu::getOverlapFuncTable() return gGeomOverlapMethodTable; } -void registerHeightFields_Raycasts(); -void registerHeightFields_Sweeps(); -void Gu::registerHeightFields() -{ - registerHeightFields_Raycasts(); - registerHeightFields_Sweeps(); - - gGeomOverlapMethodTable[PxGeometryType::eSPHERE][PxGeometryType::eHEIGHTFIELD] = GeomOverlapCallback_SphereHeightfield; - gGeomOverlapMethodTable[PxGeometryType::eCAPSULE][PxGeometryType::eHEIGHTFIELD] = GeomOverlapCallback_CapsuleHeightfield; - gGeomOverlapMethodTable[PxGeometryType::eBOX][PxGeometryType::eHEIGHTFIELD] = GeomOverlapCallback_BoxHeightfield; - gGeomOverlapMethodTable[PxGeometryType::eCONVEXMESH][PxGeometryType::eHEIGHTFIELD] = GeomOverlapCallback_ConvexHeightfield; -} diff --git a/physx/source/geomutils/src/GuPruningPool.cpp b/physx/source/geomutils/src/GuPruningPool.cpp index 3ce08784b..d5780393c 100644 --- a/physx/source/geomutils/src/GuPruningPool.cpp +++ b/physx/source/geomutils/src/GuPruningPool.cpp @@ -230,7 +230,7 @@ static void updateAndInflateBounds(PruningPool& pool, const PrunerHandle* PX_RES const PxU32 remappedIndex = *boundsIndices++; if(hasTransforms) - transforms[poolIndex] = newTransforms[remappedIndex].transform; + transforms[poolIndex] = newTransforms[remappedIndex]; inflateBounds(bounds[poolIndex], newBounds[remappedIndex], epsilon); } @@ -244,7 +244,7 @@ static void updateAndInflateBounds(PruningPool& pool, const PrunerHandle* PX_RES if(hasTransforms) { - transforms[poolIndex] = newTransforms->transform; + transforms[poolIndex] = *newTransforms; newTransforms++; } diff --git a/physx/source/geomutils/src/GuRaycastTests.cpp b/physx/source/geomutils/src/GuRaycastTests.cpp index 92cbda0db..3763f7c73 100644 --- a/physx/source/geomutils/src/GuRaycastTests.cpp +++ b/physx/source/geomutils/src/GuRaycastTests.cpp @@ -600,22 +600,6 @@ PxU32 raycast_heightField(GU_RAY_FUNC_PARAMS) return callback.mNbHits; } -static PxU32 raycast_heightField_unregistered(GU_RAY_FUNC_PARAMS) -{ - PX_UNUSED(threadContext); - PX_UNUSED(stride); - PX_UNUSED(geom); - PX_UNUSED(pose); - PX_UNUSED(rayOrigin); - PX_UNUSED(rayDir); - PX_UNUSED(maxDist); - PX_UNUSED(hitFlags); - PX_UNUSED(maxHits); - PX_UNUSED(hits); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Height Field Raycast test called with height fields unregistered "); - return 0; -} - static PxU32 raycast_custom(GU_RAY_FUNC_PARAMS) { const PxCustomGeometry& customGeom = static_cast(geom); @@ -637,7 +621,7 @@ RaycastFunc gRaycastMap[] = raycast_particlesystem, raycast_softbody, raycast_triangleMesh, - raycast_heightField_unregistered, + raycast_heightField, raycast_hairsystem, raycast_custom }; @@ -649,7 +633,3 @@ const Gu::GeomRaycastTable& Gu::getRaycastFuncTable() return gRaycastMap; } -void registerHeightFields_Raycasts() -{ - gRaycastMap[PxGeometryType::eHEIGHTFIELD] = raycast_heightField; -} diff --git a/physx/source/geomutils/src/GuSDF.cpp b/physx/source/geomutils/src/GuSDF.cpp index e776668a3..23fa03727 100644 --- a/physx/source/geomutils/src/GuSDF.cpp +++ b/physx/source/geomutils/src/GuSDF.cpp @@ -36,7 +36,6 @@ #include "GuAABBTreeNode.h" #include "GuDistancePointBox.h" #include "GuDistancePointTriangle.h" -#include "GuDistancePointTriangleSIMD.h" #include "GuAABBTreeQuery.h" #include "GuIntersectionRayTriangle.h" #include "GuIntersectionRayBox.h" @@ -44,6 +43,7 @@ #include "foundation/PxAtomic.h" #include "foundation/PxThread.h" #include "common/GuMeshAnalysis.h" +#include "GuMeshAnalysis.h" namespace physx { @@ -203,9 +203,22 @@ namespace Gu PxI32 mClosestTriId; public: - PX_FORCE_INLINE ClosestDistanceToTrimeshTraversalController(const PxU32* triangles, const PxVec3* points, Gu::BVHNode* nodes, const PxVec3& queryPoint) : - mTriangles(triangles), mPoints(points), mNodes(nodes), mQueryPoint(queryPoint), mClosestPoint(0.0f), mClosestTriId(-1) + PX_FORCE_INLINE ClosestDistanceToTrimeshTraversalController(){} + + PX_FORCE_INLINE ClosestDistanceToTrimeshTraversalController(const PxU32* triangles, const PxVec3* points, Gu::BVHNode* nodes) : + mTriangles(triangles), mPoints(points), mNodes(nodes), mQueryPoint(0.0f), mClosestPoint(0.0f), mClosestTriId(-1) + { + initialize(triangles, points, nodes); + } + + void initialize(const PxU32* triangles, const PxVec3* points, Gu::BVHNode* nodes) { + mTriangles = triangles; + mPoints = points; + mNodes = nodes; + mQueryPoint = PxVec3(0.0f); + mClosestPoint = PxVec3(0.0f); + mClosestTriId = -1; mClosestDistanceSquared = PX_MAX_F32; } @@ -217,7 +230,7 @@ namespace Gu mClosestTriId = -1; } - PX_FORCE_INLINE const PxVec3& closestPoint() const + PX_FORCE_INLINE const PxVec3& getClosestPoint() const { return mClosestPoint; } @@ -295,6 +308,46 @@ namespace Gu PX_NOCOPY(ClosestDistanceToTrimeshTraversalController) }; + class PointOntoTriangleMeshProjector : public PxPointOntoTriangleMeshProjector, public PxUserAllocated + { + PxArray mNodes; + ClosestDistanceToTrimeshTraversalController mEvaluator; + public: + PointOntoTriangleMeshProjector(const PxVec3* vertices, const PxU32* indices, PxU32 numTriangles) + { + buildTree(indices, numTriangles, vertices, mNodes); + mEvaluator.initialize(indices, vertices, mNodes.begin()); + } + + virtual PxVec3 projectPoint(const PxVec3& point) PX_OVERRIDE + { + mEvaluator.setQueryPoint(point); + Gu::traverseBVH(mNodes.begin(), mEvaluator); + PxVec3 closestPoint = mEvaluator.getClosestPoint(); + return closestPoint; + } + + virtual PxVec3 projectPoint(const PxVec3& point, PxU32& closetTriangleIndex) PX_OVERRIDE + { + mEvaluator.setQueryPoint(point); + Gu::traverseBVH(mNodes.begin(), mEvaluator); + PxVec3 closestPoint = mEvaluator.getClosestPoint(); + closetTriangleIndex = mEvaluator.getClosestTriId(); + return closestPoint; + } + + virtual void release() PX_OVERRIDE + { + mNodes.reset(); + PX_FREE_THIS; + } + }; + + PxPointOntoTriangleMeshProjector* PxCreatePointOntoTriangleMeshProjector(const PxVec3* vertices, const PxU32* indices, PxU32 numTriangleIndices) + { + return PX_NEW(PointOntoTriangleMeshProjector)(vertices, indices, numTriangleIndices); + } + void windingNumbers(const PxVec3* vertices, const PxU32* indices, PxU32 numTriangleIndices, PxU32 width, PxU32 height, PxU32 depth, PxReal* windingNumbers, PxVec3 min, PxVec3 max, PxVec3* sampleLocations) { @@ -611,11 +664,11 @@ namespace Gu { for (PxU32 x = 0; x < d.width; ++x) { - const PxI32 index = z * d.width * d.height + y * d.width + x; + const PxU32 index = z * d.width * d.height + y * d.width + x; PxVec3 queryPoint = d.pointSampler->getPoint(x, y, z); - ClosestDistanceToTrimeshTraversalController cd(d.indices, d.vertices, d.tree->begin(), PxVec3(0.0f)); + ClosestDistanceToTrimeshTraversalController cd(d.indices, d.vertices, d.tree->begin()); cd.setQueryPoint(queryPoint); if (lastTriangle != -1) @@ -635,7 +688,7 @@ namespace Gu } Gu::traverseBVH(d.tree->begin(), cd); - PxVec3 closestPoint = cd.closestPoint(); + PxVec3 closestPoint = cd.getClosestPoint(); PxReal closestDistance = (closestPoint - queryPoint).magnitude(); lastTriangle = cd.getClosestTriId(); @@ -965,12 +1018,180 @@ namespace Gu if (!isWatertight) fixSdfForNonClosedGeometry(width, height, depth, sdf, sampler.getActiveCellSize()); } + //Helper class to extract surface triangles from a tetmesh + struct SortedTriangle + { + public: + PxI32 mA; + PxI32 mB; + PxI32 mC; + bool mFlipped; + PX_FORCE_INLINE SortedTriangle(PxI32 a, PxI32 b, PxI32 c) + { + mA = a; mB = b; mC = c; mFlipped = false; + if (mA > mB) { PxSwap(mA, mB); mFlipped = !mFlipped; } + if (mB > mC) { PxSwap(mB, mC); mFlipped = !mFlipped; } + if (mA > mB) { PxSwap(mA, mB); mFlipped = !mFlipped; } + } + }; + struct TriangleHash + { + PX_FORCE_INLINE std::size_t operator()(const SortedTriangle& k) const + { + return k.mA ^ k.mB ^ k.mC; + } + PX_FORCE_INLINE bool equal(const SortedTriangle& first, const SortedTriangle& second) const + { + return first.mA == second.mA && first.mB == second.mB && first.mC == second.mC; + } + }; + PxReal signedVolume(const PxVec3* points, const PxU32* triangles, PxU32 numTriangles, const PxU32* triangleSubset = NULL, PxU32 setLength = 0) + { + PxReal signedVolume = 0; + const PxU32 l = triangleSubset ? setLength : numTriangles; + for (PxU32 j = 0; j < l; ++j) + { + const PxU32 i = triangleSubset ? triangleSubset[j] : j; + const PxU32* tri = &triangles[3 * i]; + PxVec3 a = points[tri[0]]; + PxVec3 b = points[tri[1]]; + PxVec3 c = points[tri[2]]; + PxReal y = a.dot(b.cross(c)); + signedVolume += y; + } + signedVolume *= (1.0f / 6.0f); + return signedVolume; + } + void analyzeAndFixMesh(const PxVec3* vertices, const PxU32* indicesOrig, PxU32 numTriangleIndices, PxArray& repairedIndices) + { + const PxU32* indices = indicesOrig; + PxI32 numVertices = -1; + for (PxU32 i = 0; i < numTriangleIndices; ++i) + numVertices = PxMax(numVertices, PxI32(indices[i])); + ++numVertices; + //Check for duplicate vertices + PxArray map; + MeshAnalyzer::mapDuplicatePoints(vertices, PxU32(numVertices), map, 0.0f); + bool hasDuplicateVertices = false; + for (PxU32 i = 0; i < map.size(); ++i) + { + if (map[i] != PxI32(i)) + { + hasDuplicateVertices = true; + break; + } + } + if (hasDuplicateVertices) + { + repairedIndices.resize(numTriangleIndices); + for (PxU32 i = 0; i < numTriangleIndices; ++i) + repairedIndices[i] = map[indices[i]]; + indices = repairedIndices.begin(); + } + //Check for duplicate triangles + PxHashMap tris; + bool hasDuplicateTriangles = false; + for (PxU32 i = 0; i < numTriangleIndices; i += 3) + { + SortedTriangle tri(indices[i], indices[i + 1], indices[i + 2]); + if (const PxPair* ptr = tris.find(tri)) + { + tris[tri] = ptr->second + 1; + hasDuplicateTriangles = true; + } + else + tris.insert(tri, 1); + } + if (hasDuplicateTriangles) + { + repairedIndices.clear(); + for (PxHashMap::Iterator iter = tris.getIterator(); !iter.done(); ++iter) + { + repairedIndices.pushBack(iter->first.mA); + if (iter->first.mFlipped) + { + repairedIndices.pushBack(iter->first.mC); + repairedIndices.pushBack(iter->first.mB); + } + else + { + repairedIndices.pushBack(iter->first.mB); + repairedIndices.pushBack(iter->first.mC); + } + } + } + else + { + if (!hasDuplicateVertices) //reqairedIndices is already initialized if hasDuplicateVertices is true + { + repairedIndices.resize(numTriangleIndices); + for (PxU32 i = 0; i < numTriangleIndices; ++i) + repairedIndices[i] = indices[i]; + } + } + PxHashMap edges; + PxArray flipTriangle; + PxArray> connectedTriangleGroups; + Triangle* triangles = reinterpret_cast(repairedIndices.begin()); + bool success = MeshAnalyzer::buildConsistentTriangleOrientationMap(triangles, repairedIndices.size() / 3, flipTriangle, edges, connectedTriangleGroups); + bool meshIsWatertight = true; + for (PxHashMap::Iterator iter = edges.getIterator(); !iter.done(); ++iter) + { + if (iter->second != -1) + { + meshIsWatertight = false; + break; + } + } + if (success) + { + if (hasDuplicateTriangles && meshIsWatertight && connectedTriangleGroups.size() == 1) + { + for (PxU32 i = 0; i < flipTriangle.size(); ++i) + { + Triangle& t = triangles[i]; + if (flipTriangle[i]) + PxSwap(t[0], t[1]); + } + + if (signedVolume(vertices, repairedIndices.begin(), repairedIndices.size() / 3) < 0.0f) + { + PxU32 numTriangles = repairedIndices.size() / 3; + for (PxU32 j = 0; j < numTriangles; ++j) + { + PxU32* tri = &repairedIndices[j * 3]; + PxSwap(tri[1], tri[2]); + } + } + } + } + else + { + //Here it is not possible to guarantee that the mesh fixing can succeed + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "SDF creation: Fixing of the input mesh topology not possible. The computed SDF might not work as expected. Please try to improve the mesh structure by e. g. applying remeshing."); + //connectedTriangleGroups won't have any elements, so return + return; + } - void SDFUsingWindingNumbers(const PxVec3* vertices, const PxU32* indices, PxU32 numTriangleIndices, PxU32 width, PxU32 height, PxU32 depth, + if (!meshIsWatertight) + { + PxGetFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, "SDF creation: Input mesh is not watertight. The SDF will try to close the holes to its best knowledge."); + } + } + + void SDFUsingWindingNumbers(const PxVec3* vertices, const PxU32* indicesOrig, PxU32 numTriangleIndices, PxU32 width, PxU32 height, PxU32 depth, PxReal* sdf, PxVec3 minExtents, PxVec3 maxExtents, PxVec3* sampleLocations, bool cellCenteredSamples, PxU32 numThreads) { + PxArray repairedIndices; + //Analyze the mesh to catch and fix some special cases + //There are meshes where every triangle is present once with cw and once with ccw orientation. Try to filter out only one set + analyzeAndFixMesh(vertices, indicesOrig, numTriangleIndices, repairedIndices); + const PxU32* indices = repairedIndices.size() > 0 ? repairedIndices.begin() : indicesOrig; + if (repairedIndices.size() > 0) + numTriangleIndices = repairedIndices.size(); + PxArray tree; buildTree(indices, numTriangleIndices / 3, vertices, tree); @@ -1090,6 +1311,7 @@ namespace Gu numSubgridsX * (cellsPerSubgrid + 1), numSubgridsY * (cellsPerSubgrid + 1)); PX_ASSERT(subgrids3DTexFormat[index] == placeholder); subgrids3DTexFormat[index] = sdfValue; + PX_ASSERT(PxIsFinite(sdfValue)); } } } diff --git a/physx/source/geomutils/src/GuSDF.h b/physx/source/geomutils/src/GuSDF.h index 52468c89a..35082af10 100644 --- a/physx/source/geomutils/src/GuSDF.h +++ b/physx/source/geomutils/src/GuSDF.h @@ -261,6 +261,46 @@ namespace physx \param[out] isosurfaceTriangleIndices The triangles of the extracted isosurface */ PX_PHYSX_COMMON_API void extractIsosurfaceFromSDF(const Gu::SDF& sdf, PxArray& isosurfaceVertices, PxArray& isosurfaceTriangleIndices); + + + /** + \brief A class that allows to efficiently project points onto the surface of a triangle mesh. + */ + class PxPointOntoTriangleMeshProjector + { + public: + /** + \brief Projects a point onto the surface of a triangle mesh. + + \param[in] point The point to project + \return the projected point + */ + virtual PxVec3 projectPoint(const PxVec3& point) = 0; + + /** + \brief Projects a point onto the surface of a triangle mesh. + + \param[in] point The point to project + \param[out] closestTriangleIndex The index of the triangle on which the projected point is located + \return the projected point + */ + virtual PxVec3 projectPoint(const PxVec3& point, PxU32& closestTriangleIndex) = 0; + + /** + \brief Releases the instance and its data + */ + virtual void release() = 0; + }; + + /** + \brief Creates a helper class that allows to efficiently project points onto the surface of a triangle mesh. + + \param[in] vertices The triangle mesh's vertices + \param[in] triangleIndices The triangle mesh's indices + \param[in] numTriangles The number of triangles + \return A point onto triangle mesh projector instance. The caller needs to delete the instance once it is not used anymore by calling its release method + */ + PX_PHYSX_COMMON_API PxPointOntoTriangleMeshProjector* PxCreatePointOntoTriangleMeshProjector(const PxVec3* vertices, const PxU32* triangleIndices, PxU32 numTriangles); } } diff --git a/physx/source/geomutils/src/GuSweepTests.cpp b/physx/source/geomutils/src/GuSweepTests.cpp index 049b458a3..deed21dbb 100644 --- a/physx/source/geomutils/src/GuSweepTests.cpp +++ b/physx/source/geomutils/src/GuSweepTests.cpp @@ -410,9 +410,9 @@ bool Gu::sweepBoxTriangles(GU_SWEEP_TRIANGLES_FUNC_PARAMS(PxBoxGeometry)) { const PxU32 triangleIndex = getTriangleIndex(ii, idx); - const Vec3V localV0 = V3LoadU(triangles[triangleIndex].verts[0]); - const Vec3V localV1 = V3LoadU(triangles[triangleIndex].verts[1]); - const Vec3V localV2 = V3LoadU(triangles[triangleIndex].verts[2]); + const Vec3V localV0 = V3LoadU(triangles[triangleIndex].verts[0]); + const Vec3V localV1 = V3LoadU(triangles[triangleIndex].verts[1]); + const Vec3V localV2 = V3LoadU(triangles[triangleIndex].verts[2]); const Vec3V triV0 = worldToBoxV.transform(localV0); const Vec3V triV1 = worldToBoxV.transform(localV1); @@ -572,53 +572,6 @@ static bool sweepConvex_InvalidGeom(GU_CONVEX_SWEEP_FUNC_PARAMS) return false; } -static bool sweepCapsule_HeightfieldUnregistered(GU_CAPSULE_SWEEP_FUNC_PARAMS) -{ - PX_UNUSED(threadContext); - PX_UNUSED(capsuleGeom_); - PX_UNUSED(capsulePose_); - PX_UNUSED(geom); - PX_UNUSED(pose); - PX_UNUSED(lss); - PX_UNUSED(unitDir); - PX_UNUSED(distance); - PX_UNUSED(sweepHit); - PX_UNUSED(hitFlags); - PX_UNUSED(inflation); - return PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Height Field Sweep test called with height fields unregistered "); -} - -static bool sweepBox_HeightfieldUnregistered(GU_BOX_SWEEP_FUNC_PARAMS) -{ - PX_UNUSED(threadContext); - PX_UNUSED(boxPose_); - PX_UNUSED(boxGeom_); - PX_UNUSED(geom); - PX_UNUSED(pose); - PX_UNUSED(box); - PX_UNUSED(unitDir); - PX_UNUSED(distance); - PX_UNUSED(sweepHit); - PX_UNUSED(hitFlags); - PX_UNUSED(inflation); - return PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Height Field Sweep test called with height fields unregistered "); -} - -static bool sweepConvex_HeightfieldUnregistered(GU_CONVEX_SWEEP_FUNC_PARAMS) -{ - PX_UNUSED(threadContext); - PX_UNUSED(geom); - PX_UNUSED(pose); - PX_UNUSED(convexGeom); - PX_UNUSED(convexPose); - PX_UNUSED(unitDir); - PX_UNUSED(distance); - PX_UNUSED(sweepHit); - PX_UNUSED(hitFlags); - PX_UNUSED(inflation); - return PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Height Field Sweep test called with height fields unregistered "); -} - static bool sweepCapsule_CustomGeom(GU_CAPSULE_SWEEP_FUNC_PARAMS) { PX_UNUSED(lss); @@ -653,7 +606,7 @@ Gu::GeomSweepFuncs gGeomSweepFuncs = sweepCapsule_InvalidGeom, sweepCapsule_InvalidGeom, sweepCapsule_MeshGeom, - sweepCapsule_HeightfieldUnregistered, + sweepCapsule_HeightFieldGeom, sweepCapsule_InvalidGeom, sweepCapsule_CustomGeom }, @@ -666,7 +619,7 @@ Gu::GeomSweepFuncs gGeomSweepFuncs = sweepCapsule_InvalidGeom, sweepCapsule_InvalidGeom, sweepCapsule_MeshGeom , - sweepCapsule_HeightfieldUnregistered, + sweepCapsule_HeightFieldGeom, sweepCapsule_InvalidGeom, sweepCapsule_CustomGeom }, @@ -679,7 +632,7 @@ Gu::GeomSweepFuncs gGeomSweepFuncs = sweepBox_InvalidGeom, sweepBox_InvalidGeom, sweepBox_MeshGeom, - sweepBox_HeightfieldUnregistered, + sweepBox_HeightFieldGeom, sweepBox_InvalidGeom, sweepBox_CustomGeom }, @@ -692,7 +645,7 @@ Gu::GeomSweepFuncs gGeomSweepFuncs = sweepBox_InvalidGeom, sweepBox_InvalidGeom, sweepBox_MeshGeom, - sweepBox_HeightfieldUnregistered, + sweepBox_HeightFieldGeom_Precise, sweepBox_InvalidGeom, sweepBox_CustomGeom }, @@ -705,7 +658,7 @@ Gu::GeomSweepFuncs gGeomSweepFuncs = sweepConvex_InvalidGeom, // 5 sweepConvex_InvalidGeom, // 6 sweepConvex_MeshGeom, // 7 - sweepConvex_HeightfieldUnregistered, // 8 + sweepConvex_HeightFieldGeom,// 8 sweepConvex_InvalidGeom, // 9 sweepConvex_CustomGeom // 10 } @@ -716,11 +669,3 @@ PX_PHYSX_COMMON_API const GeomSweepFuncs& Gu::getSweepFuncTable() return gGeomSweepFuncs; } -void registerHeightFields_Sweeps() -{ - gGeomSweepFuncs.capsuleMap[PxGeometryType::eHEIGHTFIELD] = sweepCapsule_HeightFieldGeom; - gGeomSweepFuncs.preciseCapsuleMap[PxGeometryType::eHEIGHTFIELD] = sweepCapsule_HeightFieldGeom; - gGeomSweepFuncs.boxMap[PxGeometryType::eHEIGHTFIELD] = sweepBox_HeightFieldGeom; - gGeomSweepFuncs.preciseBoxMap[PxGeometryType::eHEIGHTFIELD] = sweepBox_HeightFieldGeom_Precise; - gGeomSweepFuncs.convexMap[PxGeometryType::eHEIGHTFIELD] = sweepConvex_HeightFieldGeom; -} diff --git a/physx/source/geomutils/src/ccd/GuCCDSweepConvexMesh.h b/physx/source/geomutils/src/ccd/GuCCDSweepConvexMesh.h index bdc2dd5e5..87f37b948 100644 --- a/physx/source/geomutils/src/ccd/GuCCDSweepConvexMesh.h +++ b/physx/source/geomutils/src/ccd/GuCCDSweepConvexMesh.h @@ -36,10 +36,10 @@ #define GU_TRIANGLE_SWEEP_METHOD_ARGS \ const PxGeometry& shape0, \ const PxGeometry& shape1, \ - const PxTransform& transform0, \ - const PxTransform& transform1, \ - const PxTransform& lastTm0, \ - const PxTransform& lastTm1, \ + const PxTransform32& transform0, \ + const PxTransform32& transform1, \ + const PxTransform32& lastTm0, \ + const PxTransform32& lastTm1, \ PxReal restDistance, \ PxVec3& worldNormal, \ PxVec3& worldPoint, \ @@ -50,10 +50,10 @@ #define GU_SWEEP_METHOD_ARGS \ const Gu::CCDShape& shape0, \ const Gu::CCDShape& shape1, \ - const PxTransform& transform0, \ - const PxTransform& transform1, \ - const PxTransform& lastTm0, \ - const PxTransform& lastTm1, \ + const PxTransform32& transform0, \ + const PxTransform32& transform1, \ + const PxTransform32& lastTm0, \ + const PxTransform32& lastTm1, \ PxReal restDistance, \ PxVec3& worldNormal, \ PxVec3& worldPoint, \ @@ -70,10 +70,10 @@ #define GU_SWEEP_METHOD_ARGS_UNUSED \ const Gu::CCDShape& /*shape0*/, \ const Gu::CCDShape& /*shape1*/, \ - const PxTransform& /*transform0*/, \ - const PxTransform& /*transform1*/, \ - const PxTransform& /*lastTm0*/, \ - const PxTransform& /*lastTm1*/, \ + const PxTransform32& /*transform0*/,\ + const PxTransform32& /*transform1*/,\ + const PxTransform32& /*lastTm0*/, \ + const PxTransform32& /*lastTm1*/, \ PxReal /*restDistance*/, \ PxVec3& /*worldNormal*/, \ PxVec3& /*worldPoint*/, \ diff --git a/physx/source/geomutils/src/ccd/GuCCDSweepPrimitives.cpp b/physx/source/geomutils/src/ccd/GuCCDSweepPrimitives.cpp index 6534cc76a..ee2f473d4 100644 --- a/physx/source/geomutils/src/ccd/GuCCDSweepPrimitives.cpp +++ b/physx/source/geomutils/src/ccd/GuCCDSweepPrimitives.cpp @@ -65,7 +65,7 @@ static bool virtualGjkRaycastPenetration(const GjkConvex& a, const GjkConvex& b, #endif template -static PX_FORCE_INLINE PxReal CCDSweep( ConvexA& a, ConvexB& b, const PxTransform& transform0, const PxTransform& transform1, const PxTransform& lastTm0, const PxTransform& lastTm1, +static PX_FORCE_INLINE PxReal CCDSweep( ConvexA& a, ConvexB& b, const PxTransform32& transform0, const PxTransform32& transform1, const PxTransform32& lastTm0, const PxTransform32& lastTm1, const aos::FloatV& toiEstimate, PxVec3& worldPoint, PxVec3& worldNormal, PxReal inflation = 0.0f) { PX_UNUSED(toiEstimate); //KS - TODO - can we use this again? @@ -81,9 +81,9 @@ static PX_FORCE_INLINE PxReal CCDSweep( ConvexA& a, ConvexB& b, const PxTransfor const PxTransformV tr1(p1, q1); const PxMatTransformV aToB(tr1.transformInv(tr0)); - - const Vec3V trans0p = V3LoadU(transform0.p); - const Vec3V trans1p = V3LoadU(transform1.p); + + const Vec3V trans0p = V3LoadA(transform0.p); + const Vec3V trans1p = V3LoadA(transform1.p); const Vec3V trA = V3Sub(trans0p, p0); const Vec3V trB = V3Sub(trans1p, p1); const Vec3V relTr = tr1.rotateInv(V3Sub(trB, trA)); diff --git a/physx/source/geomutils/src/common/GuBarycentricCoordinates.cpp b/physx/source/geomutils/src/common/GuBarycentricCoordinates.cpp index 696f3bd25..a053970e5 100644 --- a/physx/source/geomutils/src/common/GuBarycentricCoordinates.cpp +++ b/physx/source/geomutils/src/common/GuBarycentricCoordinates.cpp @@ -26,7 +26,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "GuBarycentricCoordinates.h" using namespace physx; @@ -65,15 +64,12 @@ void Gu::barycentricCoordinates(const aos::Vec3VArg p, const aos::Vec3VArg a, co const FloatV zero = FZero(); const FloatV denom = FSel(FIsEq(totalArea, zero), zero, FRecip(totalArea)); v = FMul(vb, denom); - w = FMul(vc, denom); - + w = FMul(vc, denom); } -/* - v0 = b - a; - v1 = c - a; - v2 = p - a; -*/ +// v0 = b - a; +// v1 = c - a; +// v2 = p - a; void Gu::barycentricCoordinates(const Vec3VArg v0, const Vec3VArg v1, const Vec3VArg v2, FloatV& v, FloatV& w) { const FloatV d00 = V3Dot(v0, v0); diff --git a/physx/source/geomutils/src/common/GuMeshAnalysis.cpp b/physx/source/geomutils/src/common/GuMeshAnalysis.cpp index 37beeb281..796b31cbd 100644 --- a/physx/source/geomutils/src/common/GuMeshAnalysis.cpp +++ b/physx/source/geomutils/src/common/GuMeshAnalysis.cpp @@ -99,10 +99,28 @@ PxI32 indexOf(const Triangle& tri, PxI32 node) if (tri[0] == node) return 0; if (tri[1] == node) return 1; if (tri[2] == node) return 2; - return -1; + return 0xFFFFFFFF; } -bool MeshAnalyzer::checkConsistentTriangleOrientation(const Triangle* tris, PxU32 numTriangles, PxArray& flip, PxHashMap& edges) +bool MeshAnalyzer::checkConsistentTriangleOrientation(const Triangle* tris, PxU32 numTriangles) +{ + PxArray flip; + PxHashMap edges; + PxArray> connectedTriangleGroups; + if (!buildConsistentTriangleOrientationMap(tris, numTriangles, flip, edges, connectedTriangleGroups)) + return false; + + for (PxU32 i = 0; i < flip.size(); ++i) + { + if (flip[i]) + return false; + } + + return true; +} + +bool MeshAnalyzer::buildConsistentTriangleOrientationMap(const Triangle* tris, PxU32 numTriangles, PxArray& flip, + PxHashMap& edges, PxArray>& connectedTriangleGroups) { PxArray adj; if (!buildTriangleAdjacency(tris, numTriangles, adj, edges)) @@ -114,8 +132,6 @@ bool MeshAnalyzer::checkConsistentTriangleOrientation(const Triangle* tris, PxU3 flip.clear(); flip.resize(l, false); - PxArray> connectedTriangleGroups; - PxU32 seedIndex = 0; PxArray stack; @@ -132,7 +148,7 @@ bool MeshAnalyzer::checkConsistentTriangleOrientation(const Triangle* tris, PxU3 done[seedIndex] = true; flip[seedIndex] = false; stack.pushBack(seedIndex); - PxArray currentGroup; + PxArray currentGroup; currentGroup.pushBack(seedIndex); connectedTriangleGroups.pushBack(currentGroup); } @@ -166,8 +182,8 @@ bool MeshAnalyzer::makeTriOrientationConsistent(Triangle* tris, PxU32 numTriangl { PxHashMap edges; PxArray flipTriangle; - - if (!checkConsistentTriangleOrientation(tris, numTriangles, flipTriangle, edges)) + PxArray> connectedTriangleGroups; + if (!buildConsistentTriangleOrientationMap(tris, numTriangles, flipTriangle, edges, connectedTriangleGroups)) return false; for (PxU32 i = 0; i < flipTriangle.size(); ++i) @@ -179,17 +195,27 @@ bool MeshAnalyzer::makeTriOrientationConsistent(Triangle* tris, PxU32 numTriangl return true; } -bool MeshAnalyzer::checkMeshWatertightness(const Triangle* tris, PxU32 numTriangles) +bool MeshAnalyzer::checkMeshWatertightness(const Triangle* tris, PxU32 numTriangles, bool treatInconsistentWindingAsNonWatertight) { PxArray flip; PxHashMap edges; - if (!MeshAnalyzer::checkConsistentTriangleOrientation(tris, numTriangles, flip, edges)) + PxArray> connectedTriangleGroups; + if (!MeshAnalyzer::buildConsistentTriangleOrientationMap(tris, numTriangles, flip, edges, connectedTriangleGroups)) return false; - for (PxHashMap::Iterator iter = edges.getIterator(); !iter.done(); ++iter) - if (iter->second >= 0) + if (treatInconsistentWindingAsNonWatertight) + { + for (PxU32 i = 0; i < flip.size(); ++i) { - return false; + if (flip[i]) + return false; } + } + + for (PxHashMap::Iterator iter = edges.getIterator(); !iter.done(); ++iter) + { + if (iter->second >= 0) + return false; + } return true; } diff --git a/physx/source/geomutils/src/common/GuMeshAnalysis.h b/physx/source/geomutils/src/common/GuMeshAnalysis.h index 6842e5570..1ef97d25e 100644 --- a/physx/source/geomutils/src/common/GuMeshAnalysis.h +++ b/physx/source/geomutils/src/common/GuMeshAnalysis.h @@ -59,7 +59,7 @@ namespace Gu }; template - static void splitRanges(PxArray& mergeRanges, const PxArray& indexer, const PxArray& points, PxI32 dimIndex, S tol) + static void splitRanges(PxArray& mergeRanges, const PxArray& indexer, const T* points, PxI32 dimIndex, S tol) { PxArray newMergeRanges; @@ -106,25 +106,25 @@ namespace Gu public: template - static void mapDuplicatePoints(const PxArray& points, PxArray& result, S duplicateDistanceManhattanMetric = static_cast(1e-6)) + static void mapDuplicatePoints(const T* points, const PxU32 nbPoints, PxArray& result, S duplicateDistanceManhattanMetric = static_cast(1e-6)) { - result.reserve(points.size()); - result.forceSize_Unsafe(points.size()); + result.reserve(nbPoints); + result.forceSize_Unsafe(nbPoints); PxArray indexer; - indexer.reserve(points.size()); - indexer.forceSize_Unsafe(points.size()); - for (PxU32 i = 0; i < points.size(); ++i) + indexer.reserve(nbPoints); + indexer.forceSize_Unsafe(nbPoints); + for (PxU32 i = 0; i < nbPoints; ++i) { indexer[i] = i; result[i] = i; } - Comparer comparer(points.begin(), 0); + Comparer comparer(points, 0); PxSort(indexer.begin(), indexer.size(), comparer); PxArray mergeRanges; - mergeRanges.pushBack(Range(0, points.size())); + mergeRanges.pushBack(Range(0, nbPoints)); splitRanges(mergeRanges, indexer, points, 0, duplicateDistanceManhattanMetric); comparer.dimension = 1; @@ -154,9 +154,11 @@ namespace Gu } PX_PHYSX_COMMON_API static bool buildTriangleAdjacency(const Triangle* tris, PxU32 numTriangles, PxArray& result, PxHashMap& edges); - PX_PHYSX_COMMON_API static bool checkConsistentTriangleOrientation(const Triangle* tris, PxU32 numTriangles, PxArray& flip, PxHashMap& edges); + PX_PHYSX_COMMON_API static bool checkConsistentTriangleOrientation(const Triangle* tris, PxU32 numTriangles); + PX_PHYSX_COMMON_API static bool buildConsistentTriangleOrientationMap(const Triangle* tris, PxU32 numTriangles, PxArray& flipMap, + PxHashMap& edges, PxArray>& connectedTriangleGroups); PX_PHYSX_COMMON_API static bool makeTriOrientationConsistent(Triangle* tris, PxU32 numTriangles, bool invertOrientation = false); - PX_PHYSX_COMMON_API static bool checkMeshWatertightness(const Triangle* tris, PxU32 numTriangles); + PX_PHYSX_COMMON_API static bool checkMeshWatertightness(const Triangle* tris, PxU32 numTriangles, bool treatInconsistentWindingAsNonWatertight = true); }; } } diff --git a/physx/source/geomutils/src/contact/GuContactCapsuleConvex.cpp b/physx/source/geomutils/src/contact/GuContactCapsuleConvex.cpp index 8760e619c..4b48df7d4 100644 --- a/physx/source/geomutils/src/contact/GuContactCapsuleConvex.cpp +++ b/physx/source/geomutils/src/contact/GuContactCapsuleConvex.cpp @@ -289,7 +289,7 @@ static void GuGenerateVFContacts2(PxContactBuffer& contactBuffer, { const PxVec3& rayOrigin = points[i]; - const PxVec3 vrayOrig = world2vertexSkew.transform( rayOrigin ); + const PxVec3 vrayOrig = world2vertexSkew.transform(rayOrigin); PxF32 t; if(raycast_convexMesh2(polyData, vrayOrig, vrayDir, maxDist, t)) { diff --git a/physx/source/geomutils/src/contact/GuContactMethodImpl.h b/physx/source/geomutils/src/contact/GuContactMethodImpl.h index 521da5e82..7d8097a3e 100644 --- a/physx/source/geomutils/src/contact/GuContactMethodImpl.h +++ b/physx/source/geomutils/src/contact/GuContactMethodImpl.h @@ -52,9 +52,9 @@ namespace Gu 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 + PxReal mContactDistance; + const PxReal mMeshContactMargin; // PT: Margin used to generate mesh contacts. Temp & unclear, should be removed once GJK is default path. + const PxReal mToleranceLength; // PT: copy of PxTolerancesScale::length }; enum ManifoldFlags @@ -120,8 +120,8 @@ template PX_CUDA_CALLABLE PX_FORCE_INLINE const Geom& checkedCast(co #define GU_CONTACT_METHOD_ARGS \ const PxGeometry& shape0, \ const PxGeometry& shape1, \ - const PxTransform& transform0, \ - const PxTransform& transform1, \ + const PxTransform32& transform0, \ + const PxTransform32& transform1, \ const Gu::NarrowPhaseParams& params, \ Gu::Cache& cache, \ PxContactBuffer& contactBuffer, \ @@ -130,8 +130,8 @@ template PX_CUDA_CALLABLE PX_FORCE_INLINE const Geom& checkedCast(co #define GU_CONTACT_METHOD_ARGS_UNUSED \ const PxGeometry&, \ const PxGeometry&, \ - const PxTransform&, \ - const PxTransform&, \ + const PxTransform32&, \ + const PxTransform32&, \ const Gu::NarrowPhaseParams&, \ Gu::Cache&, \ PxContactBuffer&, \ diff --git a/physx/source/geomutils/src/contact/GuContactSphereBox.cpp b/physx/source/geomutils/src/contact/GuContactSphereBox.cpp index 1918c16c6..2cd39fbc2 100644 --- a/physx/source/geomutils/src/contact/GuContactSphereBox.cpp +++ b/physx/source/geomutils/src/contact/GuContactSphereBox.cpp @@ -36,7 +36,7 @@ static PX_FORCE_INLINE bool ContactSphereBox(const PxVec3& sphereOrigin, PxReal sphereRadius, const PxVec3& boxExtents, // const PxcCachedTransforms& boxCacheTransform, - const PxTransform& boxTransform, + const PxTransform32& boxTransform, PxVec3& point, PxVec3& normal, PxReal& separation, diff --git a/physx/source/geomutils/src/convex/GuBigConvexData.h b/physx/source/geomutils/src/convex/GuBigConvexData.h index 14017e5e8..ac2e9f41a 100644 --- a/physx/source/geomutils/src/convex/GuBigConvexData.h +++ b/physx/source/geomutils/src/convex/GuBigConvexData.h @@ -45,13 +45,6 @@ namespace Gu struct Valency { -//= 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. -//================================================================================================== - PxU16 mCount; PxU16 mOffset; }; @@ -59,13 +52,6 @@ PX_COMPILE_TIME_ASSERT(sizeof(Gu::Valency) == 4); struct BigConvexRawData { -//= 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. -//================================================================================================== - // Support vertex map PxU16 mSubdiv; // "Gaussmap" subdivision PxU16 mNbSamples; // Total #samples in gaussmap PT: this is not even needed at runtime! diff --git a/physx/source/geomutils/src/convex/GuBigConvexData2.h b/physx/source/geomutils/src/convex/GuBigConvexData2.h index 98c927b84..d7a26e8b2 100644 --- a/physx/source/geomutils/src/convex/GuBigConvexData2.h +++ b/physx/source/geomutils/src/convex/GuBigConvexData2.h @@ -40,12 +40,6 @@ namespace physx class PX_PHYSX_COMMON_API BigConvexData : 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. - //================================================================================================== public: // PX_SERIALIZATION BigConvexData(const PxEMPTY) {} diff --git a/physx/source/geomutils/src/convex/GuConvexMesh.h b/physx/source/geomutils/src/convex/GuConvexMesh.h index a3504b6bc..a80b694f9 100644 --- a/physx/source/geomutils/src/convex/GuConvexMesh.h +++ b/physx/source/geomutils/src/convex/GuConvexMesh.h @@ -92,12 +92,6 @@ namespace Gu class ConvexMesh : public PxConvexMesh, 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. - //================================================================================================== public: // PX_SERIALIZATION ConvexMesh(PxBaseFlags baseFlags) : PxConvexMesh(baseFlags), mHullData(PxEmpty), mNb(PxEmpty) diff --git a/physx/source/geomutils/src/convex/GuConvexMeshData.h b/physx/source/geomutils/src/convex/GuConvexMeshData.h index 388a03b6c..5bdaefe02 100644 --- a/physx/source/geomutils/src/convex/GuConvexMeshData.h +++ b/physx/source/geomutils/src/convex/GuConvexMeshData.h @@ -47,13 +47,6 @@ namespace Gu struct HullPolygonData { - //= 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. - //================================================================================================== - // PT: this structure won't be allocated with PX_NEW because polygons aren't allocated alone (with a dedicated alloc). // Instead they are part of a unique allocation/buffer containing all data for the ConvexHullData class (polygons, followed by // hull vertices, edge data, etc). As a result, ctors for embedded classes like PxPlane won't be called. @@ -85,12 +78,6 @@ namespace Gu // TEST_INTERNAL_OBJECTS struct InternalObjectsData { - //= 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. - //================================================================================================== PxReal mRadius; PxReal mExtents[3]; @@ -107,13 +94,6 @@ namespace Gu struct ConvexHullData { - //= 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. - //================================================================================================== - // PT: WARNING: bounds must be followed by at least 32bits of data for safe SIMD loading CenterExtents mAABB; //!< bounds TODO: compute this on the fly from first 6 vertices in the vertex array. We'll of course need to sort the most extreme ones to the front. PxVec3 mCenterOfMass; //in local space of mesh! diff --git a/physx/source/geomutils/src/cooking/GuCookingBVH.cpp b/physx/source/geomutils/src/cooking/GuCookingBVH.cpp index 315e57f94..8b1f5b2f1 100644 --- a/physx/source/geomutils/src/cooking/GuCookingBVH.cpp +++ b/physx/source/geomutils/src/cooking/GuCookingBVH.cpp @@ -38,14 +38,7 @@ using namespace Gu; static bool buildBVH(const PxBVHDesc& desc, BVHData& data, const char* errorMessage) { if(!desc.isValid()) - { -#if PX_CHECKED - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, errorMessage); -#else - PX_UNUSED(errorMessage); -#endif - return false; - } + return PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, errorMessage); BVHBuildStrategy bs; if(desc.buildStrategy==PxBVHBuildStrategy::eFAST) diff --git a/physx/source/geomutils/src/cooking/GuCookingConvexMesh.cpp b/physx/source/geomutils/src/cooking/GuCookingConvexMesh.cpp index 1ebae13c9..3fda202a0 100644 --- a/physx/source/geomutils/src/cooking/GuCookingConvexMesh.cpp +++ b/physx/source/geomutils/src/cooking/GuCookingConvexMesh.cpp @@ -85,7 +85,7 @@ static bool cookConvexMeshInternal(const PxCookingParams& params, const PxConvex } else { - if(res == PxConvexMeshCookingResult::eZERO_AREA_TEST_FAILED) + if((res == PxConvexMeshCookingResult::eZERO_AREA_TEST_FAILED) && condition) { *condition = PxConvexMeshCookingResult::eZERO_AREA_TEST_FAILED; } @@ -100,7 +100,7 @@ static bool cookConvexMeshInternal(const PxCookingParams& params, const PxConvex if(desc.polygons.count >= 256) return outputError(__LINE__, "Cooking::cookConvexMesh: user-provided hull must have less than 256 faces!"); - if (desc.flags & PxConvexFlag::eGPU_COMPATIBLE) + if ((desc.flags & PxConvexFlag::eGPU_COMPATIBLE) || params.buildGPUData) { if (desc.points.count > 64) return outputError(__LINE__, "Cooking::cookConvexMesh: GPU-compatible user-provided hull must have less than 65 vertices!"); @@ -108,8 +108,7 @@ static bool cookConvexMeshInternal(const PxCookingParams& params, const PxConvex if (desc.polygons.count > 64) return outputError(__LINE__, "Cooking::cookConvexMesh: GPU-compatible user-provided hull must have less than 65 faces!"); } - - + if(!meshBuilder.build(desc, params.gaussMapLimit, false, hullLib)) return false; @@ -127,7 +126,7 @@ static ConvexHullLib* createHullLib(PxConvexMeshDesc& desc, const PxCookingParam const PxU16 gpuMaxFacesLimit = 64; // GRB supports 64 verts max - if(desc.flags & PxConvexFlag::eGPU_COMPATIBLE) + if((desc.flags & PxConvexFlag::eGPU_COMPATIBLE) || params.buildGPUData) { desc.vertexLimit = PxMin(desc.vertexLimit, gpuMaxVertsLimit); desc.polygonLimit = PxMin(desc.polygonLimit, gpuMaxFacesLimit); diff --git a/physx/source/geomutils/src/cooking/GuCookingHF.cpp b/physx/source/geomutils/src/cooking/GuCookingHF.cpp index 6a2c94e87..dff7dc3f1 100644 --- a/physx/source/geomutils/src/cooking/GuCookingHF.cpp +++ b/physx/source/geomutils/src/cooking/GuCookingHF.cpp @@ -37,16 +37,11 @@ using namespace Gu; bool immediateCooking::cookHeightField(const PxHeightFieldDesc& desc, PxOutputStream& stream) { + if(!desc.isValid()) + return PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "Cooking::cookHeightField: user-provided heightfield descriptor is invalid!"); + PX_FPU_GUARD; - if(!desc.isValid()) - { -#if PX_CHECKED - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "Cooking::cookHeightField: user-provided heightfield descriptor is invalid!"); -#endif - return false; - } - HeightField hf(NULL); if(!hf.loadFromDesc(desc)) @@ -68,16 +63,14 @@ bool immediateCooking::cookHeightField(const PxHeightFieldDesc& desc, PxOutputSt PxHeightField* immediateCooking::createHeightField(const PxHeightFieldDesc& desc, PxInsertionCallback& insertionCallback) { - PX_FPU_GUARD; - if(!desc.isValid()) { -#if PX_CHECKED PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "Cooking::createHeightField: user-provided heightfield descriptor is invalid!"); -#endif return NULL; } + PX_FPU_GUARD; + HeightField* hf; PX_NEW_SERIALIZED(hf, HeightField)(NULL); diff --git a/physx/source/geomutils/src/cooking/GuCookingQuickHullConvexHullLib.cpp b/physx/source/geomutils/src/cooking/GuCookingQuickHullConvexHullLib.cpp index 1b1630fc0..6652cecd0 100644 --- a/physx/source/geomutils/src/cooking/GuCookingQuickHullConvexHullLib.cpp +++ b/physx/source/geomutils/src/cooking/GuCookingQuickHullConvexHullLib.cpp @@ -301,7 +301,7 @@ namespace local QuickHullHalfEdge* testEdge = edge; QuickHullHalfEdge* startEdge = NULL; - float maxDist = 0.0f; + float maxDist = -1.0f; for (PxU32 i = 0; i < 3; i++) { const float d = (testEdge->tail.point - testEdge->next->tail.point).magnitudeSquared(); @@ -1091,7 +1091,7 @@ namespace local ////////////////////////////////////////////////////////////////////////// // merge polygons with similar normals void QuickHull::postMergeHull() - { + { // merge faces with similar normals for (PxU32 i = 0; i < mHullFaces.size(); i++) { @@ -1223,7 +1223,7 @@ namespace local // adds vertex to the hull // sets addFailed to true if we failed to add a point because the merging failed // this can happen as the face plane equation changes and some faces might become concave - // returns false if the new faces count would hit the hull face hard limit (255) + // returns false if the new faces count would hit the hull face hard limit (255 / 64 for GPU-compatible) bool QuickHull::addPointToHull(const QuickHullVertex* eyeVtx, QuickHullFace& eyeFace, bool& addFailed) { addFailed = false; @@ -1881,6 +1881,10 @@ PxConvexMeshCookingResult::Enum QuickHullConvexHullLib::createConvexHull() else res = expandHullOBB(); } + else + { + mQuickHull->postMergeHull(); + } res = PxConvexMeshCookingResult::ePOLYGONS_LIMIT_REACHED; break; case local::QuickHullResult::eVERTEX_LIMIT_REACHED: @@ -1899,7 +1903,7 @@ PxConvexMeshCookingResult::Enum QuickHullConvexHullLib::createConvexHull() // check if we need to build GRB compatible mesh // if hull was cropped we already have a compatible mesh, if not check // the max verts per face - if((mConvexMeshDesc.flags & PxConvexFlag::eGPU_COMPATIBLE) && !mCropedConvexHull && + if(((mConvexMeshDesc.flags & PxConvexFlag::eGPU_COMPATIBLE) || mCookingParams.buildGPUData) && !mCropedConvexHull && (res == PxConvexMeshCookingResult::eSUCCESS || res == PxConvexMeshCookingResult::ePOLYGONS_LIMIT_REACHED)) { PX_ASSERT(mQuickHull); @@ -2003,7 +2007,7 @@ bool QuickHullConvexHullLib::cleanupForSimplex(PxVec3* vertices, PxU32 vertexCou // set third vertex to be the vertex farthest from // the line between simplex[0] and simplex[1] - PxVec3 normal; + PxVec3 normal(0.0f); float maxDist = 0; imax = 0; PxVec3 u01 = (simplex[1] - simplex[0]); @@ -2255,7 +2259,7 @@ PxConvexMeshCookingResult::Enum QuickHullConvexHullLib::expandHullOBB() break; } // check for vertex limit per face if necessary, GRB supports max 32 verts per face - if ((mConvexMeshDesc.flags & PxConvexFlag::eGPU_COMPATIBLE) && c->maxNumVertsPerFace() > gpuMaxVertsPerFace) + if (((mConvexMeshDesc.flags & PxConvexFlag::eGPU_COMPATIBLE) || mCookingParams.buildGPUData) && c->maxNumVertsPerFace() > gpuMaxVertsPerFace) { PX_DELETE(c); c = tmp; diff --git a/physx/source/geomutils/src/cooking/GuCookingTetrahedronMesh.cpp b/physx/source/geomutils/src/cooking/GuCookingTetrahedronMesh.cpp index dd1fe2260..36ff21000 100644 --- a/physx/source/geomutils/src/cooking/GuCookingTetrahedronMesh.cpp +++ b/physx/source/geomutils/src/cooking/GuCookingTetrahedronMesh.cpp @@ -168,6 +168,10 @@ struct SortedTriangleIndsHash } }; +#if PX_CHECKED +bool checkInputFloats(PxU32 nb, const float* values, const char* file, PxU32 line, const char* errorMsg); +#endif + bool TetrahedronMeshBuilder::importMesh(const PxTetrahedronMeshDesc& collisionMeshDesc, const PxCookingParams& params, TetrahedronMeshData& collisionMesh, SoftBodyCollisionData& collisionData, bool validateMesh) { @@ -188,18 +192,16 @@ bool TetrahedronMeshBuilder::importMesh(const PxTetrahedronMeshDesc& collisionMe #if PX_CHECKED // PT: check all input vertices are valid - for (PxU32 i = 0; i < collisionMeshDesc.points.count; i++) - { - const PxVec3& p = verts[i]; - if (!PxIsFinite(p.x) || !PxIsFinite(p.y) || !PxIsFinite(p.z)) - return PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "input mesh contains corrupted vertex data"); - } + if(!checkInputFloats(collisionMeshDesc.points.count*3, &verts->x, PX_FL, "input mesh contains corrupted vertex data")) + return false; #endif TetrahedronT* dest = tets; const TetrahedronT* pastLastDest = tets + collisionMesh.mNbTetrahedrons; const PxU8* source = reinterpret_cast(collisionMeshDesc.tetrahedrons.data); + PX_ASSERT(source); + //4 combos of 16 vs 32, feed in collisionMesh.mTetrahedrons if (collisionMeshDesc.flags & PxMeshFlag::e16_BIT_INDICES) { @@ -366,12 +368,19 @@ void computeRestPoseAndPointMass(TetrahedronT* tetIndices, const PxU32 nb for (PxU32 i = 0; i < nbTets; ++i) { TetrahedronT& tetInd = tetIndices[i]; - PxMat33 Q; + PxMat33 Q, QInv; const PxReal volume = computeTetrahedronVolume(verts[tetInd.v[0]], verts[tetInd.v[1]], verts[tetInd.v[2]], verts[tetInd.v[3]], Q); if (volume <= 1.e-9f) { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "computeRestPoseAndPointMass(): tretrahedron is degenerate or inverted"); + //Neo-hookean model can deal with bad tets, so not issueing this error anymore + //PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "computeRestPoseAndPointMass(): tretrahedron is degenerate or inverted"); + if (volume == 0) + QInv = PxMat33(PxZero); + else + QInv = Q.getInverse(); } + else + QInv = Q.getInverse(); // add volume fraction to particles if (invMasses != NULL) @@ -382,7 +391,7 @@ void computeRestPoseAndPointMass(TetrahedronT* tetIndices, const PxU32 nb invMasses[tetInd.v[3]] += volume * 0.25f; } - restPoses[i] = Q.getInverse(); + restPoses[i] = QInv; } } diff --git a/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.cpp b/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.cpp index b6ea9bb52..9a96eb5a9 100644 --- a/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.cpp +++ b/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.cpp @@ -534,7 +534,7 @@ bool TriangleMeshBuilder::loadFromDescInternal(PxTriangleMeshDesc& desc, PxTrian return true; } -void TriangleMeshBuilder::buildInertiaTensor() +void TriangleMeshBuilder::buildInertiaTensor(bool flipNormals) { PxTriangleMeshDesc simpleMesh; @@ -545,6 +545,8 @@ void TriangleMeshBuilder::buildInertiaTensor() simpleMesh.triangles.stride = sizeof(PxU32) * 3; simpleMesh.triangles.data = mMeshData.mTriangles; simpleMesh.flags &= (~PxMeshFlag::e16_BIT_INDICES); + if (flipNormals) + simpleMesh.flags.raise(PxMeshFlag::eFLIPNORMALS); PxIntegrals integrals; computeVolumeIntegrals(simpleMesh, 1, integrals); @@ -559,6 +561,8 @@ void TriangleMeshBuilder::buildInertiaTensorFromSDF() if (MeshAnalyzer::checkMeshWatertightness(reinterpret_cast(mMeshData.mTriangles), mMeshData.mNbTriangles)) { buildInertiaTensor(); + if (mMeshData.mMass < 0.0f) + buildInertiaTensor(true); //The mesh can be watertight but all triangles might be oriented the wrong way round return; } @@ -792,6 +796,18 @@ bool TriangleMeshBuilder::save(PxOutputStream& stream, bool platformMismatch, co #pragma warning(disable:4996) // permitting use of gatherStrided until we have a replacement. #endif +#if PX_CHECKED +bool checkInputFloats(PxU32 nb, const float* values, const char* file, PxU32 line, const char* errorMsg) +{ + while(nb--) + { + if(!PxIsFinite(*values++)) + return PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, file, line, errorMsg); + } + return true; +} +#endif + bool TriangleMeshBuilder::importMesh(const PxTriangleMeshDesc& desc,const PxCookingParams& params,PxTriangleMeshCookingResult::Enum* condition, bool validate) { //convert and clean the input mesh @@ -805,12 +821,8 @@ bool TriangleMeshBuilder::importMesh(const PxTriangleMeshDesc& desc,const PxCook #if PX_CHECKED // PT: check all input vertices are valid - for(PxU32 i=0;i(__LINE__, "input mesh contains corrupted vertex data"); - } + if(!checkInputFloats(desc.points.count*3, &verts->x, PX_FL, "input mesh contains corrupted vertex data")) + return false; #endif //for trigs index stride conversion and eventual reordering is also needed, I don't think flexicopy can do that for us. @@ -933,11 +945,8 @@ bool TriangleMeshBuilder::importMesh(const PxTriangleMeshDesc& desc,const PxCook #if PX_CHECKED // SN: check all input sdf values are valid - for (PxU32 i = 0; i < sdfDesc.sdf.count; ++i) - { - if (!PxIsFinite(sdf[i])) - return outputError(__LINE__, "input sdf contains corrupted data"); - } + if(!checkInputFloats(sdfDesc.sdf.count, sdf, PX_FL, "input sdf contains corrupted data")) + return false; #endif } diff --git a/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.h b/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.h index 21646768c..4c2c3e381 100644 --- a/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.h +++ b/physx/source/geomutils/src/cooking/GuCookingTriangleMesh.h @@ -76,7 +76,7 @@ namespace physx bool loadFromDescInternal(PxTriangleMeshDesc&, PxTriangleMeshCookingResult::Enum* condition, bool validate = false); - void buildInertiaTensor(); + void buildInertiaTensor(bool flipNormals = false); void buildInertiaTensorFromSDF(); TriangleMeshBuilder& operator=(const TriangleMeshBuilder&); diff --git a/physx/source/geomutils/src/distance/GuDistancePointTriangle.cpp b/physx/source/geomutils/src/distance/GuDistancePointTriangle.cpp index 2761d4c78..328ea05ef 100644 --- a/physx/source/geomutils/src/distance/GuDistancePointTriangle.cpp +++ b/physx/source/geomutils/src/distance/GuDistancePointTriangle.cpp @@ -28,7 +28,6 @@ #include "foundation/PxVec3.h" #include "GuDistancePointTriangle.h" -#include "GuDistancePointTriangleSIMD.h" using namespace physx; diff --git a/physx/source/geomutils/src/distance/GuDistancePointTriangle.h b/physx/source/geomutils/src/distance/GuDistancePointTriangle.h deleted file mode 100644 index 8dd312354..000000000 --- a/physx/source/geomutils/src/distance/GuDistancePointTriangle.h +++ /dev/null @@ -1,123 +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-2023 NVIDIA 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_DISTANCE_POINT_TRIANGLE_H -#define GU_DISTANCE_POINT_TRIANGLE_H - -#include "foundation/PxVec3.h" -#include "common/PxPhysXCommonConfig.h" - -namespace physx -{ -namespace Gu -{ - // PT: special version: - // - inlined - // - doesn't compute (s,t) output params - // - expects precomputed edges in input - PX_FORCE_INLINE PX_CUDA_CALLABLE PxVec3 closestPtPointTriangle2(const PxVec3& p, const PxVec3& a, const PxVec3& b, const PxVec3& c, const PxVec3& ab, const PxVec3& ac) - { - // Check if P in vertex region outside A - //const PxVec3 ab = b - a; - //const PxVec3 ac = c - a; - const PxVec3 ap = p - a; - const float d1 = ab.dot(ap); - const float d2 = ac.dot(ap); - if(d1<=0.0f && d2<=0.0f) - return a; // Barycentric coords 1,0,0 - - // Check if P in vertex region outside B - const PxVec3 bp = p - b; - const float d3 = ab.dot(bp); - const float d4 = ac.dot(bp); - if(d3>=0.0f && d4<=d3) - return b; // Barycentric coords 0,1,0 - - // Check if P in edge region of AB, if so return projection of P onto AB - const float vc = d1*d4 - d3*d2; - if(vc<=0.0f && d1>=0.0f && d3<=0.0f) - { - const float v = d1 / (d1 - d3); - return a + v * ab; // barycentric coords (1-v, v, 0) - } - - // Check if P in vertex region outside C - const PxVec3 cp = p - c; - const float d5 = ab.dot(cp); - const float d6 = ac.dot(cp); - if(d6>=0.0f && d5<=d6) - return c; // Barycentric coords 0,0,1 - - // Check if P in edge region of AC, if so return projection of P onto AC - const float vb = d5*d2 - d1*d6; - if(vb<=0.0f && d2>=0.0f && d6<=0.0f) - { - const float w = d2 / (d2 - d6); - return a + w * ac; // barycentric coords (1-w, 0, w) - } - - // Check if P in edge region of BC, if so return projection of P onto BC - const float va = d3*d6 - d5*d4; - if(va<=0.0f && (d4-d3)>=0.0f && (d5-d6)>=0.0f) - { - const float w = (d4-d3) / ((d4 - d3) + (d5-d6)); - return b + w * (c-b); // barycentric coords (0, 1-w, w) - } - - // P inside face region. Compute Q through its barycentric coords (u,v,w) - const float denom = 1.0f / (va + vb + vc); - const float v = vb * denom; - const float w = vc * denom; - return a + ab*v + ac*w; - } - - PX_PHYSX_COMMON_API PxVec3 closestPtPointTriangle(const PxVec3& p, const PxVec3& a, const PxVec3& b, const PxVec3& c, float& s, float& t); - - PX_FORCE_INLINE PxReal distancePointTriangleSquared(const PxVec3& point, - const PxVec3& triangleOrigin, - const PxVec3& triangleEdge0, - const PxVec3& triangleEdge1, - PxReal* param0=NULL, - PxReal* param1=NULL) - { - const PxVec3 pt0 = triangleEdge0 + triangleOrigin; - const PxVec3 pt1 = triangleEdge1 + triangleOrigin; - float s,t; - const PxVec3 cp = closestPtPointTriangle(point, triangleOrigin, pt0, pt1, s, t); - if(param0) - *param0 = s; - if(param1) - *param1 = t; - return (cp - point).magnitudeSquared(); - } - -} // namespace Gu - -} - -#endif diff --git a/physx/source/geomutils/src/distance/GuDistanceSegmentSegment.cpp b/physx/source/geomutils/src/distance/GuDistanceSegmentSegment.cpp index 940cd6e91..bb66e55e2 100644 --- a/physx/source/geomutils/src/distance/GuDistanceSegmentSegment.cpp +++ b/physx/source/geomutils/src/distance/GuDistanceSegmentSegment.cpp @@ -27,7 +27,6 @@ // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #include "GuDistanceSegmentSegment.h" -#include "GuDistanceSegmentSegmentSIMD.h" using namespace physx; using namespace aos; diff --git a/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.cpp b/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.cpp index 7203652bc..db14b7de6 100644 --- a/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.cpp +++ b/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.cpp @@ -28,11 +28,8 @@ #include "foundation/PxIntrinsics.h" #include "GuDistanceSegmentTriangle.h" -#include "GuDistanceSegmentTriangleSIMD.h" #include "GuDistancePointTriangle.h" -#include "GuDistancePointTriangleSIMD.h" #include "GuDistanceSegmentSegment.h" -#include "GuDistanceSegmentSegmentSIMD.h" #include "GuBarycentricCoordinates.h" using namespace physx; @@ -377,14 +374,11 @@ PxReal Gu::distanceSegmentTriangleSquared( const PxVec3& origin, const PxVec3& d return physx::intrinsics::selectMax(0.0f, fSqrDist); } - -/* - closest0 is the closest point on segment pq - closest1 is the closest point on triangle abc -*/ +// closest0 is the closest point on segment pq +// closest1 is the closest point on triangle abc aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos::Vec3VArg q, - const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, - aos::Vec3V& closest0, aos::Vec3V& closest1) + const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, + aos::Vec3V& closest0, aos::Vec3V& closest1) { using namespace aos; const FloatV zero = FZero(); @@ -406,20 +400,18 @@ aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos const FloatV bdenom = FSel(FIsGrtr(tDenom, zero), FRecip(tDenom), zero); - const Vec3V n =V3Normalize(V3Cross(ab, ac)); // normalize vector + const Vec3V n = V3Normalize(V3Cross(ab, ac)); // normalize vector //compute the closest point of p and triangle plane abc const FloatV dist3 = V3Dot(ap, n); const FloatV sqDist3 = FMul(dist3, dist3); - //compute the closest point of q and triangle plane abc const FloatV dist4 = V3Dot(aq, n); const FloatV sqDist4 = FMul(dist4, dist4); const FloatV dMul = FMul(dist3, dist4); const BoolV con = FIsGrtr(zero, dMul); - // intersect with the plane if(BAllEqTTTT(con)) { @@ -440,7 +432,6 @@ aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos return zero; } } - Vec4V t40, t41; const Vec4V sqDist44 = distanceSegmentSegmentSquared4(p,pq,a,ab, b,bc, a,ac, a,ab, t40, t41); @@ -466,7 +457,6 @@ aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos const Vec3V closestP20 = V3ScaleAdd(pq, t20, p); const Vec3V closestP21 = V3ScaleAdd(ac, t21, a); - //Get the closest point of all edges const BoolV con20 = FIsGrtr(sqDist1, sqDist0); const BoolV con21 = FIsGrtr(sqDist2, sqDist0); @@ -476,9 +466,8 @@ aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos const BoolV con3 = BAnd(con30, con31); const FloatV sqDistPE = FSel(con2, sqDist0, FSel(con3, sqDist1, sqDist2)); //const FloatV tValue = FSel(con2, t00, FSel(con3, t10, t20)); - const Vec3V closestPE0 = V3Sel(con2, closestP00, V3Sel(con3, closestP10, closestP20)); // closestP on segment - const Vec3V closestPE1 = V3Sel(con2, closestP01, V3Sel(con3, closestP11, closestP21)); // closestP on triangle - + const Vec3V closestPE0 = V3Sel(con2, closestP00, V3Sel(con3, closestP10, closestP20)); // closestP on segment + const Vec3V closestPE1 = V3Sel(con2, closestP01, V3Sel(con3, closestP11, closestP21)); // closestP on triangle const Vec3V closestP31 = V3NegScaleSub(n, dist3, p);//V3Sub(p, V3Scale(n, dist3)); const Vec3V closestP30 = p; @@ -493,8 +482,6 @@ aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos //check closestP3 is inside the triangle const BoolV con0 = isValidTriangleBarycentricCoord(v0, w0); - - const Vec3V closestP41 = V3NegScaleSub(n, dist4, q);// V3Sub(q, V3Scale(n, dist4)); const Vec3V closestP40 = q; @@ -507,23 +494,17 @@ aos::FloatV Gu::distanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos const BoolV con1 = isValidTriangleBarycentricCoord(v1, w1); - /* - p is interior point but not q - */ + // p is interior point but not q const BoolV d0 = FIsGrtr(sqDistPE, sqDist3); const Vec3V c00 = V3Sel(d0, closestP30, closestPE0); const Vec3V c01 = V3Sel(d0, closestP31, closestPE1); - /* - q is interior point but not p - */ + // q is interior point but not p const BoolV d1 = FIsGrtr(sqDistPE, sqDist4); const Vec3V c10 = V3Sel(d1, closestP40, closestPE0); const Vec3V c11 = V3Sel(d1, closestP41, closestPE1); - /* - p and q are interior point - */ + // p and q are interior point const BoolV d2 = FIsGrtr(sqDist4, sqDist3); const Vec3V c20 = V3Sel(d2, closestP30, closestP40); const Vec3V c21 = V3Sel(d2, closestP31, closestP41); diff --git a/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.h b/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.h index ff2e57eee..794fd3594 100644 --- a/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.h +++ b/physx/source/geomutils/src/distance/GuDistanceSegmentTriangle.h @@ -31,12 +31,12 @@ #include "common/PxPhysXCommonConfig.h" #include "GuSegment.h" +#include "foundation/PxVecMath.h" namespace physx { namespace Gu { - PX_PHYSX_COMMON_API PxReal distanceSegmentTriangleSquared( const PxVec3& segmentOrigin, const PxVec3& segmentExtent, const PxVec3& triangleOrigin, const PxVec3& triangleEdge0, const PxVec3& triangleEdge1, @@ -44,19 +44,21 @@ namespace Gu PX_INLINE PxReal distanceSegmentTriangleSquared( const Gu::Segment& segment, - const PxVec3& triangleOrigin, - const PxVec3& triangleEdge0, - const PxVec3& triangleEdge1, - PxReal* t=NULL, - PxReal* u=NULL, - PxReal* v=NULL) + const PxVec3& triangleOrigin, const PxVec3& triangleEdge0, const PxVec3& triangleEdge1, + PxReal* t=NULL, PxReal* u=NULL, PxReal* v=NULL) { return distanceSegmentTriangleSquared( segment.p0, segment.computeDirection(), triangleOrigin, triangleEdge0, triangleEdge1, t, u, v); } -} // namespace Gu + // closest0 is the closest point on segment pq + // closest1 is the closest point on triangle abc + PX_PHYSX_COMMON_API aos::FloatV distanceSegmentTriangleSquared( + const aos::Vec3VArg p, const aos::Vec3VArg q, + const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, + aos::Vec3V& closest0, aos::Vec3V& closest1); +} // namespace Gu } #endif diff --git a/physx/source/geomutils/src/gjk/GuVecTetrahedron.h b/physx/source/geomutils/src/gjk/GuVecTetrahedron.h index f3a867708..dd734ffea 100644 --- a/physx/source/geomutils/src/gjk/GuVecTetrahedron.h +++ b/physx/source/geomutils/src/gjk/GuVecTetrahedron.h @@ -34,7 +34,7 @@ #include "GuVecConvex.h" #include "GuConvexSupportTable.h" -#include "GuDistancePointTriangleSIMD.h" +#include "GuDistancePointTriangle.h" namespace physx { diff --git a/physx/source/geomutils/src/gjk/GuVecTriangle.h b/physx/source/geomutils/src/gjk/GuVecTriangle.h index 9e44fdb14..0be9b7361 100644 --- a/physx/source/geomutils/src/gjk/GuVecTriangle.h +++ b/physx/source/geomutils/src/gjk/GuVecTriangle.h @@ -34,7 +34,7 @@ #include "GuVecConvex.h" #include "GuConvexSupportTable.h" -#include "GuDistancePointTriangleSIMD.h" +#include "GuDistancePointTriangle.h" namespace physx { diff --git a/physx/source/geomutils/src/hf/GuHeightField.h b/physx/source/geomutils/src/hf/GuHeightField.h index 67cbf2124..9352ad6e7 100644 --- a/physx/source/geomutils/src/hf/GuHeightField.h +++ b/physx/source/geomutils/src/hf/GuHeightField.h @@ -52,12 +52,6 @@ namespace Gu class MeshFactory; class HeightField : public PxHeightField, 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. -//================================================================================================== public: // PX_SERIALIZATION HeightField(PxBaseFlags baseFlags) : PxHeightField(baseFlags), mData(PxEmpty), mModifyCount(0) {} diff --git a/physx/source/geomutils/src/intersection/GuIntersectionRayBox.cpp b/physx/source/geomutils/src/intersection/GuIntersectionRayBox.cpp index 32e236dbb..941425fcd 100644 --- a/physx/source/geomutils/src/intersection/GuIntersectionRayBox.cpp +++ b/physx/source/geomutils/src/intersection/GuIntersectionRayBox.cpp @@ -30,7 +30,6 @@ #include "foundation/PxMathIntrinsics.h" #include "foundation/PxFPU.h" #include "GuIntersectionRayBox.h" -#include "GuIntersectionRayBoxSIMD.h" using namespace physx; diff --git a/physx/source/geomutils/src/intersection/GuIntersectionRayBox.h b/physx/source/geomutils/src/intersection/GuIntersectionRayBox.h index 29f147612..c2cd0593c 100644 --- a/physx/source/geomutils/src/intersection/GuIntersectionRayBox.h +++ b/physx/source/geomutils/src/intersection/GuIntersectionRayBox.h @@ -31,12 +31,12 @@ #include "foundation/PxMathIntrinsics.h" #include "common/PxPhysXCommonConfig.h" +#include "foundation/PxVecMath.h" namespace physx { namespace Gu { - bool rayAABBIntersect(const PxVec3& minimum, const PxVec3& maximum, const PxVec3& origin, const PxVec3& _dir, PxVec3& coord); PxU32 rayAABBIntersect2(const PxVec3& minimum, const PxVec3& maximum, const PxVec3& origin, const PxVec3& _dir, PxVec3& coord, PxReal & t); @@ -82,8 +82,11 @@ namespace Gu bool PX_PHYSX_COMMON_API intersectRayAABB2( const PxVec3& minimum, const PxVec3& maximum, const PxVec3& ro, const PxVec3& rd, float maxDist, float& tnear, float& tfar); -} // namespace Gu + bool PX_PHYSX_COMMON_API intersectRayAABB2( const aos::Vec3VArg minimum, const aos::Vec3VArg maximum, + const aos::Vec3VArg ro, const aos::Vec3VArg rd, const aos::FloatVArg maxDist, + aos::FloatV& tnear, aos::FloatV& tfar); +} // namespace Gu } #endif diff --git a/physx/source/geomutils/src/mesh/GuBV4_CapsuleSweep_Internal.h b/physx/source/geomutils/src/mesh/GuBV4_CapsuleSweep_Internal.h index a30851d4d..c59941f42 100644 --- a/physx/source/geomutils/src/mesh/GuBV4_CapsuleSweep_Internal.h +++ b/physx/source/geomutils/src/mesh/GuBV4_CapsuleSweep_Internal.h @@ -297,7 +297,7 @@ static bool /*__fastcall*/ triCapsuleSweep(CapsuleSweepParams* PX_RESTRICT param return false; } -#include "GuDistanceSegmentTriangleSIMD.h" +#include "GuDistanceSegmentTriangle.h" namespace { diff --git a/physx/source/geomutils/src/mesh/GuMidphaseRTree.cpp b/physx/source/geomutils/src/mesh/GuMidphaseRTree.cpp index 43467413e..71c093c98 100644 --- a/physx/source/geomutils/src/mesh/GuMidphaseRTree.cpp +++ b/physx/source/geomutils/src/mesh/GuMidphaseRTree.cpp @@ -32,7 +32,6 @@ #include "GuIntersectionRayTriangle.h" #include "GuIntersectionCapsuleTriangle.h" #include "GuIntersectionRayBox.h" -#include "GuIntersectionRayBoxSIMD.h" #include "GuSphere.h" #include "GuBoxConversion.h" #include "GuConvexUtilsInternal.h" diff --git a/physx/source/geomutils/src/mesh/GuRTree.h b/physx/source/geomutils/src/mesh/GuRTree.h index 4f4f21589..eeb1098bb 100644 --- a/physx/source/geomutils/src/mesh/GuRTree.h +++ b/physx/source/geomutils/src/mesh/GuRTree.h @@ -81,13 +81,6 @@ namespace Gu { PX_ALIGN_PREFIX(16) struct RTreePage { - //= 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. - //================================================================================================== - static const RTreeValue MN, MX; RTreeValue minx[RTREE_N]; // [min=MX, max=MN] is used as a sentinel range for empty bounds @@ -117,12 +110,6 @@ namespace Gu { PX_ALIGN_PREFIX(16) struct RTree { - //= 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_SERIALIZATION RTree(const PxEMPTY); void exportExtraData(PxSerializationContext&); diff --git a/physx/source/geomutils/src/mesh/GuTetrahedronMesh.h b/physx/source/geomutils/src/mesh/GuTetrahedronMesh.h index 3ce4377ae..02a8f0c51 100644 --- a/physx/source/geomutils/src/mesh/GuTetrahedronMesh.h +++ b/physx/source/geomutils/src/mesh/GuTetrahedronMesh.h @@ -63,6 +63,7 @@ namespace physx virtual PxU32 getReferenceCount() const { return Cm::RefCountable_getRefCount(*this); } virtual void release() { Cm::RefCountable_decRefCount(*this); } virtual void onRefCountZero() { PX_DELETE_THIS; } + virtual PxReal* getGridModelInvMass() { return mGridModelInvMass; } PX_FORCE_INLINE PxU32 getNbTetRemapSizeFast() const { return mTetsRemapSize; } PX_FORCE_INLINE PxReal* getGridModelInvMassFast() { return mGridModelInvMass; } @@ -231,12 +232,6 @@ namespace physx // Possible optimization: align the whole struct to cache line class SoftBodyMesh : public PxSoftBodyMesh, 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. - //================================================================================================== public: virtual const char* getConcreteTypeName() const { return "PxSoftBodyMesh"; } diff --git a/physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.cpp b/physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.cpp new file mode 100644 index 000000000..bc3eddf40 --- /dev/null +++ b/physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.cpp @@ -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. + +#include "GuTetrahedronMeshUtils.h" +#include "GuDistancePointTetrahedron.h" + +namespace physx +{ +namespace Gu +{ + +void convertSoftbodyCollisionToSimMeshTets(const PxTetrahedronMesh& simMesh, const SoftBodyAuxData& simState, + const BVTetrahedronMesh& collisionMesh, PxU32 inTetId, + const PxVec4& inTetBarycentric, PxU32& outTetId, PxVec4& outTetBarycentric) +{ + if (inTetId == 0xFFFFFFFF) + { + outTetId = 0xFFFFFFFF; + outTetBarycentric = PxVec4(0.0f); + return; + } + + // Map from CPU tet ID (corresponds to the ID in the BV4 mesh) to the GPU tet ID (corresponds to the ID in + // the BV32 mesh) + inTetId = collisionMesh.mGRB_faceRemapInverse[inTetId]; + + const PxU32 endIdx = simState.mTetsAccumulatedRemapColToSim[inTetId]; + const PxU32 startIdx = inTetId != 0 ? simState.mTetsAccumulatedRemapColToSim[inTetId - 1] : 0; + + const PxU32* const tetRemapColToSim = simState.mTetsRemapColToSim; + + typedef PxVec4T uint4; + + const uint4* const collInds = + reinterpret_cast(collisionMesh.mGRB_tetraIndices /*collisionMesh->mTetrahedrons*/); + const uint4* const simInds = reinterpret_cast(simMesh.getTetrahedrons()); + + const PxVec3* const collVerts = collisionMesh.mVertices; + const PxVec3* const simVerts = simMesh.getVertices(); + + const uint4 ind = collInds[inTetId]; + + const PxVec3 point = collVerts[ind.x] * inTetBarycentric.x + collVerts[ind.y] * inTetBarycentric.y + + collVerts[ind.z] * inTetBarycentric.z + collVerts[ind.w] * inTetBarycentric.w; + + PxReal currDist = PX_MAX_F32; + + for(PxU32 i = startIdx; i < endIdx; ++i) + { + const PxU32 simTet = tetRemapColToSim[i]; + + const uint4 simInd = simInds[simTet]; + + const PxVec3 a = simVerts[simInd.x]; + const PxVec3 b = simVerts[simInd.y]; + const PxVec3 c = simVerts[simInd.z]; + const PxVec3 d = simVerts[simInd.w]; + + const PxVec3 tmpClosest = closestPtPointTetrahedronWithInsideCheck(point, a, b, c, d); + const PxVec3 v = point - tmpClosest; + const PxReal tmpDist = v.dot(v); + if(tmpDist < currDist) + { + PxVec4 tmpBarycentric; + computeBarycentric(a, b, c, d, tmpClosest, tmpBarycentric); + currDist = tmpDist; + outTetId = simTet; + outTetBarycentric = tmpBarycentric; + if(tmpDist < 1e-6f) + break; + } + } + + PX_ASSERT(outTetId != 0xFFFFFFFF); +} + +} +} \ No newline at end of file diff --git a/physx/source/geomutils/src/distance/GuDistancePointTriangleSIMD.h b/physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.h similarity index 71% rename from physx/source/geomutils/src/distance/GuDistancePointTriangleSIMD.h rename to physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.h index 77645b0b9..6151115c4 100644 --- a/physx/source/geomutils/src/distance/GuDistancePointTriangleSIMD.h +++ b/physx/source/geomutils/src/mesh/GuTetrahedronMeshUtils.h @@ -23,30 +23,24 @@ // 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 GU_DISTANCE_POINT_TRIANGLE_SIMD_H -#define GU_DISTANCE_POINT_TRIANGLE_SIMD_H +#ifndef GU_TETRAHEDRONMESHUTILS_H +#define GU_TETRAHEDRONMESHUTILS_H -#include "common/PxPhysXCommonConfig.h" -#include "foundation/PxVecMath.h" +#include namespace physx { namespace Gu { - PX_PHYSX_COMMON_API aos::FloatV distancePointTriangleSquared( const aos::Vec3VArg point, - const aos::Vec3VArg a, - const aos::Vec3VArg b, - const aos::Vec3VArg c, - aos::FloatV& u, - aos::FloatV& v, - aos::Vec3V& closestP); - -} // namespace Gu +PX_PHYSX_COMMON_API +void convertSoftbodyCollisionToSimMeshTets(const PxTetrahedronMesh& simMesh, const SoftBodyAuxData& simState, + const BVTetrahedronMesh& collisionMesh, PxU32 inTetId, + const PxVec4& inTetBarycentric, PxU32& outTetId, + PxVec4& outTetBarycentric); } +} #endif diff --git a/physx/source/geomutils/src/mesh/GuTriangleMesh.h b/physx/source/geomutils/src/mesh/GuTriangleMesh.h index a075db5b0..761022842 100644 --- a/physx/source/geomutils/src/mesh/GuTriangleMesh.h +++ b/physx/source/geomutils/src/mesh/GuTriangleMesh.h @@ -76,12 +76,6 @@ class EdgeList; class TriangleMesh : public PxTriangleMesh, 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. -//================================================================================================== public: // PX_SERIALIZATION diff --git a/physx/source/geomutils/src/pcm/GuPCMContactBoxBox.cpp b/physx/source/geomutils/src/pcm/GuPCMContactBoxBox.cpp index 9390ee589..41977d23b 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactBoxBox.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactBoxBox.cpp @@ -53,7 +53,7 @@ static void getIncidentPolygon(aos::Vec3V* pts, aos::Vec3V& faceNormal, const ao const Vec3V u1 = transf1To0.getCol1(); const Vec3V u2 = transf1To0.getCol2(); - //calcaulte the insident face for b + //calculate the insident face for b const FloatV d0 = V3Dot(u0, axis); const FloatV d1 = V3Dot(u1, axis); const FloatV d2 = V3Dot(u2, axis); @@ -82,7 +82,6 @@ static void getIncidentPolygon(aos::Vec3V* pts, aos::Vec3V& faceNormal, const ao pts[1] = V3Add(temp0, temp2); // (-x/x, y, -z) pts[2] = V3Sub(temp0, temp1); // (-x/x, -y, -z) pts[3] = V3Sub(temp0, temp2); // (-x/x, -y, z) - } else if(FAllGrtrOrEq(absd1, absd2)) { @@ -331,7 +330,7 @@ static void calculateContacts( const aos::FloatVArg extentX_, const aos::FloatVA { const Vec3V intersectP = V3ScaleAdd(p0p1, tmax, p0); manifoldContacts[numContacts].mLocalPointA = V3SetZ(intersectP, zero); - manifoldContacts[numContacts].mLocalPointB = intersectP; + manifoldContacts[numContacts].mLocalPointB = intersectP; manifoldContacts[numContacts++].mLocalNormalPen = V4SetW(Vec4V_From_Vec3V(localNormal), FNeg(V3GetZ(intersectP))); } } @@ -384,7 +383,7 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: rb = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); radiusSum = FAdd(ea0, rb); - overlap[0] = FAdd(FSub(radiusSum, FAbs(sign[0])), contactDist); + overlap[0] = FAdd(FSub(radiusSum, FAbs(sign[0])), contactDist); if(FAllGrtr(zero, overlap[0])) return false; } @@ -397,7 +396,7 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: rb = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); radiusSum = FAdd(ea1, rb); - overlap[1] = FAdd(FSub(radiusSum, FAbs(sign[1])), contactDist); + overlap[1] = FAdd(FSub(radiusSum, FAbs(sign[1])), contactDist); if(FAllGrtr(zero, overlap[1])) return false; } @@ -411,7 +410,7 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: rb = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); radiusSum = FAdd(ea2, rb); - overlap[2] = FAdd(FSub(radiusSum, FAbs(sign[2])), contactDist); + overlap[2] = FAdd(FSub(radiusSum, FAbs(sign[2])), contactDist); if(FAllGrtr(zero, overlap[2])) return false; } @@ -421,10 +420,10 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: sign[3] = V3Dot(transform1To0.p, col0); const Vec3V vtemp3 = V3Mul(abs1To0Col0, box0Extent); - ra = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); + ra = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); radiusSum = FAdd(ra, eb0); - overlap[3] = FAdd(FSub(radiusSum, FAbs(sign[3])), contactDist); + overlap[3] = FAdd(FSub(radiusSum, FAbs(sign[3])), contactDist); if(FAllGrtr(zero, overlap[3])) return false; } @@ -434,10 +433,10 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: sign[4] = V3Dot(transform1To0.p, col1); const Vec3V vtemp3 = V3Mul(abs1To0Col1, box0Extent); - ra = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); + ra = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); radiusSum = FAdd(ra, eb1); - overlap[4] = FAdd(FSub(radiusSum, FAbs(sign[4])), contactDist); + overlap[4] = FAdd(FSub(radiusSum, FAbs(sign[4])), contactDist); if(FAllGrtr(zero, overlap[4])) return false; } @@ -447,10 +446,10 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: sign[5] = V3Dot(transform1To0.p, col2); const Vec3V vtemp3 = V3Mul(abs1To0Col2, box0Extent); - ra = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); + ra = FAdd(V3GetX(vtemp3), FAdd(V3GetY(vtemp3), V3GetZ(vtemp3))); radiusSum = FAdd(ra, eb2); - overlap[5] = FAdd(FSub(radiusSum, FAbs(sign[5])), contactDist); + overlap[5] = FAdd(FSub(radiusSum, FAbs(sign[5])), contactDist); if(FAllGrtr(zero, overlap[5])) return false; } @@ -757,7 +756,7 @@ static PxU32 doBoxBoxGenerateContacts(const aos::Vec3VArg box0Extent, const aos: newTransformV.rot.col0 = V3Neg(axis12); newTransformV.rot.col1 = axis11; newTransformV.rot.col2 = axis10; - newTransformV.p =V3NegScaleSub(axis10, eb0, transform1.p);//transform0.p + extents0.x*axis00; + newTransformV.p = V3NegScaleSub(axis10, eb0, transform1.p);//transform0.p + extents0.x*axis00; } const aos::PxMatTransformV transform1ToNew = newTransformV.transformInv(transform0); @@ -872,7 +871,6 @@ bool Gu::pcmContactBoxBox(GU_CONTACT_METHOD_ARGS) PX_ASSERT(transform1.q.isSane()); PX_ASSERT(transform0.q.isSane()); - const FloatV contactDist = FLoad(params.mContactDistance); const Vec3V boxExtents0 = V3LoadU(shapeBox0.halfExtents); const Vec3V boxExtents1 = V3LoadU(shapeBox1.halfExtents); @@ -950,7 +948,7 @@ bool Gu::pcmContactBoxBox(GU_CONTACT_METHOD_ARGS) const RelativeConvex convexA1(box0, aToB); const LocalConvex convexB1(box1); - status= epaPenetration(convexA1, convexB1, manifold.mAIndice, manifold.mBIndice, manifold.mNumWarmStartPoints, + status = epaPenetration(convexA1, convexB1, manifold.mAIndice, manifold.mBIndice, manifold.mNumWarmStartPoints, true, FLoad(toleranceLength), output); } @@ -978,7 +976,7 @@ bool Gu::pcmContactBoxBox(GU_CONTACT_METHOD_ARGS) } else if(manifold.getNumContacts() > 0) { - const Vec3V worldNormal = manifold.getWorldNormal(transf1); + const Vec3V worldNormal = manifold.getWorldNormal(transf1); manifold.addManifoldContactsToContactBuffer(contactBuffer, worldNormal, transf1, contactDist); #if PCM_LOW_LEVEL_DEBUG manifold.drawManifold(*renderOutput, transf0, transf1); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactBoxConvex.cpp b/physx/source/geomutils/src/pcm/GuPCMContactBoxConvex.cpp index 3550ec46c..6da3dba6a 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactBoxConvex.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactBoxConvex.cpp @@ -43,9 +43,9 @@ using namespace Gu; using namespace aos; static bool fullContactsGenerationBoxConvex(const GjkConvex* relativeConvex, const GjkConvex* localConvex, const PxTransformV& transf0, const PxTransformV& transf1, - PersistentContact* manifoldContacts, PxContactBuffer& contactBuffer, Gu::PersistentContactManifold& manifold, Vec3VArg normal, - const Vec3VArg closestA, const Vec3VArg closestB, const FloatVArg contactDist, const bool idtScale, const bool doOverlapTest, PxRenderOutput* renderOutput, - const PxReal toleranceLength) + PersistentContact* manifoldContacts, PxContactBuffer& contactBuffer, Gu::PersistentContactManifold& manifold, Vec3VArg normal, + const Vec3VArg closestA, const Vec3VArg closestB, const FloatVArg contactDist, bool idtScale, bool doOverlapTest, PxRenderOutput* renderOutput, + PxReal toleranceLength) { Gu::PolygonalData polyData0; @@ -61,10 +61,10 @@ static bool fullContactsGenerationBoxConvex(const GjkConvex* relativeConvex, con Gu::PolygonalData polyData1; getPCMConvexData(convexHull, idtScale, polyData1); - Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); SupportLocalImpl map0(box, transf0, identity, identity, true); - PxU8 buff1[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff1[sizeof(SupportLocalImpl)]); SupportLocal* map1 = (idtScale ? static_cast(PX_PLACEMENT_NEW(buff1, SupportLocalImpl)(static_cast(convexHull), transf1, convexHull.vertex2Shape, convexHull.shape2Vertex, idtScale)) : static_cast(PX_PLACEMENT_NEW(buff1, SupportLocalImpl)(convexHull, transf1, convexHull.vertex2Shape, convexHull.shape2Vertex, idtScale))); @@ -81,7 +81,6 @@ static bool fullContactsGenerationBoxConvex(const GjkConvex* relativeConvex, con #if PCM_LOW_LEVEL_DEBUG manifold.drawManifold(*renderOutput, transf0, transf1); #endif - const Vec3V worldNormal = manifold.getWorldNormal(transf1); manifold.addManifoldContactsToContactBuffer(contactBuffer, worldNormal, transf1, contactDist); @@ -102,10 +101,10 @@ static bool fullContactsGenerationBoxConvex(const GjkConvex* relativeConvex, con return false; } -static bool generateOrProcessContactsBoxConvex(const GjkConvex* relativeConvex, const GjkConvex* localConvex, const PxTransformV& transf0, const PxTransformV& transf1, - const PxMatTransformV& aToB, GjkStatus status, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, - const PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, - const bool idtScale, const PxReal toleranceLength, PxRenderOutput* renderOutput) +static bool generateOrProcessContactsBoxConvex( const GjkConvex* relativeConvex, const GjkConvex* localConvex, const PxTransformV& transf0, const PxTransformV& transf1, + const PxMatTransformV& aToB, GjkStatus status, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, + PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, + bool idtScale, PxReal toleranceLength, PxRenderOutput* renderOutput) { if (status == GJK_NON_INTERSECT) { @@ -246,7 +245,7 @@ bool Gu::pcmContactBoxConvex(GU_CONTACT_METHOD_ARGS) } else if(manifold.getNumContacts()>0) { - const Vec3V worldNormal = manifold.getWorldNormal(transf1); + const Vec3V worldNormal = manifold.getWorldNormal(transf1); manifold.addManifoldContactsToContactBuffer(contactBuffer, worldNormal, transf1, contactDist); #if PCM_LOW_LEVEL_DEBUG manifold.drawManifold(*renderOutput, transf0, transf1); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleBox.cpp b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleBox.cpp index 9e2c2328a..f6149f9ff 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleBox.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleBox.cpp @@ -48,7 +48,7 @@ static bool fullContactsGenerationCapsuleBox(const CapsuleV& capsule, const BoxV PCMPolygonalBox polyBox(halfExtents); polyBox.getPolygonalData(&polyData); - Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); SupportLocalImpl map(box, transf1, identity, identity); PxU32 origContacts = numContacts; @@ -129,7 +129,7 @@ bool Gu::pcmContactCapsuleBox(GU_CONTACT_METHOD_ARGS) GjkOutput output; const Vec3V initialSearchDir = V3Sub(capsule.getCenter(), box.getCenter()); - status = gjkPenetration, LocalConvex >(convexA, convexB, initialSearchDir, contactDist, true, + status = gjkPenetration, LocalConvex >(convexA, convexB, initialSearchDir, contactDist, true, manifold.mAIndice, manifold.mBIndice, manifold.mNumWarmStartPoints, output); PersistentContact* manifoldContacts = PX_CP_TO_PCP(contactBuffer.contacts); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleCapsule.cpp b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleCapsule.cpp index fcb0797d0..f3b782465 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleCapsule.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleCapsule.cpp @@ -29,7 +29,7 @@ #include "geomutils/PxContactBuffer.h" #include "GuVecCapsule.h" #include "GuContactMethodImpl.h" -#include "GuDistanceSegmentSegmentSIMD.h" +#include "GuDistanceSegmentSegment.h" using namespace physx; using namespace Gu; @@ -185,7 +185,7 @@ bool Gu::pcmContactCapsuleCapsule(GU_CONTACT_METHOD_ARGS) if(BAllEqTTTT(bCon)) { const FloatV dist = FSqrt(sqDist); - const FloatV pen = FSub(dist, sumRadius); + const FloatV pen = FSub(dist, sumRadius); const Vec3V normal = V3ScaleInv(v, dist); PX_ASSERT(isFiniteVec3V(normal)); const Vec3V _p = V3NegScaleSub(normal, r0, projS1); @@ -205,8 +205,8 @@ bool Gu::pcmContactCapsuleCapsule(GU_CONTACT_METHOD_ARGS) if(BAllEqTTTT(bCon)) { const FloatV dist = FSqrt(sqDist); - const FloatV pen = FSub(dist, sumRadius); - const Vec3V normal = V3ScaleInv(v, dist); + const FloatV pen = FSub(dist, sumRadius); + const Vec3V normal = V3ScaleInv(v, dist); PX_ASSERT(isFiniteVec3V(normal)); const Vec3V _p = V3NegScaleSub(normal, r0, projE1); const Vec3V p = V3Add(_p, positionOffset); @@ -225,7 +225,7 @@ bool Gu::pcmContactCapsuleCapsule(GU_CONTACT_METHOD_ARGS) if(BAllEqTTTT(bCon)) { const FloatV dist = FSqrt(sqDist); - const FloatV pen = FSub(dist, sumRadius); + const FloatV pen = FSub(dist, sumRadius); const Vec3V normal = V3ScaleInv(v, dist); PX_ASSERT(isFiniteVec3V(normal)); const Vec3V _p = V3NegScaleSub(normal, r0, s0); @@ -246,7 +246,7 @@ bool Gu::pcmContactCapsuleCapsule(GU_CONTACT_METHOD_ARGS) if(BAllEqTTTT(bCon)) { const FloatV dist = FSqrt(sqDist); - const FloatV pen = FSub(dist, sumRadius); + const FloatV pen = FSub(dist, sumRadius); const Vec3V normal = V3ScaleInv(v, dist); PX_ASSERT(isFiniteVec3V(normal)); const Vec3V _p = V3NegScaleSub(normal, r0, e0); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleConvex.cpp b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleConvex.cpp index 295d57289..7cfa9dbef 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleConvex.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleConvex.cpp @@ -40,23 +40,21 @@ using namespace physx; using namespace Gu; using namespace aos; -static bool fullContactsGenerationCapsuleConvex(const CapsuleV& capsule, const ConvexHullV& convexHull, const PxMatTransformV& aToB, const PxTransformV& transf0,const PxTransformV& transf1, - PersistentContact* manifoldContacts, PxContactBuffer& contactBuffer, const bool idtScale, PersistentContactManifold& manifold, Vec3VArg normal, - const Vec3VArg closest, const PxReal tolerance, const FloatVArg contactDist, const bool doOverlapTest, PxRenderOutput* renderOutput, const PxReal toleranceLength) +static bool fullContactsGenerationCapsuleConvex(const CapsuleV& capsule, const ConvexHullV& convexHull, const PxMatTransformV& aToB, const PxTransformV& transf0,const PxTransformV& transf1, + PersistentContact* manifoldContacts, PxContactBuffer& contactBuffer, bool idtScale, PersistentContactManifold& manifold, Vec3VArg normal, + const Vec3VArg closest, PxReal tolerance, const FloatVArg contactDist, bool doOverlapTest, PxRenderOutput* renderOutput, PxReal toleranceLength) { - PX_UNUSED(renderOutput); Gu::PolygonalData polyData; getPCMConvexData(convexHull,idtScale, polyData); - PxU8 buff[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff[sizeof(SupportLocalImpl)]); SupportLocal* map = (idtScale ? static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(static_cast(convexHull), transf1, convexHull.vertex2Shape, convexHull.shape2Vertex, idtScale)) : static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(convexHull, transf1, convexHull.vertex2Shape, convexHull.shape2Vertex, idtScale))); PxU32 numContacts = 0; if (generateFullContactManifold(capsule, polyData, map, aToB, manifoldContacts, numContacts, contactDist, normal, closest, tolerance, doOverlapTest, toleranceLength)) { - if (numContacts > 0) { manifold.addBatchManifoldContacts2(manifoldContacts, numContacts); @@ -125,7 +123,6 @@ bool Gu::pcmContactCapsuleConvex(GU_CONTACT_METHOD_ARGS) GjkStatus status = manifold.mNumContacts > 0 ? GJK_UNDEFINED : GJK_NON_INTERSECT; - PX_UNUSED(bLostContacts); if(bLostContacts || manifold.invalidate_SphereCapsule(curRTrans, minMargin)) { const bool idtScale = shapeConvex.scale.isIdentity(); @@ -208,15 +205,12 @@ bool Gu::pcmContactCapsuleConvex(GU_CONTACT_METHOD_ARGS) //Add contact to manifold manifold.addManifoldPoint2(localPointA, output.closestB, localNormalPen, replaceBreakingThreshold); - - } else { doOverlapTest = true; } } - if(initialContacts == 0 || bLostContacts || doOverlapTest) { diff --git a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleMesh.cpp b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleMesh.cpp index db7317221..d0d7e7587 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactCapsuleMesh.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactCapsuleMesh.cpp @@ -103,9 +103,7 @@ bool physx::Gu::pcmContactCapsuleMesh(GU_CONTACT_METHOD_ARGS) // Capsule data const PxVec3 tmp = getCapsuleHalfHeightVector(transform0, shapeCapsule); - Segment worldCapsule; - worldCapsule.p0 = transform0.p + tmp; - worldCapsule.p1 = transform0.p - tmp; + const Segment worldCapsule(transform0.p + tmp, transform0.p - tmp); const Segment meshCapsule( // Capsule in mesh space transform1.transformInv(worldCapsule.p0), @@ -181,12 +179,14 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateEE(const aos::Vec3VArg p, co const FloatV signP = FSub(np, d); const FloatV signQ = FSub(nq, d); const FloatV temp = FMul(signP, signQ); - if(FAllGrtr(temp, zero)) return;//If both points in the same side as the plane, no intersect points + if(FAllGrtr(temp, zero)) + return;//If both points in the same side as the plane, no intersect points // if colliding edge (p3,p4) and plane are parallel return no collision const Vec3V pq = V3Sub(q, p); const FloatV npq= V3Dot(n, pq); - if(FAllEq(npq, zero)) return; + if(FAllEq(npq, zero)) + return; const FloatV one = FOne(); //calculate the intersect point in the segment pq @@ -205,7 +205,7 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateEE(const aos::Vec3VArg p, co if(BAllEqFFFF(con)) return; - //const Vec3V localPointB = V3ScaleAdd(ab, tValue, a); v = V3Sub(localPointA, localPointB); v = V3NegScaleSub(ab, tValue, tap) + //const Vec3V localPointB = V3ScaleAdd(ab, tValue, a); v = V3Sub(localPointA, localPointB); v = V3NegScaleSub(ab, tValue, tap) const Vec3V v = V3NegScaleSub(ab, tValue, ap); const FloatV sqDist = V3Dot(v, v); @@ -221,8 +221,6 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateEE(const aos::Vec3VArg p, co } } - - void Gu::PCMCapsuleVsMeshContactGeneration::generateEEContacts(const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, const aos::Vec3VArg normal, const PxU32 triangleIndex, const aos::Vec3VArg p, @@ -238,9 +236,9 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateEEContacts(const aos::Vec3VA generateEE(p, q, sqInflatedRadius, normal, triangleIndex, a, c, manifoldContacts, numContacts); } -void Gu::PCMCapsuleVsMeshContactGeneration::generateEEMTD(const aos::Vec3VArg p, const aos::Vec3VArg q, const aos::FloatVArg inflatedRadius, - const aos::Vec3VArg normal, const PxU32 triangleIndex, const aos::Vec3VArg a, const aos::Vec3VArg b, - Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts) +void Gu::PCMCapsuleVsMeshContactGeneration::generateEEMTD( const aos::Vec3VArg p, const aos::Vec3VArg q, const aos::FloatVArg inflatedRadius, + const aos::Vec3VArg normal, const PxU32 triangleIndex, const aos::Vec3VArg a, const aos::Vec3VArg b, + Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts) { const FloatV zero = FZero(); const Vec3V ab = V3Sub(b, a); @@ -251,12 +249,14 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateEEMTD(const aos::Vec3VArg p, const FloatV signP = FSub(np, d); const FloatV signQ = FSub(nq, d); const FloatV temp = FMul(signP, signQ); - if(FAllGrtr(temp, zero)) return;//If both points in the same side as the plane, no intersect points + if(FAllGrtr(temp, zero)) + return;//If both points in the same side as the plane, no intersect points // if colliding edge (p3,p4) and plane are parallel return no collision const Vec3V pq = V3Sub(q, p); const FloatV npq= V3Dot(n, pq); - if(FAllEq(npq, zero)) return; + if(FAllEq(npq, zero)) + return; //calculate the intersect point in the segment pq const FloatV segTValue = FDiv(FSub(d, np), npq); @@ -283,12 +283,11 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateEEMTD(const aos::Vec3VArg p, } } - -void Gu::PCMCapsuleVsMeshContactGeneration::generateEEContactsMTD(const aos::Vec3VArg a, const aos::Vec3VArg b, - const aos::Vec3VArg c, const aos::Vec3VArg normal, - const PxU32 triangleIndex, const aos::Vec3VArg p, - const aos::Vec3VArg q, const aos::FloatVArg inflatedRadius, - Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts) +void Gu::PCMCapsuleVsMeshContactGeneration::generateEEContactsMTD( const aos::Vec3VArg a, const aos::Vec3VArg b, + const aos::Vec3VArg c, const aos::Vec3VArg normal, + const PxU32 triangleIndex, const aos::Vec3VArg p, + const aos::Vec3VArg q, const aos::FloatVArg inflatedRadius, + Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts) { generateEEMTD(p, q, inflatedRadius, normal, triangleIndex, a, b, manifoldContacts, numContacts); generateEEMTD(p, q, inflatedRadius, normal, triangleIndex, b, c, manifoldContacts, numContacts); @@ -311,13 +310,17 @@ void Gu::PCMCapsuleVsMeshContactGeneration::generateContacts(const aos::Vec3VArg const FloatV d00 = V3Dot(ab, ab); const FloatV d01 = V3Dot(ab, ac); const FloatV d11 = V3Dot(ac, ac); - const FloatV bdenom = FRecip(FSub(FMul(d00,d11), FMul(d01, d01))); + + const FloatV zero = FZero(); + const FloatV largeValue = FLoad(1e+20f); + const FloatV tDenom = FSub(FMul(d00, d11), FMul(d01, d01)); + const FloatV bdenom = FSel(FIsGrtr(tDenom, zero), FRecip(tDenom), largeValue); //compute the intersect point of p and triangle plane abc const FloatV inomp = V3Dot(planeNormal, V3Neg(ap)); const FloatV ideom = V3Dot(planeNormal, normal); - const FloatV ipt = FSel(FIsGrtr(ideom, FZero()), FNeg(FDiv(inomp, ideom)), FLoad(1e+20f)); + const FloatV ipt = FSel(FIsGrtr(ideom, zero), FNeg(FDiv(inomp, ideom)), largeValue); const Vec3V closestP31 = V3NegScaleSub(normal, ipt, p); const Vec3V closestP30 = p; @@ -465,11 +468,9 @@ static PX_FORCE_INLINE aos::Vec4V pcmDistanceSegmentSegmentSquared4(const aos::V return vd; } -/* - t is the barycenteric coordinate of a segment - u is the barycenteric coordinate of a triangle - v is the barycenteric coordinate of a triangle -*/ +// t is the barycenteric coordinate of a segment +// u is the barycenteric coordinate of a triangle +// v is the barycenteric coordinate of a triangle static aos::FloatV pcmDistanceSegmentTriangleSquared( const aos::Vec3VArg p, const aos::Vec3VArg q, const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, aos::FloatV& t, aos::FloatV& u, aos::FloatV& v) @@ -484,7 +485,7 @@ static aos::FloatV pcmDistanceSegmentTriangleSquared( const aos::Vec3VArg p, con const Vec3V ap = V3Sub(p, a); const Vec3V aq = V3Sub(q, a); - const Vec3V n =V3Normalize(V3Cross(ab, ac)); // normalize vector + const Vec3V n = V3Normalize(V3Cross(ab, ac)); // normalize vector const Vec4V combinedDot = V3Dot4(ab, ab, ab, ac, ac, ac, ap, n); const FloatV d00 = V4GetX(combinedDot); @@ -492,8 +493,10 @@ static aos::FloatV pcmDistanceSegmentTriangleSquared( const aos::Vec3VArg p, con const FloatV d11 = V4GetZ(combinedDot); const FloatV dist3 = V4GetW(combinedDot); - const FloatV bdenom = FRecip(FSub(FMul(d00,d11), FMul(d01, d01))); - + // PT: the new version is copied from Gu::distanceSegmentTriangleSquared + const FloatV tDenom = FSub(FMul(d00, d11), FMul(d01, d01)); + const FloatV bdenom = FSel(FIsGrtr(tDenom, zero), FRecip(tDenom), zero); + const FloatV sqDist3 = FMul(dist3, dist3); //compute the closest point of q and triangle plane abc @@ -555,9 +558,7 @@ static aos::FloatV pcmDistanceSegmentTriangleSquared( const aos::Vec3VArg p, con if(BAllEqTTTT(cond2)) { - /* - both p and q project points are interior point - */ + // both p and q project points are interior point const BoolV d2 = FIsGrtr(sqDist4, sqDist3); t = FSel(d2, zero, one); u = FSel(d2, v0, v1); @@ -693,7 +694,6 @@ static bool selectNormal(const aos::FloatVArg u, aos::FloatVArg v, PxU8 data) bool Gu::PCMCapsuleVsMeshContactGeneration::processTriangle(const PxVec3* verts, const PxU32 triangleIndex, PxU8 triFlags, const PxU32* vertInds) { - PX_UNUSED(triangleIndex); PX_UNUSED(vertInds); const FloatV zero = FZero(); @@ -841,3 +841,12 @@ bool Gu::PCMCapsuleVsMeshContactGeneration::processTriangle(const TriangleV& tri } return true; } + + +// PT: below is just for internal testing +PX_PHYSX_COMMON_API aos::FloatV pcmDistanceSegmentTriangleSquaredExported( const aos::Vec3VArg p, const aos::Vec3VArg q, + const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, + aos::FloatV& t, aos::FloatV& u, aos::FloatV& v) +{ + return pcmDistanceSegmentTriangleSquared(p, q, a, b, c, t, u, v); +} diff --git a/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.cpp b/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.cpp index 8aec8c996..f00d15a8f 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.cpp @@ -38,7 +38,7 @@ using namespace aos; /* This function adds the newly created manifold contacts to a new patch or existing patches */ -void PCMConvexVsMeshContactGeneration::addContactsToPatch(const aos::Vec3VArg patchNormal, const PxU32 previousNumContacts) +void PCMConvexVsMeshContactGeneration::addContactsToPatch(const aos::Vec3VArg patchNormal, PxU32 previousNumContacts) { const Vec3V patchNormalInTriangle = mMeshToConvex.rotateInv(patchNormal); @@ -117,7 +117,7 @@ void PCMConvexVsMeshContactGeneration::generateLastContacts() if(needsProcessing) { - Gu::TriangleV localTriangle(currentContact.mVerts); + const Gu::TriangleV localTriangle(currentContact.mVerts); Vec3V patchNormal; const PxU32 previousNumContacts = mNumContacts; //the localTriangle is in the convex space @@ -177,7 +177,7 @@ void PCMConvexVsMeshContactGeneration::generateLastContacts() bool PCMConvexVsMeshContactGeneration::processTriangle(const PxVec3* verts, PxU32 triangleIndex, PxU8 triFlags, const PxU32* vertInds) { - const Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); const FloatV zero = FZero(); const Vec3V v0 = V3LoadU(verts[0]); @@ -201,7 +201,7 @@ bool PCMConvexVsMeshContactGeneration::processTriangle(const PxVec3* verts, PxU3 const Vec3V locV1 = mMeshToConvex.transform(v1); const Vec3V locV2 = mMeshToConvex.transform(v2); - Gu::TriangleV localTriangle(locV0, locV1, locV2); + const Gu::TriangleV localTriangle(locV0, locV1, locV2); { SupportLocalImpl localTriMap(localTriangle, mConvexTransform, identity, identity, true); @@ -237,10 +237,10 @@ bool PCMConvexVsMeshContactGeneration::processTriangle(const PxVec3* verts, PxU3 return true; } -bool PCMConvexVsMeshContactGeneration::processTriangle(const Gu::PolygonalData& polyData, SupportLocal* polyMap, const PxVec3* verts, const PxU32 triangleIndex, PxU8 triFlags,const aos::FloatVArg inflation, const bool isDoubleSided, +bool PCMConvexVsMeshContactGeneration::processTriangle(const Gu::PolygonalData& polyData, const SupportLocal* polyMap, const PxVec3* verts, PxU32 triangleIndex, PxU8 triFlags,const aos::FloatVArg inflation, bool isDoubleSided, const aos::PxTransformV& convexTransform, const aos::PxMatTransformV& meshToConvex, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts) { - const Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); const FloatV zero = FZero(); const Vec3V v0 = V3LoadU(verts[0]); @@ -265,7 +265,7 @@ bool PCMConvexVsMeshContactGeneration::processTriangle(const Gu::PolygonalData& if(culled) return false; - Gu::TriangleV localTriangle(locV0, locV1, locV2); + const Gu::TriangleV localTriangle(locV0, locV1, locV2); SupportLocalImpl localTriMap(localTriangle, convexTransform, identity, identity, true); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.h b/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.h index 09aadad0e..cce08be61 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.h +++ b/physx/source/geomutils/src/pcm/GuPCMContactConvexCommon.h @@ -39,7 +39,6 @@ namespace physx { - namespace Gu { @@ -60,7 +59,6 @@ class PCMMeshContactGeneration const aos::PxTransformV& mMeshTransform; Gu::MultiplePersistentContactManifold& mMultiManifold; PxContactBuffer& mContactBuffer; - aos::FloatV mAcceptanceEpsilon; aos::FloatV mSqReplaceBreakingThreshold; aos::PxMatTransformV mMeshToConvex; @@ -82,7 +80,6 @@ class PCMMeshContactGeneration PxContactBuffer& contactBuffer, PxInlineArray* deferredContacts, PxRenderOutput* renderOutput - ) : mContactDist(contactDist), mReplaceBreakingThreshold(replaceBreakingThreshold), @@ -92,7 +89,6 @@ class PCMMeshContactGeneration mContactBuffer(contactBuffer), mDeferredContacts(deferredContacts), mRenderOutput(renderOutput) - { using namespace aos; mNumContactPatch = 0; @@ -137,10 +133,8 @@ class PCMMeshContactGeneration void processContacts(const PxU8 maxContactPerManifold, const bool isNotLastPatch = true); }; -/* - This function is based on the current patch normal to either create a new patch or merge the manifold contacts in this patch with the manifold contacts in the last existing - patch. This means there might be more than GU_SINGLE_MANIFOLD_CACHE_SIZE in a SinglePersistentContactManifold. -*/ +// This function is based on the current patch normal to either create a new patch or merge the manifold contacts in this patch with the manifold contacts in the last existing +// patch. This means there might be more than GU_SINGLE_MANIFOLD_CACHE_SIZE in a SinglePersistentContactManifold. PX_FORCE_INLINE void PCMMeshContactGeneration::addManifoldPointToPatch(const aos::Vec3VArg currentPatchNormal, const aos::FloatVArg maxPen, const PxU32 previousNumContacts) { using namespace aos; @@ -193,10 +187,8 @@ PX_FORCE_INLINE void PCMMeshContactGeneration::addManifoldPointToPatch(const aos } } -/* - This function sort the contact patch based on the max penetration so that deepest penetration contact patch will be in front of the less penetration contact - patch -*/ +// This function sort the contact patch based on the max penetration so that deepest penetration contact patch will be in front of the less penetration contact +// patch PX_FORCE_INLINE void PCMMeshContactGeneration::prioritizeContactPatches() { //we are using insertion sort to prioritize contact patchs @@ -226,7 +218,6 @@ PX_FORCE_INLINE void PCMMeshContactGeneration::prioritizeContactPatches() } } - PX_FORCE_INLINE void PCMMeshContactGeneration::processContacts(const PxU8 maxContactPerManifold, bool isNotLastPatch) { using namespace aos; @@ -277,9 +268,8 @@ class PCMConvexVsMeshContactGeneration : public PCMMeshContactGeneration public: aos::Vec3V mHullCenterMesh; - const Gu::PolygonalData& mPolyData; - SupportLocal* mPolyMap; + const SupportLocal* mPolyMap; const Cm::FastVertex2ShapeScaling& mConvexScaling; bool mIdtConvexScale; bool mSilhouetteEdgesAreActive; @@ -291,9 +281,8 @@ class PCMConvexVsMeshContactGeneration : public PCMMeshContactGeneration const aos::PxTransformV& meshTransform, Gu::MultiplePersistentContactManifold& multiManifold, PxContactBuffer& contactBuffer, - const Gu::PolygonalData& polyData, - SupportLocal* polyMap, + const SupportLocal* polyMap, PxInlineArray* delayedContacts, const Cm::FastVertex2ShapeScaling& convexScaling, bool idtConvexScale, @@ -316,19 +305,19 @@ class PCMConvexVsMeshContactGeneration : public PCMMeshContactGeneration mHullCenterMesh = mMeshToConvex.transformInv(hullCenterLocal); } - bool generateTriangleFullContactManifold(Gu::TriangleV& localTriangle, const PxU32 triangleIndex, const PxU32* triIndices, const PxU8 triFlags, const Gu::PolygonalData& polyData, Gu::SupportLocalImpl* localTriMap, Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, + bool generateTriangleFullContactManifold(const Gu::TriangleV& localTriangle, PxU32 triangleIndex, const PxU32* triIndices, PxU8 triFlags, const Gu::PolygonalData& polyData, const Gu::SupportLocalImpl* localTriMap, const Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal); - bool generatePolyDataContactManifold(Gu::TriangleV& localTriangle, const PxU32 featureIndex, const PxU32 triangleIndex, const PxU8 triFlags, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal); + bool generatePolyDataContactManifold(const Gu::TriangleV& localTriangle, PxU32 featureIndex, PxU32 triangleIndex, PxU8 triFlags, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal); void generateLastContacts(); - void addContactsToPatch(const aos::Vec3VArg patchNormal, const PxU32 previousNumContacts); + void addContactsToPatch(const aos::Vec3VArg patchNormal, PxU32 previousNumContacts); bool processTriangle(const PxVec3* verts, PxU32 triangleIndex, PxU8 triFlags, const PxU32* vertInds); - static bool generateTriangleFullContactManifold(Gu::TriangleV& localTriangle, const PxU32 triangleIndex, const PxU8 triFlags, const Gu::PolygonalData& polyData, Gu::SupportLocalImpl* localTriMap, Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, + static bool generateTriangleFullContactManifold(const Gu::TriangleV& localTriangle, PxU32 triangleIndex, PxU8 triFlags, const Gu::PolygonalData& polyData, const Gu::SupportLocalImpl* localTriMap, const Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal, PxRenderOutput* renderOutput = NULL); - static bool processTriangle(const Gu::PolygonalData& polyData, SupportLocal* polyMap, const PxVec3* verts, const PxU32 triangleIndex, PxU8 triFlags, const aos::FloatVArg inflation, const bool isDoubleSided, + static bool processTriangle(const Gu::PolygonalData& polyData, const SupportLocal* polyMap, const PxVec3* verts, PxU32 triangleIndex, PxU8 triFlags, const aos::FloatVArg inflation, bool isDoubleSided, const aos::PxTransformV& convexTransform, const aos::PxMatTransformV& meshToConvex, Gu::MeshPersistentContact* manifoldContact, PxU32& numContacts); }; @@ -390,7 +379,6 @@ class PCMCapsuleVsMeshContactGeneration : public PCMMeshContactGeneration aos::FloatV mInflatedRadius; aos::FloatV mSqInflatedRadius; const CapsuleV& mCapsule; - PCMCapsuleVsMeshContactGeneration( const CapsuleV& capsule, diff --git a/physx/source/geomutils/src/pcm/GuPCMContactConvexConvex.cpp b/physx/source/geomutils/src/pcm/GuPCMContactConvexConvex.cpp index 46f90bd31..b5a88ad49 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactConvexConvex.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactConvexConvex.cpp @@ -40,9 +40,9 @@ using namespace Gu; using namespace aos; static bool fullContactsGenerationConvexConvex(const GjkConvex* relativeConvex, const GjkConvex* localConvex, const PxTransformV& transf0, const PxTransformV& transf1, - const bool idtScale0, const bool idtScale1, PersistentContact* manifoldContacts, PxContactBuffer& contactBuffer, + bool idtScale0, bool idtScale1, PersistentContact* manifoldContacts, PxContactBuffer& contactBuffer, PersistentContactManifold& manifold, Vec3VArg normal, const Vec3VArg closestA, const Vec3VArg closestB, - const FloatVArg contactDist, const bool doOverlapTest, PxRenderOutput* renderOutput, const PxReal toleranceLength) + const FloatVArg contactDist, bool doOverlapTest, PxRenderOutput* renderOutput, PxReal toleranceLength) { Gu::PolygonalData polyData0, polyData1; const ConvexHullV& convexHull0 = relativeConvex->getConvex(); @@ -50,8 +50,8 @@ static bool fullContactsGenerationConvexConvex(const GjkConvex* relativeConvex, getPCMConvexData(convexHull0, idtScale0, polyData0); getPCMConvexData(convexHull1, idtScale1, polyData1); - PxU8 buff0[sizeof(SupportLocalImpl)]; - PxU8 buff1[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff0[sizeof(SupportLocalImpl)]); + PX_ALIGN(16, PxU8 buff1[sizeof(SupportLocalImpl)]); SupportLocal* map0 = (idtScale0 ? static_cast(PX_PLACEMENT_NEW(buff0, SupportLocalImpl)(static_cast(convexHull0), transf0, convexHull0.vertex2Shape, convexHull0.shape2Vertex, idtScale0)) : static_cast(PX_PLACEMENT_NEW(buff0, SupportLocalImpl)(convexHull0, transf0, convexHull0.vertex2Shape, convexHull0.shape2Vertex, idtScale0))); @@ -64,7 +64,6 @@ static bool fullContactsGenerationConvexConvex(const GjkConvex* relativeConvex, if(generateFullContactManifold(polyData0, polyData1, map0, map1, manifoldContacts, numContacts, contactDist, normal, closestA, closestB, convexHull0.getMarginF(), convexHull1.getMarginF(), doOverlapTest, renderOutput, toleranceLength)) { - if (numContacts > 0) { //reduce contacts @@ -94,10 +93,10 @@ static bool fullContactsGenerationConvexConvex(const GjkConvex* relativeConvex, return false; } -static bool generateOrProcessContactsConvexConvex(const GjkConvex* relativeConvex, const GjkConvex* localConvex, const PxTransformV& transf0, const PxTransformV& transf1, - const PxMatTransformV& aToB, GjkStatus status, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, - const PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, - const bool idtScale0, const bool idtScale1, const PxReal toleranceLength, PxRenderOutput* renderOutput) +static bool generateOrProcessContactsConvexConvex( const GjkConvex* relativeConvex, const GjkConvex* localConvex, const PxTransformV& transf0, const PxTransformV& transf1, + const PxMatTransformV& aToB, GjkStatus status, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, + PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, + bool idtScale0, bool idtScale1, PxReal toleranceLength, PxRenderOutput* renderOutput) { if (status == GJK_NON_INTERSECT) { @@ -140,10 +139,10 @@ static bool generateOrProcessContactsConvexConvex(const GjkConvex* relativeConve } } -static bool convexHullNoScale0(const ConvexHullV& convexHull0, const ConvexHullV& convexHull1, const PxTransformV& transf0, const PxTransformV& transf1, - const PxMatTransformV& aToB, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, - const PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, - const bool idtScale1, const PxReal toleranceLength, PxRenderOutput* renderOutput) +static bool convexHullNoScale0( const ConvexHullV& convexHull0, const ConvexHullV& convexHull1, const PxTransformV& transf0, const PxTransformV& transf1, + const PxMatTransformV& aToB, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, + PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, + bool idtScale1, PxReal toleranceLength, PxRenderOutput* renderOutput) { const RelativeConvex convexA(static_cast(convexHull0), aToB); if(idtScale1) @@ -167,9 +166,9 @@ static bool convexHullNoScale0(const ConvexHullV& convexHull0, const ConvexHullV } static bool convexHullHasScale0(const ConvexHullV& convexHull0, const ConvexHullV& convexHull1, const PxTransformV& transf0, const PxTransformV& transf1, - const PxMatTransformV& aToB, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, - const PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, - const bool idtScale1, const PxReal toleranceLength, PxRenderOutput* renderOutput) + const PxMatTransformV& aToB, GjkOutput& output, PersistentContactManifold& manifold, PxContactBuffer& contactBuffer, + PxU32 initialContacts, const FloatV minMargin, const FloatV contactDist, + bool idtScale1, PxReal toleranceLength, PxRenderOutput* renderOutput) { RelativeConvex convexA(convexHull0, aToB); if(idtScale1) @@ -265,7 +264,7 @@ bool Gu::pcmContactConvexConvex(GU_CONTACT_METHOD_ARGS) } else if(manifold.getNumContacts()> 0) { - const Vec3V worldNormal = manifold.getWorldNormal(transf1); + const Vec3V worldNormal = manifold.getWorldNormal(transf1); manifold.addManifoldContactsToContactBuffer(contactBuffer, worldNormal, transf1, contactDist); #if PCM_LOW_LEVEL_DEBUG manifold.drawManifold(*renderOutput, transf0, transf1); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactConvexHeightField.cpp b/physx/source/geomutils/src/pcm/GuPCMContactConvexHeightField.cpp index 559b6eda9..7a2c2ceee 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactConvexHeightField.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactConvexHeightField.cpp @@ -243,7 +243,7 @@ bool Gu::pcmContactBoxHeightField(GU_CONTACT_METHOD_ARGS) PCMPolygonalBox polyBox(shapeBox.halfExtents); polyBox.getPolygonalData(&polyData); - const Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); //SupportLocalImpl boxMap(boxV, boxTransform, identity, identity); SupportLocalImpl boxMap(boxV, boxTransform, identity, identity, true); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactConvexMesh.cpp b/physx/source/geomutils/src/pcm/GuPCMContactConvexMesh.cpp index 0e1157231..3dbb091f6 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactConvexMesh.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactConvexMesh.cpp @@ -201,13 +201,13 @@ bool Gu::pcmContactConvexMesh(GU_CONTACT_METHOD_ARGS) if(idtScaleConvex) { SupportLocalImpl convexMap(static_cast(convexHull), convexTransform, convexHull.vertex2Shape, convexHull.shape2Vertex, true); - return Gu::PCMContactConvexMesh(polyData, &convexMap, minMargin, hullAABB, shapeMesh,transform0,transform1, params.mContactDistance, contactBuffer, convexScaling, + return Gu::PCMContactConvexMesh(polyData, &convexMap, minMargin, hullAABB, shapeMesh, transform0, transform1, params.mContactDistance, contactBuffer, convexScaling, meshScaling, idtScaleConvex, idtScaleMesh, multiManifold, renderOutput); } else { SupportLocalImpl convexMap(convexHull, convexTransform, convexHull.vertex2Shape, convexHull.shape2Vertex, false); - return Gu::PCMContactConvexMesh(polyData, &convexMap, minMargin, hullAABB, shapeMesh,transform0,transform1, params.mContactDistance, contactBuffer, convexScaling, + return Gu::PCMContactConvexMesh(polyData, &convexMap, minMargin, hullAABB, shapeMesh, transform0, transform1, params.mContactDistance, contactBuffer, convexScaling, meshScaling, idtScaleConvex, idtScaleMesh, multiManifold, renderOutput); } } @@ -244,7 +244,7 @@ bool Gu::pcmContactBoxMesh(GU_CONTACT_METHOD_ARGS) PCMPolygonalBox polyBox(shapeBox.halfExtents); polyBox.getPolygonalData(&polyData); - Mat33V identity = M33Identity(); + const Mat33V identity = M33Identity(); SupportLocalImpl boxMap(boxV, boxTransform, identity, identity, true); return Gu::PCMContactConvexMesh(polyData, &boxMap, minMargin, hullAABB, shapeMesh, transform0, transform1, params.mContactDistance, contactBuffer, idtScaling, meshScaling, diff --git a/physx/source/geomutils/src/pcm/GuPCMContactGen.h b/physx/source/geomutils/src/pcm/GuPCMContactGen.h index fb8ebc67e..a5d7d4a73 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactGen.h +++ b/physx/source/geomutils/src/pcm/GuPCMContactGen.h @@ -29,7 +29,6 @@ #ifndef GU_PCM_CONTACT_GEN_H #define GU_PCM_CONTACT_GEN_H - #include "GuConvexSupportTable.h" #include "GuPersistentContactManifold.h" #include "GuShapeConvex.h" @@ -39,23 +38,20 @@ namespace physx { - namespace Gu { - - //full contact gen code for box/convexhull vs convexhull - bool generateFullContactManifold(Gu::PolygonalData& polyData0, Gu::PolygonalData& polyData1, Gu::SupportLocal* map0, Gu::SupportLocal* map1, Gu::PersistentContact* manifoldContacts, + bool generateFullContactManifold(const Gu::PolygonalData& polyData0, const Gu::PolygonalData& polyData1, const Gu::SupportLocal* map0, const Gu::SupportLocal* map1, Gu::PersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, const aos::Vec3VArg normal, const aos::Vec3VArg closestA, const aos::Vec3VArg closestB, - const PxReal toleranceA, const PxReal toleranceB, bool doOverlapTest, PxRenderOutput* renderOutput, const PxReal toleranceLength); + PxReal toleranceA, PxReal toleranceB, bool doOverlapTest, PxRenderOutput* renderOutput, PxReal toleranceLength); //full contact gen code for capsule vs convexhulll - bool generateFullContactManifold(const Gu::CapsuleV& capsule, Gu::PolygonalData& polyData, Gu::SupportLocal* map, const aos::PxMatTransformV& aToB, Gu::PersistentContact* manifoldContacts, - PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& normal, const aos::Vec3VArg closest, const PxReal tolerance, bool doOverlapTest, const PxReal toleranceScale); + bool generateFullContactManifold(const Gu::CapsuleV& capsule, const Gu::PolygonalData& polyData, const Gu::SupportLocal* map, const aos::PxMatTransformV& aToB, Gu::PersistentContact* manifoldContacts, + PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& normal, const aos::Vec3VArg closest, PxReal tolerance, bool doOverlapTest, PxReal toleranceScale); //full contact gen code for capsule vs box - bool generateCapsuleBoxFullContactManifold(const Gu::CapsuleV& capsule, Gu::PolygonalData& polyData, Gu::SupportLocal* map, const aos::PxMatTransformV& aToB, Gu::PersistentContact* manifoldContacts, PxU32& numContacts, - const aos::FloatVArg contactDist, aos::Vec3V& normal, const aos::Vec3VArg closest, const PxReal boxMargin, const bool doOverlapTest, const PxReal toeranceScale, PxRenderOutput* renderOutput); + bool generateCapsuleBoxFullContactManifold(const Gu::CapsuleV& capsule, const Gu::PolygonalData& polyData, const Gu::SupportLocal* map, const aos::PxMatTransformV& aToB, Gu::PersistentContact* manifoldContacts, PxU32& numContacts, + const aos::FloatVArg contactDist, aos::Vec3V& normal, const aos::Vec3VArg closest, PxReal boxMargin, bool doOverlapTest, PxReal toleranceScale, PxRenderOutput* renderOutput); //based on the gjk status to decide whether we should do full contact gen with GJK/EPA normal. Also, this method store //GJK/EPA point to the manifold in case full contact gen doesn't generate any contact @@ -64,17 +60,16 @@ namespace Gu Gu::PersistentContactManifold& manifold); //MTD code for box/convexhull vs box/convexhull - bool computeMTD(Gu::PolygonalData& polyData0, Gu::PolygonalData& polyData1, SupportLocal* map0, SupportLocal* map1, aos::FloatV& penDepth, aos::Vec3V& normal); + bool computeMTD(const Gu::PolygonalData& polyData0, const Gu::PolygonalData& polyData1, const SupportLocal* map0, const SupportLocal* map1, aos::FloatV& penDepth, aos::Vec3V& normal); //MTD code for capsule vs box/convexhull - bool computeMTD(const Gu::CapsuleV& capsule, Gu::PolygonalData& polyData, Gu::SupportLocal* map, aos::FloatV& penDepth, aos::Vec3V& normal); + bool computeMTD(const Gu::CapsuleV& capsule, const Gu::PolygonalData& polyData, const Gu::SupportLocal* map, aos::FloatV& penDepth, aos::Vec3V& normal); - void buildPartialHull(const Gu::PolygonalData& polyData, SupportLocal* map, Gu::SeparatingAxes& validAxes, const aos::Vec3VArg v, const aos::Vec3VArg _dir); + void buildPartialHull(const Gu::PolygonalData& polyData, const SupportLocal* map, Gu::SeparatingAxes& validAxes, const aos::Vec3VArg v, const aos::Vec3VArg _dir); //full contact gen code for sphere vs convexhull - bool generateSphereFullContactManifold(const Gu::CapsuleV& capsule, Gu::PolygonalData& polyData, Gu::SupportLocal* map, Gu::PersistentContact* manifoldContacts, PxU32& numContacts, - const aos::FloatVArg contactDist, aos::Vec3V& normal, const bool doOverlapTest); - + bool generateSphereFullContactManifold(const Gu::CapsuleV& capsule, const Gu::PolygonalData& polyData, const Gu::SupportLocal* map, Gu::PersistentContact* manifoldContacts, PxU32& numContacts, + const aos::FloatVArg contactDist, aos::Vec3V& normal, bool doOverlapTest); } } diff --git a/physx/source/geomutils/src/pcm/GuPCMContactGenBoxConvex.cpp b/physx/source/geomutils/src/pcm/GuPCMContactGenBoxConvex.cpp index eca4442b5..38d7e18a6 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactGenBoxConvex.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactGenBoxConvex.cpp @@ -55,18 +55,16 @@ using namespace aos; namespace physx { - namespace Gu -{ - - static bool testFaceNormal(const PolygonalData& polyData0, const PolygonalData& polyData1, SupportLocal* map0, SupportLocal* map1, const PxMatTransformV& transform0To1, const PxMatTransformV& transform1To0, const FloatVArg contactDist, - FloatV& minOverlap, PxU32& feature, Vec3V& faceNormal, const FeatureStatus faceStatus, FeatureStatus& status) +{ + static bool testFaceNormal(const PolygonalData& polyData0, const PolygonalData& polyData1, const SupportLocal* map0, const SupportLocal* map1, const PxMatTransformV& transform0To1, const PxMatTransformV& transform1To0, const FloatVArg contactDist, + FloatV& minOverlap, PxU32& feature, Vec3V& faceNormal, FeatureStatus faceStatus, FeatureStatus& status) { PX_UNUSED(polyData1); FloatV _minOverlap = FMax();//minOverlap; - PxU32 _feature = 0; - Vec3V _faceNormal = faceNormal; + PxU32 _feature = 0; + Vec3V _faceNormal = faceNormal; FloatV min0, max0; FloatV min1, max1; @@ -106,9 +104,7 @@ namespace Gu //rotate polygon's normal into the local space of polyData1 const Vec3V n1 = transform0To1.rotate(n0); - #if PCM_USE_INTERNAL_OBJECT - //test internal object //ML: we don't need to transform the normal into the vertex space. If polyData1 don't have scale, //the vertex2Shape matrix will be identity, shape space normal will be the same as vertex space's normal. @@ -129,12 +125,8 @@ namespace Gu //Internal object overlaps more than current min, so can skip it //because (a) it isn't a separating axis and (b) it isn't the smallest axis if(FAllGrtr(_tempOverlap, _minOverlap)) - { continue; - } - #endif - const FloatV translate = V3Dot(center1To0, n0); map1->doSupport(n1, min1, max1); @@ -163,17 +155,13 @@ namespace Gu status = faceStatus; } - - feature = _feature; return true; - } - //plane is in the shape space of polyData - void buildPartialHull(const PolygonalData& polyData, SupportLocal* map, SeparatingAxes& validAxes, const Vec3VArg planeP, const Vec3VArg planeDir) + void buildPartialHull(const PolygonalData& polyData, const SupportLocal* map, SeparatingAxes& validAxes, const Vec3VArg planeP, const Vec3VArg planeDir) { const FloatV zero = FZero(); const Vec3V dir = V3Normalize(planeDir); @@ -209,11 +197,9 @@ namespace Gu } } - - static bool testEdgeNormal(const PolygonalData& polyData0, const PolygonalData& polyData1, SupportLocal* map0, SupportLocal* map1, const PxMatTransformV& transform0To1, const PxMatTransformV& transform1To0, const FloatVArg contactDist, - FloatV& minOverlap, Vec3V& edgeNormalIn0, const FeatureStatus edgeStatus, FeatureStatus& status) + static bool testEdgeNormal(const PolygonalData& polyData0, const PolygonalData& polyData1, const SupportLocal* map0, const SupportLocal* map1, const PxMatTransformV& transform0To1, const PxMatTransformV& transform1To0, const FloatVArg contactDist, + FloatV& minOverlap, Vec3V& edgeNormalIn0, FeatureStatus edgeStatus, FeatureStatus& status) { - FloatV overlap = minOverlap; FloatV min0, max0; FloatV min1, max1; @@ -303,7 +289,6 @@ namespace Gu PX_ASSERT(FAllGrtrOrEq(_max0, _min0)); PX_ASSERT(FAllGrtrOrEq(_max1, _min1)); - const FloatV _min = FMax(_min0, _min1); const FloatV _max = FMin(_max0, _max1); @@ -312,10 +297,7 @@ namespace Gu //Internal object overlaps more than current min, so can skip it //because (a) it isn't a separating axis and (b) it isn't the smallest axis if(FAllGrtr(_tempOverlap, overlap)) - { continue; - } - #endif //get polyData0's projection map0->doSupport(n0, min0, max0); @@ -337,7 +319,6 @@ namespace Gu #if PCM_USE_INTERNAL_OBJECT PX_ASSERT(FAllGrtrOrEq(tempOverlap, _tempOverlap)); #endif - if(FAllGrtr(overlap, tempOverlap)) { overlap = tempOverlap; @@ -350,16 +331,13 @@ namespace Gu minOverlap = overlap; return true; - } - //contactNormal is in the space of polyData0 - void generatedContacts(PolygonalData& polyData0, PolygonalData& polyData1, const HullPolygonData& referencePolygon, const HullPolygonData& incidentPolygon, - SupportLocal* map0, SupportLocal* map1, const PxMatTransformV& transform0To1, PersistentContact* manifoldContacts, + void generatedContacts(const PolygonalData& polyData0, const PolygonalData& polyData1, const HullPolygonData& referencePolygon, const HullPolygonData& incidentPolygon, + const SupportLocal* map0, const SupportLocal* map1, const PxMatTransformV& transform0To1, PersistentContact* manifoldContacts, PxU32& numContacts, const FloatVArg contactDist, PxRenderOutput* renderOutput) { - PX_UNUSED(renderOutput); const FloatV zero = FZero(); @@ -373,7 +351,6 @@ namespace Gu const PxU8* inds1 = polyData1.mPolygonVertexRefs + incidentPolygon.mVRef8; - Vec3V* points0In0 = reinterpret_cast(PxAllocaAligned(sizeof(Vec3V)*referencePolygon.mNbVerts, 16)); Vec3V* points1In0 = reinterpret_cast(PxAllocaAligned(sizeof(Vec3V)*incidentPolygon.mNbVerts, 16)); bool* points1In0Penetration = reinterpret_cast(PxAlloca(sizeof(bool)*incidentPolygon.mNbVerts)); @@ -416,7 +393,6 @@ namespace Gu Vec3V iPolygonMin= max; Vec3V iPolygonMax = nmax; - PxU32 inside = 0; for(PxU32 i=0; itransform.transformInv(map1->transform); const PxMatTransformV transform0To1V = map1->transform.transformInv(map0->transform); - if(doOverlapTest) { @@ -603,7 +559,6 @@ namespace Gu if(!testFaceNormal(polyData1, polyData0, map1, map0, transform1To0V, transform0To1V, contactDist, minOverlap, feature1, minNormal, POLYDATA1, status)) return false; - bool doEdgeTest = false; EdgeTest: @@ -616,7 +571,6 @@ namespace Gu if(status != EDGE) return true; } - if(status == POLYDATA0) { @@ -645,7 +599,7 @@ namespace Gu { //minNormal is in the local space of polydata1 const HullPolygonData& referencePolygon = polyData1.mPolygons[feature1]; - const HullPolygonData& incidentPolygon = polyData0.mPolygons[getPolygonIndex(polyData0, map0, transform1To0V.rotate(minNormal))]; + const HullPolygonData& incidentPolygon = polyData0.mPolygons[getPolygonIndex(polyData0, map0, transform1To0V.rotate(minNormal))]; //reference face is polyData1 generatedContacts(polyData1, polyData0, referencePolygon, incidentPolygon, map1, map0, transform1To0V, manifoldContacts, numContacts, contactDist, renderOutput); @@ -665,7 +619,6 @@ namespace Gu doEdgeTest = true; goto EdgeTest; } - } else { @@ -773,10 +726,8 @@ namespace Gu return doOverlapTest; } - - bool computeMTD(Gu::PolygonalData& polyData0, Gu::PolygonalData& polyData1, SupportLocal* map0, SupportLocal* map1, aos::FloatV& penDepth, aos::Vec3V& normal) + bool computeMTD(const Gu::PolygonalData& polyData0, const Gu::PolygonalData& polyData1, const SupportLocal* map0, const SupportLocal* map1, aos::FloatV& penDepth, aos::Vec3V& normal) { - using namespace aos; const PxMatTransformV transform1To0V = map0->transform.transformInv(map1->transform); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactGenSphereCapsule.cpp b/physx/source/geomutils/src/pcm/GuPCMContactGenSphereCapsule.cpp index 6d84b65b6..d93f81dca 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactGenSphereCapsule.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactGenSphereCapsule.cpp @@ -40,7 +40,7 @@ using namespace Gu; using namespace aos; //ML: this function is shared by the sphere/capsule vs convex hulls full contact gen, capsule in the local space of polyData -static bool testPolyDataAxis(const Gu::CapsuleV& capsule, const Gu::PolygonalData& polyData, SupportLocal* map, const aos::FloatVArg contactDist, aos::FloatV& minOverlap, aos::Vec3V& separatingAxis) +static bool testPolyDataAxis(const Gu::CapsuleV& capsule, const Gu::PolygonalData& polyData, const SupportLocal* map, const aos::FloatVArg contactDist, aos::FloatV& minOverlap, aos::Vec3V& separatingAxis) { FloatV _minOverlap = FMax();//minOverlap; FloatV min0, max0; @@ -151,7 +151,7 @@ static bool intersectRayPolyhedron(const aos::Vec3VArg a, const aos::Vec3VArg di // |/ |/ |/ 6 = +++ // 0+------+1 *---x 7 = -++ -static bool testSATCapsulePoly(const CapsuleV& capsule, const PolygonalData& polyData, SupportLocal* map, const FloatVArg contactDist, FloatV& minOverlap, Vec3V& separatingAxis) +static bool testSATCapsulePoly(const CapsuleV& capsule, const PolygonalData& polyData, const SupportLocal* map, const FloatVArg contactDist, FloatV& minOverlap, Vec3V& separatingAxis) { using namespace aos; FloatV _minOverlap = FMax();//minOverlap; @@ -219,10 +219,9 @@ static bool testSATCapsulePoly(const CapsuleV& capsule, const PolygonalData& pol return true; } -static void generatedCapsuleBoxFaceContacts(const CapsuleV& capsule, PolygonalData& polyData, const HullPolygonData& referencePolygon, SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, +static void generatedCapsuleBoxFaceContacts(const CapsuleV& capsule, const PolygonalData& polyData, const HullPolygonData& referencePolygon, const SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, const FloatVArg contactDist, const Vec3VArg normal) { - const FloatV radius = FAdd(capsule.radius, contactDist); //calculate the intersect point of ray to plane @@ -285,7 +284,7 @@ static void generatedCapsuleBoxFaceContacts(const CapsuleV& capsule, PolygonalD } } -static void generatedFaceContacts(const CapsuleV& capsule, PolygonalData& polyData, SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, +static void generatedFaceContacts(const CapsuleV& capsule, const PolygonalData& polyData, const SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, const FloatVArg contactDist, const Vec3VArg normal) { using namespace aos; @@ -362,10 +361,9 @@ static void generateEE(const Vec3VArg p, const Vec3VArg q, const Vec3VArg normal } } -static void generatedContactsEEContacts(const CapsuleV& capsule, PolygonalData& polyData, const HullPolygonData& referencePolygon, SupportLocal* map, const PxMatTransformV& aToB, +static void generatedContactsEEContacts(const CapsuleV& capsule, const PolygonalData& polyData, const HullPolygonData& referencePolygon, const SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, const FloatVArg contactDist, const Vec3VArg contactNormal) { - const PxU8* inds = polyData.mPolygonVertexRefs + referencePolygon.mVRef8; Vec3V* points0In0 = reinterpret_cast(PxAllocaAligned(sizeof(Vec3V)*referencePolygon.mNbVerts, 16)); @@ -381,8 +379,8 @@ static void generatedContactsEEContacts(const CapsuleV& capsule, PolygonalData& } } -bool physx::Gu::generateCapsuleBoxFullContactManifold(const CapsuleV& capsule, PolygonalData& polyData, SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, - const FloatVArg contactDist, Vec3V& normal, const Vec3VArg closest, const PxReal margin, const bool doOverlapTest, const PxReal toleranceScale, PxRenderOutput* renderOutput) +bool physx::Gu::generateCapsuleBoxFullContactManifold(const CapsuleV& capsule, const PolygonalData& polyData, const SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, + const FloatVArg contactDist, Vec3V& normal, const Vec3VArg closest, PxReal margin, bool doOverlapTest, PxReal toleranceScale, PxRenderOutput* renderOutput) { PX_UNUSED(renderOutput); const PxU32 originalContacts = numContacts; @@ -425,8 +423,8 @@ bool physx::Gu::generateCapsuleBoxFullContactManifold(const CapsuleV& capsule, P } //capsule is in the local space of polyData -bool physx::Gu::generateFullContactManifold(const CapsuleV& capsule, PolygonalData& polyData, SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, - const FloatVArg contactDist, Vec3V& normal, const Vec3VArg closest, const PxReal margin, const bool doOverlapTest, const PxReal toleranceLength) +bool physx::Gu::generateFullContactManifold(const CapsuleV& capsule, const PolygonalData& polyData, const SupportLocal* map, const PxMatTransformV& aToB, PersistentContact* manifoldContacts, PxU32& numContacts, + const FloatVArg contactDist, Vec3V& normal, const Vec3VArg closest, PxReal margin, bool doOverlapTest, PxReal toleranceLength) { const PxU32 originalContacts = numContacts; @@ -473,8 +471,8 @@ bool physx::Gu::generateFullContactManifold(const CapsuleV& capsule, PolygonalDa } //sphere is in the local space of polyData, we treate sphere as capsule -bool physx::Gu::generateSphereFullContactManifold(const CapsuleV& capsule, PolygonalData& polyData, SupportLocal* map, PersistentContact* manifoldContacts, PxU32& numContacts, - const FloatVArg contactDist, Vec3V& normal, const bool doOverlapTest) +bool physx::Gu::generateSphereFullContactManifold(const CapsuleV& capsule, const PolygonalData& polyData, const SupportLocal* map, PersistentContact* manifoldContacts, PxU32& numContacts, + const FloatVArg contactDist, Vec3V& normal, bool doOverlapTest) { if(doOverlapTest) { @@ -502,7 +500,7 @@ bool physx::Gu::generateSphereFullContactManifold(const CapsuleV& capsule, Polyg } //capsule is in the shape space of polyData -bool physx::Gu::computeMTD(const CapsuleV& capsule, PolygonalData& polyData, SupportLocal* map, FloatV& penDepth, Vec3V& normal) +bool physx::Gu::computeMTD(const CapsuleV& capsule, const PolygonalData& polyData, const SupportLocal* map, FloatV& penDepth, Vec3V& normal) { const FloatV contactDist = FZero(); Vec3V separatingAxis; diff --git a/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.cpp b/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.cpp index a0d05a91c..e282aa46b 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.cpp @@ -32,7 +32,7 @@ using namespace physx; using namespace Gu; using namespace aos; -bool physx::Gu::contains(aos::Vec3V* verts, const PxU32 numVerts, const aos::Vec3VArg p, const aos::Vec3VArg min, const aos::Vec3VArg max) +bool physx::Gu::contains(aos::Vec3V* verts, PxU32 numVerts, const aos::Vec3VArg p, const aos::Vec3VArg min, const aos::Vec3VArg max) { const BoolV tempCon = BOr(V3IsGrtr(min, p), V3IsGrtr(p, max)); const BoolV con = BOr(BGetX(tempCon), BGetY(tempCon)); @@ -102,7 +102,7 @@ bool physx::Gu::contains(aos::Vec3V* verts, const PxU32 numVerts, const aos::Vec return intersectionPoints> 0; } -PxI32 physx::Gu::getPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal* map, const aos::Vec3VArg normal, PxI32& polyIndex2) +PxI32 physx::Gu::getPolygonIndex(const Gu::PolygonalData& polyData, const SupportLocal* map, const aos::Vec3VArg normal, PxI32& polyIndex2) { //normal is in shape space, need to transform the vertex space const Vec3V n = M33TrnspsMulV3(map->vertex2Shape, normal); @@ -133,6 +133,8 @@ PxI32 physx::Gu::getPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal PxU32 closestEdge = 0xffffffff; FloatV maxDpSq = FMul(minProj, minProj); + FloatV maxDpSq2 = FLoad(-10.0f); + for (PxU32 i = 0; i < numEdges; ++i)//, inc = VecI32V_Add(inc, vOne)) { const PxU32 index = i * 2; @@ -149,6 +151,15 @@ PxI32 physx::Gu::getPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal const FloatV dp = V3Dot(edgeNormal, nnormal);//edgeNormal.dot(normal); const FloatV sqDp = FMul(dp, dp); + if(f0==closestFaceIndex || f1==closestFaceIndex) + { + if(BAllEqTTTT(FIsGrtrOrEq(sqDp, maxDpSq2))) + { + maxDpSq2 = sqDp; + polyIndex2 = f0==closestFaceIndex ? PxI32(f1) : PxI32(f0); + } + } + const BoolV con0 = FIsGrtrOrEq(dp, zero); const BoolV con1 = FIsGrtr(sqDp, FMul(maxDpSq, enMagSq)); const BoolV con = BAnd(con0, con1); @@ -187,8 +198,8 @@ PxI32 physx::Gu::getPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal return closestFaceIndex; } -PxU32 physx::Gu::getWitnessPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal* map, const aos::Vec3VArg normal, - const aos::Vec3VArg closest, const PxReal tolerance) +PxU32 physx::Gu::getWitnessPolygonIndex(const Gu::PolygonalData& polyData, const SupportLocal* map, const aos::Vec3VArg normal, + const aos::Vec3VArg closest, PxReal tolerance) { PxReal pd[256]; //first pass : calculate the smallest distance from the closest point to the polygon face diff --git a/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.h b/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.h index 3d2ab6245..a5ce8f31c 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.h +++ b/physx/source/geomutils/src/pcm/GuPCMContactGenUtil.h @@ -50,7 +50,7 @@ namespace Gu EDGE }; - bool contains(aos::Vec3V* verts, const PxU32 numVerts, const aos::Vec3VArg p, const aos::Vec3VArg min, const aos::Vec3VArg max); + bool contains(aos::Vec3V* verts, PxU32 numVerts, const aos::Vec3VArg p, const aos::Vec3VArg min, const aos::Vec3VArg max); PX_FORCE_INLINE aos::FloatV signed2DTriArea(const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c) { @@ -64,9 +64,9 @@ namespace Gu return FSub(t0, t1); } - PxI32 getPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal* map, const aos::Vec3VArg normal, PxI32& polyIndex2); + PxI32 getPolygonIndex(const Gu::PolygonalData& polyData, const SupportLocal* map, const aos::Vec3VArg normal, PxI32& polyIndex2); - PX_FORCE_INLINE PxI32 getPolygonIndex(const Gu::PolygonalData& polyData, SupportLocal* map, const aos::Vec3VArg normal) + PX_FORCE_INLINE PxI32 getPolygonIndex(const Gu::PolygonalData& polyData, const SupportLocal* map, const aos::Vec3VArg normal) { using namespace aos; @@ -74,8 +74,8 @@ namespace Gu return getPolygonIndex(polyData, map, normal, index2); } - PxU32 getWitnessPolygonIndex( const Gu::PolygonalData& polyData, SupportLocal* map, const aos::Vec3VArg normal, - const aos::Vec3VArg closest, const PxReal tolerance); + PxU32 getWitnessPolygonIndex( const Gu::PolygonalData& polyData, const SupportLocal* map, const aos::Vec3VArg normal, + const aos::Vec3VArg closest, PxReal tolerance); }//Gu }//physx diff --git a/physx/source/geomutils/src/pcm/GuPCMContactPlaneBox.cpp b/physx/source/geomutils/src/pcm/GuPCMContactPlaneBox.cpp index 600bab35d..0f0106204 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactPlaneBox.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactPlaneBox.cpp @@ -157,7 +157,7 @@ bool Gu::pcmContactPlaneBox(GU_CONTACT_METHOD_ARGS) { const FloatV pen = FAdd(s4, px); //(-x, y, z) - const Vec3V p =V3Merge(nbx, by, bz); + const Vec3V p = V3Merge(nbx, by, bz); manifoldContacts[numContacts].mLocalPointA = p; manifoldContacts[numContacts].mLocalPointB = V3NegScaleSub(localNormal, pen, aToB.transform(p)); manifoldContacts[numContacts++].mLocalNormalPen = V4SetW(Vec4V_From_Vec3V(localNormal), pen); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactSphereCapsule.cpp b/physx/source/geomutils/src/pcm/GuPCMContactSphereCapsule.cpp index de7cc1a11..5f1c9b526 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactSphereCapsule.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactSphereCapsule.cpp @@ -62,7 +62,7 @@ bool Gu::pcmContactSphereCapsule(GU_CONTACT_METHOD_ARGS) const PxCapsuleGeometry& shapeCapsule = checkedCast(shape1); //Sphere in world space - const Vec3V sphereCenter = V3LoadA(&transform0.p.x); + const Vec3V sphereCenter = V3LoadA(&transform0.p.x); const QuatV q1 = QuatVLoadA(&transform1.q.x); const Vec3V p1 = V3LoadA(&transform1.p.x); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactSphereConvex.cpp b/physx/source/geomutils/src/pcm/GuPCMContactSphereConvex.cpp index ce26d9e46..e4960fb26 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactSphereConvex.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactSphereConvex.cpp @@ -63,7 +63,7 @@ static bool fullContactsGenerationSphereConvex(const Gu::CapsuleV& capsule, cons Gu::PolygonalData polyData; getPCMConvexData(convexHull,idtScale, polyData); - PxU8 buff[sizeof(SupportLocalImpl)]; + PX_ALIGN(16, PxU8 buff[sizeof(SupportLocalImpl)]); SupportLocal* map = (idtScale ? static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(static_cast(convexHull), transf1, convexHull.vertex2Shape, convexHull.shape2Vertex, idtScale)) : static_cast(PX_PLACEMENT_NEW(buff, SupportLocalImpl)(convexHull, transf1, convexHull.vertex2Shape, convexHull.shape2Vertex, idtScale))); diff --git a/physx/source/geomutils/src/pcm/GuPCMContactSphereSphere.cpp b/physx/source/geomutils/src/pcm/GuPCMContactSphereSphere.cpp index d250c8357..1d5ecd69d 100644 --- a/physx/source/geomutils/src/pcm/GuPCMContactSphereSphere.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMContactSphereSphere.cpp @@ -41,9 +41,9 @@ bool Gu::pcmContactSphereSphere(GU_CONTACT_METHOD_ARGS) const PxSphereGeometry& shapeSphere0 = checkedCast(shape0); const PxSphereGeometry& shapeSphere1 = checkedCast(shape1); - const FloatV cDist = FLoad(params.mContactDistance); - const Vec3V p0 = V3LoadA(&transform0.p.x); - const Vec3V p1 = V3LoadA(&transform1.p.x); + const FloatV cDist = FLoad(params.mContactDistance); + const Vec3V p0 = V3LoadA(&transform0.p.x); + const Vec3V p1 = V3LoadA(&transform1.p.x); const FloatV r0 = FLoad(shapeSphere0.radius); const FloatV r1 = FLoad(shapeSphere1.radius); @@ -55,7 +55,7 @@ bool Gu::pcmContactSphereSphere(GU_CONTACT_METHOD_ARGS) if(FAllGrtr(FMul(inflatedSum, inflatedSum), distanceSq)) { - const FloatV eps = FLoad(0.00001f); + const FloatV eps = FLoad(0.00001f); const FloatV dist = FSqrt(distanceSq); const BoolV bCon = FIsGrtrOrEq(eps, dist); const Vec3V normal = V3Sel(bCon, V3UnitX(), V3ScaleInv(_delta, dist)); diff --git a/physx/source/geomutils/src/pcm/GuPCMTriangleContactGen.cpp b/physx/source/geomutils/src/pcm/GuPCMTriangleContactGen.cpp index 6347872e1..68e146e2b 100644 --- a/physx/source/geomutils/src/pcm/GuPCMTriangleContactGen.cpp +++ b/physx/source/geomutils/src/pcm/GuPCMTriangleContactGen.cpp @@ -46,14 +46,12 @@ using namespace aos; namespace physx { - static bool testPolyFaceNormal(const Gu::TriangleV& triangle, const PolygonalData& polyData, SupportLocalImpl* triMap, SupportLocal* polyMap, const FloatVArg contactDist, - FloatV& minOverlap, PxU32& feature, Vec3V& faceNormal, const FeatureStatus faceStatus, FeatureStatus& status) + static bool testPolyFaceNormal(const PolygonalData& polyData, const SupportLocalImpl* triMap, const SupportLocal* polyMap, const FloatVArg contactDist, + FloatV& minOverlap, PxU32& feature, Vec3V& faceNormal, FeatureStatus faceStatus, FeatureStatus& status) { - PX_UNUSED(triangle); - FloatV _minOverlap = FMax(); - PxU32 _feature = 0; - Vec3V _faceNormal = faceNormal; + PxU32 _feature = 0; + Vec3V _faceNormal = faceNormal; FloatV min0, max0; FloatV min1, max1; const FloatV eps = FEps(); @@ -93,7 +91,6 @@ namespace physx } else { - //in the local space of polyData0 for(PxU32 i=0; i* triMap, SupportLocal* polyMap, const FloatVArg contactDist, - FloatV& minOverlap, PxU32& feature, Vec3V& faceNormal, const FeatureStatus faceStatus, FeatureStatus& status) + static bool testTriangleFaceNormal(const TriangleV& triangle, const PolygonalData& /*polyData*/, const SupportLocalImpl* /*triMap*/, const SupportLocal* polyMap, const FloatVArg contactDist, + FloatV& minOverlap, PxU32& feature, Vec3V& faceNormal, FeatureStatus faceStatus, FeatureStatus& status) { - PX_UNUSED(triMap); - PX_UNUSED(polyData); - FloatV min1, max1; const FloatV eps = FEps(); @@ -176,13 +167,11 @@ namespace physx faceNormal=triangleLocNormal; return true; - } - static bool testPolyEdgeNormal(const TriangleV& triangle, const PxU8 triFlags, const PolygonalData& polyData, SupportLocalImpl* triMap, SupportLocal* polyMap, const FloatVArg contactDist, - FloatV& minOverlap, Vec3V& minNormal, const FeatureStatus edgeStatus, FeatureStatus& status) + static bool testPolyEdgeNormal(const TriangleV& triangle, const PxU8 triFlags, const PolygonalData& polyData, const SupportLocalImpl* triMap, const SupportLocal* polyMap, const FloatVArg contactDist, + FloatV& minOverlap, Vec3V& minNormal, FeatureStatus edgeStatus, FeatureStatus& status) { - PX_UNUSED(triFlags); FloatV overlap = minOverlap; FloatV min0, max0; FloatV min1, max1; @@ -193,19 +182,19 @@ namespace physx const Vec3V v1 = M33MulV3(polyMap->shape2Vertex, triangle.verts[1]); const Vec3V v2 = M33MulV3(polyMap->shape2Vertex, triangle.verts[2]); - TriangleV vertexSpaceTriangle(v0, v1, v2); + const TriangleV vertexSpaceTriangle(v0, v1, v2); PxU32 nbTriangleAxes = 0; Vec3V triangleAxes[3]; for(PxI8 kStart = 0, kEnd =2; kStart<3; kEnd = kStart++) { - bool active = (triFlags & (1 << (kEnd+3))) != 0; + const bool active = (triFlags & (1 << (kEnd+3))) != 0; if(active) { const Vec3V p00 = vertexSpaceTriangle.verts[kStart]; const Vec3V p01 = vertexSpaceTriangle.verts[kEnd]; - triangleAxes[nbTriangleAxes++] = V3Sub(p01, p00); + triangleAxes[nbTriangleAxes++] = V3Sub(p01, p00); } } @@ -236,7 +225,6 @@ namespace physx for (PxU32 j = 0; j < nbTriangleAxes; ++j) { - const Vec3V currentPolyEdge = triangleAxes[j]; const Vec3V v = V3Cross(convexEdge, currentPolyEdge); @@ -268,21 +256,16 @@ namespace physx minNormal = V3Neg(n0); status = edgeStatus; } - } } - } } minOverlap = overlap; return true; - } #if BRUTE_FORCE_EDGE_EDGE - - bool testPolyEdgeNormalBruteForce(const TriangleV& triangle, const PxU8 triFlags, const PolygonalData& polyData, SupportLocalImpl* triMap, SupportLocal* polyMap, const FloatVArg contactDist, FloatV& minOverlap, Vec3V& minNormal, const FeatureStatus edgeStatus, FeatureStatus& status) { @@ -321,7 +304,6 @@ namespace physx for (PxI8 kEnd = 0, kStart = 2; kEnd<3; kStart = kEnd++) { - const Vec3V triVert0 = triangle.verts[kStart]; const Vec3V triVert1 = triangle.verts[kEnd]; @@ -350,7 +332,6 @@ namespace physx bestTriStart = kStart; bestTriEnd = kEnd; } - } } } @@ -364,13 +345,11 @@ namespace physx } return true; - } bool testPolyEdgeNormalBruteForceVertsByEdges(const TriangleV& triangle, const PxU8 triFlags, const PolygonalData& polyData, SupportLocalImpl* triMap, SupportLocal* polyMap, const FloatVArg contactDist, FloatV& minOverlap, Vec3V& minNormal, const FeatureStatus edgeStatus, FeatureStatus& status, PxU32& bestEdgeIndex, PxI8& bestTriStart, PxI8& bestTriEnd) { - PX_UNUSED(triFlags); const PxU32 numConvexEdges = polyData.mNbEdges; @@ -392,7 +371,6 @@ namespace physx Vec3V convexEdge = V3Sub(vertex11, vertex10); - for (PxI8 kEnd = 0, kStart = 2; kEnd<3; kStart = kEnd++) { const Vec3V triVert0 = triangle.verts[kStart]; @@ -433,7 +411,6 @@ namespace physx } } } - } if (FAllGrtr(minOverlap, bestDist)) @@ -444,19 +421,13 @@ namespace physx } return true; - } - #endif #if EDGE_EDGE_GAUSS_MAP - - - bool isMinkowskiFace(const Vec3V& A, const Vec3V& B, const Vec3V& B_x_A, const Vec3V& C, const Vec3V& D, const Vec3V& D_x_C) { - const FloatV zero = FZero(); // Two edges build a face on the Minkowski sum if the associated arcs AB and CD intersect on the Gauss map. // The associated arcs are defined by the adjacent face normals of each edge. @@ -497,9 +468,8 @@ namespace physx Vec3V bestAxis = V3Zero(); const Vec3V eps2 = V3Splat(FLoad(1e-6)); - //Center is in shape space - const Vec3V shapeSpaceCOM =V3LoadU(polyData.mCenter); + const Vec3V shapeSpaceCOM = V3LoadU(polyData.mCenter); const Vec3V vertexSpaceCOM = M33MulV3(polyMap->shape2Vertex, shapeSpaceCOM); PxVec3 vertexCOM; @@ -507,7 +477,6 @@ namespace physx for (PxU32 convexEdgeIdx = 0; convexEdgeIdx < numConvexEdges; ++convexEdgeIdx) { - const PxU16 v0idx1 = verticesByEdges16[convexEdgeIdx*2]; const PxU32 v1idx1 = verticesByEdges16[convexEdgeIdx * 2 + 1]; @@ -533,8 +502,7 @@ namespace physx PX_ASSERT(signDist1 < 0.f); for (PxI8 kEnd = 0, kStart = 2; kEnd<3; kStart = kEnd++) - { - + { const Vec3V triVert0 = triangle.verts[kStart]; const Vec3V triVert1 = triangle.verts[kEnd]; const Vec3V triEdge = V3Sub(triVert1, triVert0); @@ -542,7 +510,6 @@ namespace physx //if (isMinkowskiFace(convexNormal0, convexNormal1, V3Neg(convexEdge), V3Neg(triNormal), triNormal, V3Neg(triEdge))) if (isMinkowskiFace(convexNormal0, convexNormal1, convexEdge, V3Neg(triNormal), triNormal, triEdge)) { - // compute the separation along this axis in vertex space axis = V3Cross(convexEdge, triEdge); @@ -564,7 +531,6 @@ namespace physx if (FAllGrtr(dist, contactDist)) return false; - #if SAT_VARIFY FloatV min0, max0; FloatV min1, max1; @@ -586,9 +552,7 @@ namespace physx const FloatV dif = FAbs(FAdd(tempDist, dist)); PX_UNUSED(dif); PX_ASSERT(FAllGrtr(FLoad(1e-4f), dif)); - #endif - if (FAllGrtr(dist, bestDist)) { bestDist = dist; @@ -601,7 +565,6 @@ namespace physx } } } - } if (FAllGrtr(minOverlap, bestDist)) @@ -611,12 +574,10 @@ namespace physx status = edgeStatus; } return true; - } - #endif - static PX_FORCE_INLINE PxU32 addMeshContacts(MeshPersistentContact* manifoldContacts, const Vec3V& pA, const Vec3V& pB, const Vec4V& normalPen, const PxU32 triangleIndex, const PxU32 numContacts) + static PX_FORCE_INLINE PxU32 addMeshContacts(MeshPersistentContact* manifoldContacts, const Vec3V& pA, const Vec3V& pB, const Vec4V& normalPen, PxU32 triangleIndex, PxU32 numContacts) { manifoldContacts[numContacts].mLocalPointA = pA; manifoldContacts[numContacts].mLocalPointB = pB; @@ -625,13 +586,10 @@ namespace physx return numContacts+1; } - - static void generatedTriangleContacts(const Gu::TriangleV& triangle, const PxU32 triangleIndex, const PxU8/* _triFlags*/, const Gu::PolygonalData& polyData1, const Gu::HullPolygonData& incidentPolygon, Gu::SupportLocal* map1, Gu::MeshPersistentContact* manifoldContacts, PxU32& numManifoldContacts, + static void generatedTriangleContacts(const Gu::TriangleV& triangle, PxU32 triangleIndex, PxU8/* _triFlags*/, const Gu::PolygonalData& polyData1, const Gu::HullPolygonData& incidentPolygon, const Gu::SupportLocal* map1, Gu::MeshPersistentContact* manifoldContacts, PxU32& numManifoldContacts, const aos::FloatVArg contactDist, const aos::Vec3VArg contactNormal, PxRenderOutput* renderOutput) { - PX_UNUSED(renderOutput); - using namespace aos; //PxU8 triFlags = _triFlags; const PxU32 previousContacts = numManifoldContacts; @@ -646,14 +604,11 @@ namespace physx Vec3V* points1In0 = reinterpret_cast(PxAllocaAligned(sizeof(Vec3V)*incidentPolygon.mNbVerts, 16)); FloatV* points1In0TValue = reinterpret_cast(PxAllocaAligned(sizeof(FloatV)*incidentPolygon.mNbVerts, 16)); bool* points1In0Penetration = reinterpret_cast(PxAlloca(sizeof(bool)*incidentPolygon.mNbVerts)); - points0In0[0] = triangle.verts[0]; points0In0[1] = triangle.verts[1]; points0In0[2] = triangle.verts[2]; - - //Transform all the verts from vertex space to shape space map1->populateVerts(inds1, incidentPolygon.mNbVerts, polyData1.mVerts, points1In0); @@ -676,7 +631,6 @@ namespace physx rPolygonMax = V3Max(rPolygonMax, points0In0[i]); } - rPolygonMin = V3Sub(rPolygonMin, eps); rPolygonMax = V3Add(rPolygonMax, eps); @@ -686,7 +640,6 @@ namespace physx Vec3V iPolygonMin= max; Vec3V iPolygonMax = nmax; - PxU32 inside = 0; for(PxU32 i=0; ipopulateVerts(inds0, referencePolygon.mNbVerts, polyData0.mVerts, points0In0); @@ -916,8 +852,6 @@ namespace physx rPolygonMin = V3Sub(rPolygonMin, eps); rPolygonMax = V3Add(rPolygonMax, eps); - - const FloatV d = V3GetZ(points0In0[0]); @@ -963,14 +897,10 @@ namespace physx } } } - } - if(inside == 3) - { return; - } inside = 0; iPolygonMin = V3Sub(iPolygonMin, eps); @@ -983,7 +913,6 @@ namespace physx { if(contains(points1In0, 3, points0In0[i], iPolygonMin, iPolygonMax)) { - const Vec3V vert0 = M33TrnspsMulV3(rot, points0In0[i]); const FloatV t =FSub(V3Dot(incidentNormal, vert0), iPlaneD); @@ -1017,15 +946,11 @@ namespace physx numManifoldContacts = previousContacts + GU_SINGLE_MANIFOLD_SINGLE_POLYGONE_CACHE_SIZE; } } - } - } if(inside == referencePolygon.mNbVerts) return; - - //Always generate segment contacts //(2) segment intesection @@ -1042,7 +967,6 @@ namespace physx for (PxU32 rStart = 0, rEnd = PxU32(referencePolygon.mNbVerts - 1); rStart < referencePolygon.mNbVerts; rEnd = rStart++) { - const Vec3V rpA = points0In0[rStart]; const Vec3V rpB = points0In0[rEnd]; @@ -1054,20 +978,17 @@ namespace physx if(BAllEqTTTT(con)) continue; - - FloatV a1 = signed2DTriArea(rpA, rpB, ipA); - FloatV a2 = signed2DTriArea(rpA, rpB, ipB); - + const FloatV a1 = signed2DTriArea(rpA, rpB, ipA); + const FloatV a2 = signed2DTriArea(rpA, rpB, ipB); if(FAllGrtr(zero, FMul(a1, a2))) { - FloatV a3 = signed2DTriArea(ipA, ipB, rpA); - FloatV a4 = signed2DTriArea(ipA, ipB, rpB); + const FloatV a3 = signed2DTriArea(ipA, ipB, rpA); + const FloatV a4 = signed2DTriArea(ipA, ipB, rpB); if(FAllGrtr(zero, FMul(a3, a4))) { - //these two segment intersect const FloatV t = FMul(a1, FRecip(FSub(a2, a1))); @@ -1082,7 +1003,6 @@ namespace physx if(FAllGrtr(pen, contactDist)) continue; - const Vec4V localNormalPen = V4SetW(Vec4V_From_Vec3V(nContactNormal), pen); numManifoldContacts = addMeshContacts(manifoldContacts, pA, pB, localNormalPen, triangleIndex, numManifoldContacts); @@ -1100,34 +1020,26 @@ namespace physx } } } - } - - bool Gu::PCMConvexVsMeshContactGeneration::generateTriangleFullContactManifold(Gu::TriangleV& localTriangle, const PxU32 triangleIndex, const PxU32* triIndices, const PxU8 triFlags, const Gu::PolygonalData& polyData, Gu::SupportLocalImpl* localTriMap, Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, + bool Gu::PCMConvexVsMeshContactGeneration::generateTriangleFullContactManifold(const Gu::TriangleV& localTriangle, PxU32 triangleIndex, const PxU32* triIndices, PxU8 triFlags, const Gu::PolygonalData& polyData, const Gu::SupportLocalImpl* localTriMap, const Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal) { - - using namespace aos; - { - FeatureStatus status = POLYDATA0; FloatV minOverlap = FMax(); //minNormal will be in the local space of polyData Vec3V minNormal = V3Zero(); - PxU32 feature0; if(!testTriangleFaceNormal(localTriangle, polyData, localTriMap, polyMap, contactDist, minOverlap, feature0, minNormal, POLYDATA0, status)) return false; PxU32 feature1; - if(!testPolyFaceNormal(localTriangle, polyData, localTriMap, polyMap, contactDist, minOverlap, feature1, minNormal, POLYDATA1, status)) + if(!testPolyFaceNormal(polyData, localTriMap, polyMap, contactDist, minOverlap, feature1, minNormal, POLYDATA1, status)) return false; - - if (!testPolyEdgeNormal(localTriangle, triFlags, polyData, localTriMap, polyMap, contactDist, minOverlap, minNormal, EDGE, status)) + if(!testPolyEdgeNormal(localTriangle, triFlags, polyData, localTriMap, polyMap, contactDist, minOverlap, minNormal, EDGE, status)) return false; const Vec3V triNormal = localTriangle.normal(); @@ -1147,11 +1059,9 @@ namespace physx { generatedTriangleContacts(localTriangle, triangleIndex, triFlags, polyData, polyData.mPolygons[index2], polyMap, manifoldContacts, numContacts, contactDist, triNormal, mRenderOutput); } - } else { - if(status == POLYDATA1) { const Gu::HullPolygonData* referencePolygon = &polyData.mPolygons[feature1]; @@ -1211,17 +1121,12 @@ namespace physx return true; } - - bool Gu::PCMConvexVsMeshContactGeneration::generateTriangleFullContactManifold(Gu::TriangleV& localTriangle, const PxU32 triangleIndex, const PxU8 triFlags, const Gu::PolygonalData& polyData, Gu::SupportLocalImpl* localTriMap, Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, + bool Gu::PCMConvexVsMeshContactGeneration::generateTriangleFullContactManifold(const Gu::TriangleV& localTriangle, PxU32 triangleIndex, PxU8 triFlags, const Gu::PolygonalData& polyData, const Gu::SupportLocalImpl* localTriMap, const Gu::SupportLocal* polyMap, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal, PxRenderOutput* renderOutput) { - - using namespace aos; - const FloatV threshold = FLoad(0.7071f);//about 45 degree PX_UNUSED(threshold); { - FeatureStatus status = POLYDATA0; FloatV minOverlap = FMax(); //minNormal will be in the local space of polyData @@ -1232,7 +1137,7 @@ namespace physx return false; PxU32 feature1; - if(!testPolyFaceNormal(localTriangle, polyData, localTriMap, polyMap, contactDist, minOverlap, feature1, minNormal, POLYDATA1, status)) + if(!testPolyFaceNormal(polyData, localTriMap, polyMap, contactDist, minOverlap, feature1, minNormal, POLYDATA1, status)) return false; if(!testPolyEdgeNormal(localTriangle, triFlags, polyData, localTriMap, polyMap, contactDist, minOverlap, minNormal, EDGE, status)) @@ -1243,17 +1148,13 @@ namespace physx const Gu::HullPolygonData* referencePolygon = &polyData.mPolygons[getPolygonIndex(polyData, polyMap, triNormal)]; generatedTriangleContacts(localTriangle, triangleIndex, triFlags, polyData, *referencePolygon, polyMap, manifoldContacts, numContacts, contactDist, triNormal, renderOutput); - } return true; } - bool Gu::PCMConvexVsMeshContactGeneration::generatePolyDataContactManifold(Gu::TriangleV& localTriangle, const PxU32 featureIndex, const PxU32 triangleIndex, const PxU8 triFlags, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal) + bool Gu::PCMConvexVsMeshContactGeneration::generatePolyDataContactManifold(const Gu::TriangleV& localTriangle, PxU32 featureIndex, PxU32 triangleIndex, PxU8 triFlags, Gu::MeshPersistentContact* manifoldContacts, PxU32& numContacts, const aos::FloatVArg contactDist, aos::Vec3V& patchNormal) { - - using namespace aos; - const Gu::HullPolygonData* referencePolygon = &mPolyData.mPolygons[featureIndex]; const Vec3V contactNormal = V3Normalize(M33TrnspsMulV3(mPolyMap->shape2Vertex, V3LoadU(referencePolygon->mPlane.n))); @@ -1265,5 +1166,4 @@ namespace physx return true; } - }//physx diff --git a/physx/source/geomutils/src/pcm/GuPersistentContactManifold.cpp b/physx/source/geomutils/src/pcm/GuPersistentContactManifold.cpp index 499ef4776..8c9d49b55 100644 --- a/physx/source/geomutils/src/pcm/GuPersistentContactManifold.cpp +++ b/physx/source/geomutils/src/pcm/GuPersistentContactManifold.cpp @@ -35,18 +35,16 @@ #include "GuGJKUtil.h" using namespace physx; +using namespace aos; namespace physx { namespace Gu { -/* - This local function is to avoid DLL call -*/ +// This local function is to avoid DLL call static aos::FloatV distancePointSegmentSquaredLocal(const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg p) { - using namespace aos; const FloatV zero = FZero(); const FloatV one = FOne(); @@ -62,16 +60,12 @@ static aos::FloatV distancePointSegmentSquaredLocal(const aos::Vec3VArg a, const return V3Dot(v, v); } -/* - This local function is to avoid DLL call -*/ +// This local function is to avoid DLL call static aos::FloatV distancePointTriangleSquaredLocal( const aos::Vec3VArg p, const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c) { - using namespace aos; - const FloatV zero = FZero(); //const Vec3V zero = V3Zero(); const Vec3V ab = V3Sub(b, a); @@ -175,9 +169,6 @@ static aos::FloatV distancePointTriangleSquaredLocal( const aos::Vec3VArg p, return V3Dot(vv, vv); } - - - //This is the translational threshold used in invalidate_BoxConvexHull. 0.5 is 50% of the object margin. we use different threshold between //0 and 4 points. This threashold is a scale that is multiplied by the objects' margins. const PxF32 invalidateThresholds[5] = { 0.5f, 0.125f, 0.25f, 0.375f, 0.375f }; @@ -191,11 +182,9 @@ const PxF32 invalidateThresholds2[3] = { 0.5f, 0.1f, 0.75f }; //between previous and current frame const PxF32 invalidateQuatThresholds[5] = { 0.9998f, 0.9999f, 0.9999f, 0.9999f, 0.9999f }; - //This is the rotational threshold used in invalidate_SphereCapsule. 0.9995f is a threshold for quat difference //between previous and current frame const PxF32 invalidateQuatThresholds2[3] = { 0.9995f, 0.9999f, 0.9997f }; - } } @@ -207,7 +196,6 @@ static void drawManifoldPoint(const Gu::PersistentContact& manifold, const aos: { PX_UNUSED(color); - using namespace aos; const Vec3V worldA = trA.transform(manifold.mLocalPointA); const Vec3V worldB = trB.transform(manifold.mLocalPointB); const Vec3V localNormal = Vec3V_From_Vec4V(manifold.mLocalNormalPen); @@ -249,15 +237,12 @@ static void drawManifoldPoint(const Gu::PersistentContact& manifold, const aos: const PxVec3 c = a - v*10.f; out << 0xffff00ff << a << c; - } static void drawManifoldPoint(const Gu::PersistentContact& manifold, const aos::PxTransformV& trA, const aos::PxTransformV& trB, const aos::FloatVArg radius, PxRenderOutput& out, PxU32 color=0xffffff) { PX_UNUSED(color); - using namespace aos; - const Vec3V localNormal = Vec3V_From_Vec4V(manifold.mLocalNormalPen); const Vec3V worldNormal = trB.rotate(localNormal); const Vec3V worldA = V3NegScaleSub(worldNormal, radius, trA.transform(manifold.mLocalPointA)); @@ -294,23 +279,17 @@ static void drawManifoldPoint(const Gu::PersistentContact& manifold, const aos: out << 0xffff0000 << m << PxRenderOutput::LINES << b + forwards2 << b - forwards2; out << 0xffff0000 << m << PxRenderOutput::LINES << a << b; - } - static PxU32 gColors[8] = { 0xff0000ff, 0xff00ff00, 0xffff0000, 0xff00ffff, 0xffff00ff, 0xffffff00, 0xff000080, 0xff008000}; - #endif -/* - SIMD version -*/ +// SIMD version aos::Mat33V Gu::findRotationMatrixFromZAxis(const aos::Vec3VArg to) { - using namespace aos; - + const FloatV one = FOne(); const FloatV threshold = FLoad(0.9999f); @@ -330,11 +309,9 @@ aos::Mat33V Gu::findRotationMatrixFromZAxis(const aos::Vec3VArg to) const Vec3V col2 = V3Merge(FNeg(vy), vx, e); return Mat33V(col0, col1, col2); - } else { - const FloatV two = FLoad(2.f); const Vec3V from = V3UnitZ(); const Vec3V absFrom = V3UnitY(); @@ -354,7 +331,6 @@ aos::Mat33V Gu::findRotationMatrixFromZAxis(const aos::Vec3VArg to) const Vec3V c2v = V3Scale(v, c2); const Vec3V c3v = V3Scale(v, c3); - FloatV temp0 = V3GetX(c1u); FloatV temp1 = V3GetX(c2v); FloatV temp2 = V3GetX(c3v); @@ -377,16 +353,12 @@ aos::Mat33V Gu::findRotationMatrixFromZAxis(const aos::Vec3VArg to) col2 = V3SetZ(col2, FAdd(V3GetZ(col2), one)); return Mat33V(col0, col1, col2); - } } - void Gu::PersistentContactManifold::drawManifold( PxRenderOutput& out, const aos::PxTransformV& trA, const aos::PxTransformV& trB) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT - PxVec3 a, b; V3StoreU(trA.p, a); V3StoreU(trB.p, b); @@ -405,7 +377,6 @@ void Gu::PersistentContactManifold::drawManifold( PxRenderOutput& out, const aos void Gu::PersistentContactManifold::drawManifold( PxRenderOutput& out, const aos::PxTransformV& trA, const aos::PxTransformV& trB, const aos::FloatVArg radius) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT PxVec3 a, b; @@ -439,7 +410,6 @@ void Gu::PersistentContactManifold::drawManifold(const Gu::PersistentContact& m, void Gu::PersistentContactManifold::drawPoint(PxRenderOutput& out, const aos::Vec3VArg p, const PxF32 size, const PxU32 color) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT const PxVec3 up(0.f, size, 0.f); const PxVec3 right(size, 0.f, 0.f); @@ -463,7 +433,6 @@ void Gu::PersistentContactManifold::drawPoint(PxRenderOutput& out, const aos::Ve void Gu::PersistentContactManifold::drawLine(PxRenderOutput& out, const aos::Vec3VArg p0, const aos::Vec3VArg p1, const PxU32 color) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT PxVec3 a, b; V3StoreU(p0, a); @@ -481,7 +450,6 @@ void Gu::PersistentContactManifold::drawLine(PxRenderOutput& out, const aos::Vec void Gu::PersistentContactManifold::drawTriangle(PxRenderOutput& out, const aos::Vec3VArg p0, const aos::Vec3VArg p1, const aos::Vec3VArg p2, const PxU32 color) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT PxVec3 a, b, c; V3StoreU(p0, a); @@ -502,7 +470,6 @@ void Gu::PersistentContactManifold::drawTriangle(PxRenderOutput& out, const aos: void Gu::PersistentContactManifold::drawTetrahedron(PxRenderOutput& out, const aos::Vec3VArg p0, const aos::Vec3VArg p1, const aos::Vec3VArg p2, const aos::Vec3VArg p3, const PxU32 color) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT PxVec3 a, b, c, d; V3StoreU(p0, a); @@ -517,7 +484,6 @@ void Gu::PersistentContactManifold::drawTetrahedron(PxRenderOutput& out, const a out << color << m << PxRenderOutput::LINES << b << c; out << color << m << PxRenderOutput::LINES << b << d; out << color << m << PxRenderOutput::LINES << c << d; - #else PX_UNUSED(out); PX_UNUSED(p0); @@ -529,7 +495,6 @@ void Gu::PersistentContactManifold::drawTetrahedron(PxRenderOutput& out, const a void Gu::PersistentContactManifold::drawPolygon( PxRenderOutput& out, const aos::PxTransformV& transform, aos::Vec3V* points, const PxU32 numVerts, const PxU32 color) { - using namespace aos; #if VISUALIZE_PERSISTENT_CONTACT for(PxU32 i=0; i 4, we will reduce the contact points to 4 -*/ +// This function is for box/convexhull full contact generation. If the numPoints > 4, we will reduce the contact points to 4 void Gu::PersistentContactManifold::reduceBatchContacts(const PersistentContact* manifoldPoints, const PxU32 numPoints, const PxReal tolereanceLength) { - using namespace aos; - PxU8 chosenIndices[4]; PxU8 candidates[64]; @@ -1205,7 +1117,6 @@ void Gu::PersistentContactManifold::reduceBatchContacts(const PersistentContact* PxU32 index1 = GU_MANIFOLD_INVALID_INDEX; PxU32 candidateIndex1 = GU_MANIFOLD_INVALID_INDEX; - //calculate the min and max point away from the segment for (PxU32 i = 0; i 2, we will reduce the contact points to 2 -*/ + +// This function is for capsule full contact generation. If the numPoints > 2, we will reduce the contact points to 2 void Gu::PersistentContactManifold::reduceBatchContacts2(const PersistentContact* manifoldPoints, const PxU32 numPoints) { - using namespace aos; - PX_ASSERT(numPoints < 64); bool chosen[64]; physx::PxMemZero(chosen, sizeof(bool)*numPoints); @@ -1322,10 +1227,9 @@ void Gu::PersistentContactManifold::reduceBatchContacts2(const PersistentContact } } //keep the deepest points in the first position - mContactPoints[0] = manifoldPoints[index]; + mContactPoints[0] = manifoldPoints[index]; chosen[index] = true; - //calculate the furthest away points Vec3V v = V3Sub(manifoldPoints[0].mLocalPointB, mContactPoints[0].mLocalPointB); maxDis = V3Dot(v, v); @@ -1343,7 +1247,7 @@ void Gu::PersistentContactManifold::reduceBatchContacts2(const PersistentContact } //PX_ASSERT(chosen[index] == false); - mContactPoints[1] = manifoldPoints[index]; + mContactPoints[1] = manifoldPoints[index]; chosen[index] = true; PxI32 secondIndex = index; @@ -1377,8 +1281,6 @@ void Gu::PersistentContactManifold::reduceBatchContacts2(const PersistentContact PxU32 Gu::PersistentContactManifold::addManifoldPoint(const aos::Vec3VArg localPointA, const aos::Vec3VArg localPointB, const aos::Vec4VArg localNormalPen , const aos::FloatVArg replaceBreakingThreshold) { - using namespace aos; - if(replaceManifoldPoint(localPointA, localPointB, localNormalPen, replaceBreakingThreshold)) //replace the new point with the old one return 0; @@ -1396,19 +1298,13 @@ PxU32 Gu::PersistentContactManifold::addManifoldPoint(const aos::Vec3VArg localP default: return reduceContactsForPCM(localPointA, localPointB, localNormalPen);//should be always return zero }; - } - -/* - This function is for capsule vs other primitives. If the manifold originally has contacts and we can incrementally add a point at a time, we will - use this function to add a point to manifold. If the number of contacts inside the manifold is more than 2, we will reduce contacts to 2 points. -*/ +// This function is for capsule vs other primitives. If the manifold originally has contacts and we can incrementally add a point at a time, we will +// use this function to add a point to manifold. If the number of contacts inside the manifold is more than 2, we will reduce contacts to 2 points. PxU32 Gu::PersistentContactManifold::addManifoldPoint2(const aos::Vec3VArg localPointA, const aos::Vec3VArg localPointB, const aos::Vec4VArg localNormalPen , const aos::FloatVArg replaceBreakingThreshold) { - using namespace aos; - if(replaceManifoldPoint(localPointA, localPointB, localNormalPen, replaceBreakingThreshold)) //replace the new point with the old one return 0; @@ -1426,25 +1322,19 @@ PxU32 Gu::PersistentContactManifold::addManifoldPoint2(const aos::Vec3VArg local PX_ASSERT(0); }; return 0; - } -/* - This function is used in the capsule full manifold contact genenation. We will pass in a list of manifold contacts. If the number of contacts are more than - 2, we will need to do contact reduction while we are storing the chosen manifold contacts from the manifold contact list to the manifold contact - buffer. -*/ +// This function is used in the capsule full manifold contact genenation. We will pass in a list of manifold contacts. If the number of contacts are more than +// 2, we will need to do contact reduction while we are storing the chosen manifold contacts from the manifold contact list to the manifold contact buffer. void Gu::PersistentContactManifold::addBatchManifoldContacts2(const PersistentContact* manifoldContacts, const PxU32 numPoints) { - using namespace aos; - if(numPoints <= 2) { for(PxU32 i=0; imStartIndex; jmEndIndex; ++j) { - mContactPoints[tempNumContacts++] = manifoldContact[j]; + mContactPoints[tempNumContacts++] = manifoldContact[j]; } currentPatch = currentPatch->mNextPatch; } @@ -1498,8 +1383,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::addBatchManifoldContactsSphere( { PX_UNUSED(replaceBreakingThreshold); - using namespace aos; - const FloatV maxPen = reduceBatchContactsSphere(manifoldContact, numContactExt, patch); mNumContacts = 1; return maxPen; @@ -1509,8 +1392,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::addBatchManifoldContactsCapsule { PX_UNUSED(replaceBreakingThreshold); - using namespace aos; - if(patch.mTotalSize <=GU_CAPSULE_MANIFOLD_CACHE_SIZE) { PCMContactPatch* currentPatch = &patch; @@ -1530,25 +1411,20 @@ aos::FloatV Gu::SinglePersistentContactManifold::addBatchManifoldContactsCapsule } else { - const FloatV maxPen = reduceBatchContactsCapsule(manifoldContact, numContactExt, patch); mNumContacts = GU_CAPSULE_MANIFOLD_CACHE_SIZE; return maxPen; } - } - aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsSphere(const MeshPersistentContact* manifoldContactExt, const PxU32 numContacts, PCMContactPatch& patch) { PX_UNUSED(numContacts); - using namespace aos; FloatV max = FMax(); FloatV maxDist = max; PxI32 index = -1; - PCMContactPatch* currentPatch = &patch; while(currentPatch) { @@ -1568,13 +1444,10 @@ aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsSphere(const mContactPoints[0] = manifoldContactExt[index]; return maxDist; - } aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsCapsule(const MeshPersistentContact* manifoldContactExt, const PxU32 numContacts, PCMContactPatch& patch) { - using namespace aos; - bool* chosen = reinterpret_cast(PxAlloca(sizeof(bool)*numContacts)); physx::PxMemZero(chosen, sizeof(bool)*numContacts); const FloatV max = FMax(); @@ -1583,7 +1456,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsCapsule(cons FloatV maxPen = max; - PCMContactPatch* currentPatch = &patch; while(currentPatch) { @@ -1603,7 +1475,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsCapsule(cons mContactPoints[0] = manifoldContactExt[index]; maxPen = FMin(maxPen, V4GetW(manifoldContactExt[index].mLocalNormalPen)); - //calculate the furthest away points Vec3V v = V3Sub(manifoldContactExt[patch.mStartIndex].mLocalPointB, mContactPoints[0].mLocalPointB); maxDis = V3Dot(v, v); @@ -1660,8 +1531,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsCapsule(cons aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsConvex(const MeshPersistentContact* manifoldContactExt, const PxU32 numContacts, PCMContactPatch& patch) { - using namespace aos; - bool* chosen = reinterpret_cast(PxAlloca(sizeof(bool)*numContacts)); physx::PxMemZero(chosen, sizeof(bool)*numContacts); const FloatV max = FMax(); @@ -1730,7 +1599,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsConvex(const FloatV minDis = max; PxU32 index1 = GU_MANIFOLD_INVALID_INDEX; - //calculate the point furthest way to the segment currentPatch = &patch; @@ -1846,8 +1714,6 @@ aos::FloatV Gu::SinglePersistentContactManifold::reduceBatchContactsConvex(const PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* manifoldPoints, PxU32 numPoints) { - using namespace aos; - PxU8 chosenIndices[GU_SINGLE_MANIFOLD_SINGLE_POLYGONE_CACHE_SIZE]; PxU8* candidates = reinterpret_cast(PxAlloca(sizeof(PxU8) * numPoints)); @@ -1869,7 +1735,6 @@ PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* if (numPoints <= GU_SINGLE_MANIFOLD_SINGLE_POLYGONE_CACHE_SIZE) return numPoints; - const FloatV max = FMax(); const FloatV nmax = FNeg(max); FloatV maxPen = V4GetW(manifoldPoints[0].mLocalNormalPen); @@ -1923,7 +1788,6 @@ PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* } } - chosenIndices[1] = PxU8(index); //move the chosen indices out of the candidates indices nbCandiates = nbCandiates - 1; @@ -1931,7 +1795,6 @@ PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* newManifold[1] = manifoldPoints[chosenIndices[1]]; - v = V3Sub(newManifold[1].mLocalPointB, newManifold[0].mLocalPointB); const Vec3V cn0 = Vec3V_From_Vec4V(newManifold[0].mLocalNormalPen); Vec3V norm = V3Cross(v, cn0); @@ -1960,7 +1823,6 @@ PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* index1 = candidates[i]; candidateIndex1 = i; } - } chosenIndices[2] = PxU8(index); @@ -2011,7 +1873,6 @@ PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* index = candidates[i]; candidateIndex = i; } - } chosenIndices[4] = PxU8(index); @@ -2021,7 +1882,6 @@ PxU32 Gu::SinglePersistentContactManifold::reduceContacts(MeshPersistentContact* newManifold[4] = manifoldPoints[chosenIndices[4]]; - //copy the new manifold back for (PxU32 i = 0; i 0; } - -/* - This function copies the mesh persistent contact from compress buffer(NpCacheStreamPair in the PxcNpThreadContext) to the multiple manifold -*/ +// This function copies the mesh persistent contact from compress buffer(NpCacheStreamPair in the PxcNpThreadContext) to the multiple manifold // PT: function moved to cpp to go around a compiler bug on PS4 void physx::Gu::MultiplePersistentContactManifold::fromBuffer(PxU8* PX_RESTRICT buffer) { - using namespace aos; PxU32 numManifolds = 0; if (buffer != NULL) { @@ -2449,7 +2280,7 @@ void physx::Gu::MultiplePersistentContactManifold::fromBuffer(PxU8* PX_RESTRICT } else { - mRelativeTransform.Invalidate(); + mRelativeTransform.invalidate(); } mNumManifolds = PxU8(numManifolds); for (PxU32 a = numManifolds; a < GU_MAX_MANIFOLD_SIZE; ++a) @@ -2461,8 +2292,6 @@ void physx::Gu::MultiplePersistentContactManifold::fromBuffer(PxU8* PX_RESTRICT void Gu::addManifoldPoint(Gu::PersistentContact* manifoldContacts, Gu::PersistentContactManifold& manifold, GjkOutput& output, const aos::PxMatTransformV& aToB, const aos::FloatV replaceBreakingThreshold) { - using namespace aos; - const Vec3V localPointA = aToB.transformInv(output.closestA); const Vec4V localNormalPen = V4SetW(Vec4V_From_Vec3V(output.normal), output.penDep); diff --git a/physx/source/geomutils/src/pcm/GuPersistentContactManifold.h b/physx/source/geomutils/src/pcm/GuPersistentContactManifold.h index 86f33a55a..6eae165c6 100644 --- a/physx/source/geomutils/src/pcm/GuPersistentContactManifold.h +++ b/physx/source/geomutils/src/pcm/GuPersistentContactManifold.h @@ -152,7 +152,7 @@ class PersistentContactManifold PersistentContactManifold(PersistentContact* contactPointsBuff, PxU8 capacity): mNumContacts(0), mCapacity(capacity), mNumWarmStartPoints(0), mContactPoints(contactPointsBuff) { using namespace physx::aos; - mRelativeTransform.Invalidate(); + mRelativeTransform.invalidate(); mQuatA = QuatIdentity(); mQuatB = QuatIdentity(); } @@ -322,7 +322,7 @@ class PersistentContactManifold { mNumWarmStartPoints = 0; mNumContacts = 0; - mRelativeTransform.Invalidate(); + mRelativeTransform.invalidate(); } PX_FORCE_INLINE void initialize() @@ -533,7 +533,7 @@ class PX_PHYSX_COMMON_API MultiplePersistentContactManifold public: MultiplePersistentContactManifold():mNumManifolds(0), mNumTotalContacts(0) { - mRelativeTransform.Invalidate(); + mRelativeTransform.invalidate(); } PX_FORCE_INLINE void setRelativeTransform(const aos::PxTransformV& transform) @@ -697,7 +697,7 @@ class PX_PHYSX_COMMON_API MultiplePersistentContactManifold { mNumManifolds = 0; mNumTotalContacts = 0; - mRelativeTransform.Invalidate(); + mRelativeTransform.invalidate(); for(PxU8 i=0; i 0; --i) diff --git a/physx/source/geomutils/src/sweep/GuSweepCapsuleTriangle.cpp b/physx/source/geomutils/src/sweep/GuSweepCapsuleTriangle.cpp index 6ea892336..424b54ae9 100644 --- a/physx/source/geomutils/src/sweep/GuSweepCapsuleTriangle.cpp +++ b/physx/source/geomutils/src/sweep/GuSweepCapsuleTriangle.cpp @@ -29,7 +29,6 @@ #include "GuSweepCapsuleTriangle.h" #include "GuIntersectionCapsuleTriangle.h" #include "GuDistanceSegmentTriangle.h" -#include "GuDistanceSegmentTriangleSIMD.h" #include "GuIntersectionTriangleBox.h" #include "GuSweepSphereTriangle.h" #include "GuInternal.h" diff --git a/physx/source/immediatemode/src/NpImmediateMode.cpp b/physx/source/immediatemode/src/NpImmediateMode.cpp index df38b39ae..8ada35253 100644 --- a/physx/source/immediatemode/src/NpImmediateMode.cpp +++ b/physx/source/immediatemode/src/NpImmediateMode.cpp @@ -36,6 +36,8 @@ #include "../../lowleveldynamics/src/DySolverContext.h" #include "../../lowlevel/common/include/collision/PxcContactMethodImpl.h" #include "../../lowleveldynamics/src/DyTGSContactPrep.h" +#include "../../lowleveldynamics/src/DyTGS.h" +#include "../../lowleveldynamics/src/DyConstraintPartition.h" #include "GuPersistentContactManifold.h" #include "NpConstraint.h" #include "common/PxProfileZone.h" @@ -69,7 +71,7 @@ void immediate::PxConstructStaticSolverBody(const PxTransform& globalPose, PxSol PX_ASSERT((size_t(&solverBodyData) & 0xf) == 0); const PxVec3 zero(0.0f); - Dy::copyToSolverBodyData(zero, zero, 0.f, zero, globalPose, -PX_MAX_F32, PX_MAX_F32, PX_INVALID_NODE, PX_MAX_F32, solverBodyData, 0, 0.f, false); + Dy::copyToSolverBodyData(zero, zero, 0.0f, zero, globalPose, -PX_MAX_F32, PX_MAX_F32, PX_INVALID_NODE, PX_MAX_F32, solverBodyData, 0, 0.0f, false); } void immediate::PxIntegrateSolverBodies(PxSolverBodyData* solverBodyData, PxSolverBody* solverBody, const PxVec3* linearMotionVelocity, const PxVec3* angularMotionState, PxU32 nbBodiesToIntegrate, PxReal dt) @@ -104,14 +106,11 @@ namespace PX_FORCE_INLINE void immSolveInternalConstraints(PxReal dt, PxReal invDt, Cm::SpatialVectorF* impulses, Cm::SpatialVectorF* DeltaV, PxReal elapsedTime, bool velocityIteration, bool isTGS) { - FeatherstoneArticulation::solveInternalConstraints(dt, invDt, impulses, DeltaV, velocityIteration, isTGS, elapsedTime, isTGS ? 0.7f : 1.f); + FeatherstoneArticulation::solveInternalConstraints(dt, invDt, impulses, DeltaV, velocityIteration, isTGS, elapsedTime, isTGS ? 0.7f : 1.0f); } - PX_FORCE_INLINE void immComputeUnconstrainedVelocitiesTGS(PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, const PxVec3& gravity, PxReal invLengthScale) + PX_FORCE_INLINE void immComputeUnconstrainedVelocitiesTGS(PxReal dt, PxReal totalDt, PxReal invDt, PxReal /*invTotalDt*/, const PxVec3& gravity, PxReal invLengthScale) { - PX_UNUSED(invTotalDt); - PX_UNUSED(totalDt); - PX_UNUSED(dt); mArticulationData.setDt(totalDt); Cm::SpatialVectorF* Z = mTempZ.begin(); @@ -130,9 +129,9 @@ namespace Cm::SpatialVectorF* Z = mTempZ.begin(); Cm::SpatialVectorF* deltaV = mTempDeltaV.begin(); FeatherstoneArticulation::computeUnconstrainedVelocitiesInternal(gravity, Z, deltaV, invLengthScale); - const PxReal invDt = 1.f/dt; + const PxReal invDt = 1.0f/dt; setupInternalConstraints(mArticulationData.getLinks(), mArticulationData.getLinkCount(), - mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE, mArticulationData, Z, dt, dt, invDt, 1.f, false); + mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE, mArticulationData, Z, dt, dt, invDt, 1.0f, false); } void allocate(const PxU32 nbLinks); @@ -161,33 +160,11 @@ namespace void initJointCore(Dy::ArticulationJointCore& core, const PxArticulationJointDataRC& inboundJoint); }; -#define MAX_NUM_PARTITIONS 32u - - class RigidBodyClassification + class RigidBodyClassification : public RigidBodyClassificationBase { - PX_NOCOPY(RigidBodyClassification) - private: - PxU8* PX_RESTRICT mBodies; - const PxU32 mBodySize; - const PxU32 mBodyStride; - const PxU32 mBodyCount; - public: - RigidBodyClassification(PxU8* PX_RESTRICT bodies, PxU32 bodyCount, PxU32 bodyStride) : mBodies(bodies), mBodySize(bodyCount*bodyStride), mBodyStride(bodyStride), mBodyCount(bodyCount) - { - } - - //Returns true if it is a dynamic-dynamic constraint; false if it is a dynamic-static or dynamic-kinematic constraint - PX_FORCE_INLINE bool classifyConstraint(const PxSolverConstraintDesc& desc, uintptr_t& indexA, uintptr_t& indexB, - bool& activeA, bool& activeB, PxU32& bodyAProgress, PxU32& bodyBProgress) const + RigidBodyClassification(PxU8* bodies, PxU32 bodyCount, PxU32 bodyStride) : RigidBodyClassificationBase(bodies, bodyCount, bodyStride) { - indexA = uintptr_t(reinterpret_cast(desc.bodyA) - mBodies) / mBodyStride; - indexB = uintptr_t(reinterpret_cast(desc.bodyB) - mBodies) / mBodyStride; - activeA = indexA < mBodyCount; - activeB = indexB < mBodyCount; - bodyAProgress = desc.bodyA->solverProgress; - bodyBProgress = desc.bodyB->solverProgress; - return activeA && activeB; } PX_FORCE_INLINE void reserveSpaceForStaticConstraints(PxU32* numConstraintsPerPartition) @@ -205,33 +182,6 @@ namespace } } - PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, PxU32 bodyAProgress, PxU32 bodyBProgress, PxU16 availablePartition) - { - desc.bodyA->solverProgress = bodyAProgress; - desc.bodyA->maxSolverNormalProgress = PxMax(desc.bodyA->maxSolverNormalProgress, availablePartition); - desc.bodyB->solverProgress = bodyBProgress; - desc.bodyB->maxSolverNormalProgress = PxMax(desc.bodyB->maxSolverNormalProgress, availablePartition); - } - - PX_FORCE_INLINE PxU32 getStaticContactWriteIndex(const PxSolverConstraintDesc& desc, bool activeA, bool activeB) - { - if (activeA) - return PxU32(desc.bodyA->maxSolverNormalProgress + desc.bodyA->maxSolverFrictionProgress++); - else if (activeB) - return PxU32(desc.bodyB->maxSolverNormalProgress + desc.bodyB->maxSolverFrictionProgress++); - - return 0xffffffff; - } - - PX_FORCE_INLINE void recordStaticConstraint(const PxSolverConstraintDesc& desc, bool& activeA, bool& activeB) const - { - if(activeA) - desc.bodyA->maxSolverFrictionProgress++; - - if(activeB) - desc.bodyB->maxSolverFrictionProgress++; - } - PX_FORCE_INLINE void zeroBodies() { for(PxU32 a=0; a - void writeConstraintDesc(const PxSolverConstraintDesc* PX_RESTRICT descs, PxU32 numConstraints, Classification& classification, - PxU32* accumulatedConstraintsPerPartition, PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDesc) + void writeConstraintDesc( const PxSolverConstraintDesc* PX_RESTRICT descs, PxU32 numConstraints, Classification& classification, + PxU32* accumulatedConstraintsPerPartition, PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDesc) { const PxSolverConstraintDesc* _desc = descs; const PxU32 numConstraintsMin1 = numConstraints - 1; @@ -580,6 +521,9 @@ namespace PxU32 BatchConstraints(const PxSolverConstraintDesc* solverConstraintDescs, PxU32 nbConstraints, PxConstraintBatchHeader* outBatchHeaders, PxSolverConstraintDesc* outOrderedConstraintDescs, Classification& classification) { + if(!nbConstraints) + return 0; + PxU32 constraintsPerPartition[MAX_NUM_PARTITIONS + 1]; classification.zeroBodies(); @@ -659,10 +603,10 @@ bool immediate::PxCreateContactConstraints(PxConstraintBatchHeader* batchHeaders PxConstraintAllocator& allocator, PxReal invDt, PxReal bounceThreshold, PxReal frictionOffsetThreshold, PxReal correlationDistance, PxSpatialVector* ZV) { - PX_ASSERT(invDt > 0.f && PxIsFinite(invDt)); - PX_ASSERT(bounceThreshold < 0.f); - PX_ASSERT(frictionOffsetThreshold > 0.f); - PX_ASSERT(correlationDistance > 0.f); + PX_ASSERT(invDt > 0.0f && PxIsFinite(invDt)); + PX_ASSERT(bounceThreshold < 0.0f); + PX_ASSERT(frictionOffsetThreshold > 0.0f); + PX_ASSERT(correlationDistance > 0.0f); Dy::CorrelationBuffer cb; @@ -733,8 +677,8 @@ bool immediate::PxCreateContactConstraints(PxConstraintBatchHeader* batchHeaders bool immediate::PxCreateJointConstraints(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxSpatialVector* ZV, PxReal dt, PxReal invDt) { - PX_ASSERT(dt > 0.f); - PX_ASSERT(invDt > 0.f && PxIsFinite(invDt)); + PX_ASSERT(dt > 0.0f); + PX_ASSERT(invDt > 0.0f && PxIsFinite(invDt)); PxU32 currentDescIdx = 0; @@ -922,12 +866,9 @@ void immediate::PxSolveConstraints(const PxConstraintBatchHeader* batchHeaders, PX_ASSERT(PxIsZero(solverBodies, nbSolverBodies)); //Ensure that solver body velocities have been zeroed before solving PX_ASSERT((size_t(solverBodies) & 0xf) == 0); - //Stage 1: solve the position iterations... - Dy::SolveBlockMethod* solveTable = Dy::getSolveBlockTable(); - - Dy::SolveBlockMethod* solveConcludeTable = Dy::getSolverConcludeBlockTable(); - - Dy::SolveWriteBackBlockMethod* solveWritebackTable = Dy::getSolveWritebackBlockTable(); + const Dy::SolveBlockMethod* solveTable = Dy::getSolveBlockTable(); + const Dy::SolveBlockMethod* solveConcludeTable = Dy::getSolverConcludeBlockTable(); + const Dy::SolveWriteBackBlockMethod* solveWritebackTable = Dy::getSolveWritebackBlockTable(); Dy::SolverContext cache; cache.mThresholdStreamIndex = 0; @@ -942,71 +883,51 @@ void immediate::PxSolveConstraints(const PxConstraintBatchHeader* batchHeaders, cache.Z = Z; cache.deltaV = deltaV; - struct Articulations + Dy::FeatherstoneArticulation** articulations = reinterpret_cast(solverArticulations); + + struct PGS { - static PX_FORCE_INLINE void solveInternalConstraints(float dt, float invDt, PxU32 nbSolverArticulations, Dy::FeatherstoneArticulation** solverArticulations, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV, bool velIter) + static PX_FORCE_INLINE void solveArticulationInternalConstraints(float dt, float invDt, PxU32 nbSolverArticulations, Dy::FeatherstoneArticulation** solverArticulations, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV, bool velIter) { - for(PxU32 a=0;a(solverArticulations[a]); - immArt->immSolveInternalConstraints(dt, invDt, Z, deltaV, 0.f, velIter, false); + immArticulation* immArt = static_cast(*solverArticulations++); + immArt->immSolveInternalConstraints(dt, invDt, Z, deltaV, 0.0f, velIter, false); } } - }; - for(PxU32 i=nbPositionIterations; i>1; --i) - { - cache.doFriction = i <= 3; - for(PxU32 a=0; a(solverArticulations), Z, deltaV, false); - } + solveArticulationInternalConstraints(dt, invDt, nbSolverArticulations, articulations, Z, deltaV, velIter); + } + }; - cache.doFriction = true; - for(PxU32 a=0; a(solverArticulations), Z, deltaV, false); + for(PxU32 i=nbPositionIterations; i>1; --i) + PGS::runIter(batchHeaders, nbBatchHeaders, solverConstraintDescs, nbSolverArticulations, articulations, Z, deltaV, solveTable, cache, dt, invDt, i <= 3, false); + PGS::runIter(batchHeaders, nbBatchHeaders, solverConstraintDescs, nbSolverArticulations, articulations, Z, deltaV, solveConcludeTable, cache, dt, invDt, true, false); //Save motion velocities... - for(PxU32 a=0; a(solverArticulations[a]); - FeatherstoneArticulation::saveVelocity(unusedDesc, deltaV); - } + for(PxU32 a=0; a(solverArticulations[a]), deltaV); for(PxU32 i=nbVelocityIterations; i>1; --i) - { - for(PxU32 a=0; a(solverArticulations), Z, deltaV, true); - } - - for(PxU32 a=0; a(solverArticulations), Z, deltaV, true); + PGS::runIter(batchHeaders, nbBatchHeaders, solverConstraintDescs, nbSolverArticulations, articulations, Z, deltaV, solveTable, cache, dt, invDt, true, true); + PGS::runIter(batchHeaders, nbBatchHeaders, solverConstraintDescs, nbSolverArticulations, articulations, Z, deltaV, solveWritebackTable, cache, dt, invDt, true, true); } static void createCache(Gu::Cache& cache, PxGeometryType::Enum geomType0, PxGeometryType::Enum geomType1, PxCacheAllocator& allocator) @@ -1042,14 +963,16 @@ static void createCache(Gu::Cache& cache, PxGeometryType::Enum geomType0, PxGeom } } -bool immediate::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) +bool immediate::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) { - PX_ASSERT(meshContactMargin > 0.f); - PX_ASSERT(toleranceLength > 0.f); - PX_ASSERT(contactDistance > 0.f); + PX_ASSERT(meshContactMargin > 0.0f); + PX_ASSERT(toleranceLength > 0.0f); + PX_ASSERT(contactDistance > 0.0f); PxContactBuffer contactBuffer; + PxTransform32 transform0; + PxTransform32 transform1; for (PxU32 i = 0; i < nbPairs; ++i) { contactBuffer.count = 0; @@ -1059,21 +982,20 @@ bool immediate::PxGenerateContacts(const PxGeometry* const * geom0, const PxGeom const PxGeometry* tempGeom0 = geom0[i]; const PxGeometry* tempGeom1 = geom1[i]; - PX_ALIGN(16, PxTransform) transform0 = pose0[i]; - PX_ALIGN(16, PxTransform) transform1 = pose1[i]; - const bool bSwap = type0 > type1; if (bSwap) { - const PxGeometry* temp = tempGeom0; - tempGeom0 = geom1[i]; - tempGeom1 = temp; - PxGeometryType::Enum tempType = type0; - type0 = type1; - type1 = tempType; + PxSwap(tempGeom0, tempGeom1); + PxSwap(type0, type1); + transform1 = pose0[i]; transform0 = pose1[i]; } + else + { + transform0 = pose0[i]; + transform1 = pose1[i]; + } //Now work out which type of PCM we need... @@ -1126,6 +1048,8 @@ bool immediate::PxGenerateContacts(const PxGeometry* const * geom0, const PxGeom { Gu::PersistentContactManifold& manifold = cache.getManifold(); manifold.mRelativeTransform = oldManifold->mRelativeTransform; + manifold.mQuatA = oldManifold->mQuatA; + manifold.mQuatB = oldManifold->mQuatB; manifold.mNumContacts = oldManifold->mNumContacts; manifold.mNumWarmStartPoints = oldManifold->mNumWarmStartPoints; manifold.mAIndice[0] = oldManifold->mAIndice[0]; manifold.mAIndice[1] = oldManifold->mAIndice[1]; @@ -1302,19 +1226,11 @@ void immArticulation::complete() mTempZ.resize(linkSize); } -static bool gRegistration = false; -void immediate::PxRegisterImmediateArticulations() -{ - Dy::PxvRegisterArticulationsReducedCoordinate(); - gRegistration = true; -} - PxArticulationCookie immediate::PxBeginCreateArticulationRC(const PxArticulationDataRC& data) { // PT: we create the same class as before under the hood, we just don't tell users yet. Returning a void pointer/cookie // means we can prevent them from using the articulation before it's fully completed. We do this because we're going to // delay the link creation, so we don't want them to call PxAddArticulationLink and expect the link to be here already. - PX_ASSERT(gRegistration && "Please call PxRegisterImmediateArticulations() before creating immediate articulations."); void* memory = PxAlignedAllocator<64>().allocate(sizeof(immArticulation), PX_FL); PX_PLACEMENT_NEW(memory, immArticulation(data)); return memory; @@ -1403,75 +1319,13 @@ PxArticulationCache* immediate::PxCreateArticulationCache(PxArticulationHandle a immArticulation* immArt = static_cast(articulation); immArt->complete(); - const PxU32 totalDofs = immArt->getDofs(); - const PxU32 linkCount = immArt->getBodyCount(); - const PxU32 jointCount = linkCount - 1; - - const PxU32 totalSize = - sizeof(PxArticulationCache) - + sizeof(PxSpatialForce) * linkCount //external force - + sizeof(PxReal) * (6 + totalDofs) * ((1 + jointCount) * 6) //offset to end of dense jacobian (assuming free floating base) - + sizeof(PxReal) * totalDofs * totalDofs //mass matrix - + sizeof(PxReal) * totalDofs * 4 //jointVelocity, jointAcceleration, jointPosition, joint force - + sizeof(PxSpatialVelocity) * linkCount * 2 //link velocity, link acceleration - + sizeof(PxArticulationRootLinkData); - - PxU8* tCache = reinterpret_cast(PX_ALLOC(totalSize, "Articulation cache")); - PxMemZero(tCache, totalSize); - - PxArticulationCache* cache = reinterpret_cast(tCache); - - PxU32 offset = sizeof(PxArticulationCache); - cache->externalForces = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialForce) * linkCount; - - cache->denseJacobian = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * (6 + totalDofs) * ((1 + jointCount) * 6); //size of dense jacobian assuming free floating base link. - - cache->massMatrix = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs * totalDofs; - - cache->jointVelocity = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointAcceleration = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointPosition = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointForce = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->linkVelocity = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialVelocity) * linkCount; - - cache->linkAcceleration = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialVelocity) * linkCount; - - cache->rootLinkData = reinterpret_cast(tCache + offset); - - cache->coefficientMatrix = NULL; - cache->lambda = NULL; - - const PxU32 scratchMemorySize = sizeof(Cm::SpatialVectorF) * linkCount * 5 //motionVelocity, motionAccelerations, coriolisVectors, spatialZAVectors, externalAccels; - + sizeof(Dy::SpatialMatrix) * linkCount //compositeSpatialInertias; - + sizeof(PxReal) * totalDofs * 5; //jointVelocity, jointAcceleration, jointForces, jointPositions, jointFrictionForces - - void* scratchMemory = PX_ALLOC(scratchMemorySize, "Cache scratch memory"); - cache->scratchMemory = scratchMemory; - - cache->scratchAllocator = PX_NEW(PxcScratchAllocator); - - reinterpret_cast(cache->scratchAllocator)->setBlock(scratchMemory, scratchMemorySize); - - return cache; + return FeatherstoneArticulation::createCache(immArt->getDofs(), immArt->getBodyCount(), 0); } void immediate::PxCopyInternalStateToArticulationCache(PxArticulationHandle articulation, PxArticulationCache& cache, PxArticulationCacheFlags flag) { immArticulation* immArt = static_cast(articulation); - immArt->copyInternalStateToCache(cache, flag); + immArt->copyInternalStateToCache(cache, flag, false); } void immediate::PxApplyArticulationCache(PxArticulationHandle articulation, PxArticulationCache& cache, PxArticulationCacheFlags flag) @@ -1493,7 +1347,7 @@ void immediate::PxReleaseArticulationCache(PxArticulationCache& cache) PX_FREE(ptr); } -void immediate::PxComputeUnconstrainedVelocities(PxArticulationHandle articulation, const PxVec3& gravity, const PxReal dt, const PxReal invLengthScale) +void immediate::PxComputeUnconstrainedVelocities(PxArticulationHandle articulation, const PxVec3& gravity, PxReal dt, PxReal invLengthScale) { if(!articulation) return; @@ -1508,7 +1362,7 @@ void immediate::PxComputeUnconstrainedVelocities(PxArticulationHandle articulati immArt->immComputeUnconstrainedVelocities(dt, gravity, invLengthScale); } -void immediate::PxUpdateArticulationBodies(PxArticulationHandle articulation, const PxReal dt) +void immediate::PxUpdateArticulationBodies(PxArticulationHandle articulation, PxReal dt) { if(!articulation) return; @@ -1518,8 +1372,8 @@ void immediate::PxUpdateArticulationBodies(PxArticulationHandle articulation, co FeatherstoneArticulation::updateBodies(immArt, immArt->mTempDeltaV.begin(), dt, true); } -void immediate::PxComputeUnconstrainedVelocitiesTGS(PxArticulationHandle articulation, const PxVec3& gravity, const PxReal dt, - const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal invLengthScale) +void immediate::PxComputeUnconstrainedVelocitiesTGS(PxArticulationHandle articulation, const PxVec3& gravity, PxReal dt, + PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal invLengthScale) { if (!articulation) return; @@ -1534,7 +1388,7 @@ void immediate::PxComputeUnconstrainedVelocitiesTGS(PxArticulationHandle articul immArt->immComputeUnconstrainedVelocitiesTGS(dt, totalDt, invDt, invTotalDt, gravity, invLengthScale); } -void immediate::PxUpdateArticulationBodiesTGS(PxArticulationHandle articulation, const PxReal dt) +void immediate::PxUpdateArticulationBodiesTGS(PxArticulationHandle articulation, PxReal dt) { if (!articulation) return; @@ -1752,19 +1606,19 @@ namespace physx { namespace Dy { - void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angularVelocity, const PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, - const PxReal maxDepenetrationVelocity, const PxReal maxContactImpulse, const PxU32 nodeIndex, const PxReal reportThreshold, - const PxReal maxAngVelSq, PxU32 lockFlags, bool isKinematic, + void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angularVelocity, PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, + PxReal maxDepenetrationVelocity, PxReal maxContactImpulse, PxU32 nodeIndex, PxReal reportThreshold, + PxReal maxAngVelSq, PxU32 lockFlags, bool isKinematic, PxTGSSolverBodyVel& solverVel, PxTGSSolverBodyTxInertia& solverBodyTxInertia, PxTGSSolverBodyData& solverBodyData, - const PxReal dt, const bool gyroscopicForces); + PxReal dt, bool gyroscopicForces); - void integrateCoreStep(PxTGSSolverBodyVel& vel, PxTGSSolverBodyTxInertia& txInertia, const PxF32 dt); + void integrateCoreStep(PxTGSSolverBodyVel& vel, PxTGSSolverBodyTxInertia& txInertia, PxF32 dt); } } void immediate::PxConstructSolverBodiesTGS(const PxRigidBodyData* inRigidData, PxTGSSolverBodyVel* outSolverBodyVel, - PxTGSSolverBodyTxInertia* outSolverBodyTxInertia, PxTGSSolverBodyData* outSolverBodyData, const PxU32 nbBodies, const PxVec3& gravity, - const PxReal dt, const bool gyroscopicForces) + PxTGSSolverBodyTxInertia* outSolverBodyTxInertia, PxTGSSolverBodyData* outSolverBodyData, PxU32 nbBodies, const PxVec3& gravity, + PxReal dt, bool gyroscopicForces) { for (PxU32 a = 0; a 0.f && PxIsFinite(invDt)); - PX_ASSERT(bounceThreshold < 0.f); - PX_ASSERT(frictionOffsetThreshold > 0.f); - PX_ASSERT(correlationDistance > 0.f); + PX_ASSERT(invDt > 0.0f && PxIsFinite(invDt)); + PX_ASSERT(bounceThreshold < 0.0f); + PX_ASSERT(frictionOffsetThreshold > 0.0f); + PX_ASSERT(correlationDistance > 0.0f); Dy::CorrelationBuffer cb; @@ -1877,12 +1731,12 @@ bool immediate::PxCreateContactConstraintsTGS(PxConstraintBatchHeader* batchHead return true; } -bool immediate::PxCreateJointConstraintsTGS(PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, - PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invDt, - const PxReal invTotalDt, const PxReal lengthScale) +bool immediate::PxCreateJointConstraintsTGS(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, + PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt, + PxReal invTotalDt, PxReal lengthScale) { - PX_ASSERT(dt > 0.f); - PX_ASSERT(invDt > 0.f && PxIsFinite(invDt)); + PX_ASSERT(dt > 0.0f); + PX_ASSERT(invDt > 0.0f && PxIsFinite(invDt)); const PxReal biasCoefficient = 2.f*PxSqrt(dt/totalDt); @@ -1941,10 +1795,9 @@ bool immediate::PxCreateJointConstraintsTGS(PxConstraintBatchHeader* batchHeader return true; } - template -static bool PxCreateJointConstraintsWithShadersTGS_T(PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, ParamsT* params, PxTGSSolverConstraintPrepDesc* jointDescs, - PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal lengthScale) +static bool PxCreateJointConstraintsWithShadersTGS_T(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, ParamsT* params, PxTGSSolverConstraintPrepDesc* jointDescs, + PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal lengthScale) { Px1DConstraint allRows[Dy::MAX_CONSTRAINT_ROWS * 4]; @@ -2004,15 +1857,14 @@ static bool PxCreateJointConstraintsWithShadersTGS_T(PxConstraintBatchHeader* ba return true; //KS - TODO - do some error reporting/management... } - bool immediate::PxCreateJointConstraintsWithShadersTGS(PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, PxConstraint** constraints, PxTGSSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal lengthScale) { return PxCreateJointConstraintsWithShadersTGS_T(batchHeaders, nbBatchHeaders, constraints, jointDescs, allocator, dt, totalDt, invDt, invTotalDt, lengthScale); } -bool immediate::PxCreateJointConstraintsWithImmediateShadersTGS(PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, PxImmediateConstraint* constraints, PxTGSSolverConstraintPrepDesc* jointDescs, - PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invDt, const PxReal invTotalDt, const PxReal lengthScale) +bool immediate::PxCreateJointConstraintsWithImmediateShadersTGS(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxImmediateConstraint* constraints, PxTGSSolverConstraintPrepDesc* jointDescs, + PxConstraintAllocator& allocator, PxReal dt, PxReal totalDt, PxReal invDt, PxReal invTotalDt, PxReal lengthScale) { class immConstraintAdapter { @@ -2029,21 +1881,16 @@ bool immediate::PxCreateJointConstraintsWithImmediateShadersTGS(PxConstraintBatc return PxCreateJointConstraintsWithShadersTGS_T(batchHeaders, nbHeaders, constraints, jointDescs, allocator, dt, totalDt, invDt, invTotalDt, lengthScale); } -void immediate::PxSolveConstraintsTGS(const PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs, - PxTGSSolverBodyVel* solverBodies, PxTGSSolverBodyTxInertia* txInertias, const PxU32 nbSolverBodies, const PxU32 nbPositionIterations, const PxU32 nbVelocityIterations, - const float dt, const float invDt, const PxU32 nbSolverArticulations, PxArticulationHandle* solverArticulations, PxSpatialVector* pxZ, PxSpatialVector* pxDeltaV) +void immediate::PxSolveConstraintsTGS(const PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs, + PxTGSSolverBodyVel* solverBodies, PxTGSSolverBodyTxInertia* txInertias, PxU32 nbSolverBodies, PxU32 nbPositionIterations, PxU32 nbVelocityIterations, + float dt, float invDt, PxU32 nbSolverArticulations, PxArticulationHandle* solverArticulations, PxSpatialVector* pxZ, PxSpatialVector* pxDeltaV) { - PX_UNUSED(solverBodies); - PX_UNUSED(nbSolverBodies); PX_ASSERT(nbPositionIterations > 0); PX_ASSERT(nbVelocityIterations > 0); - //Stage 1: solve the position iterations... - Dy::TGSSolveBlockMethod* solveTable = Dy::g_SolveTGSMethods; - - Dy::TGSSolveConcludeMethod* solveConcludeTable = Dy::g_SolveConcludeTGSMethods; - - Dy::TGSWriteBackMethod* writebackTable = Dy::g_WritebackTGSMethods; + const Dy::TGSSolveBlockMethod* solveTable = Dy::g_SolveTGSMethods; + const Dy::TGSSolveConcludeMethod* solveConcludeTable = Dy::g_SolveConcludeTGSMethods; + const Dy::TGSWriteBackMethod* writebackTable = Dy::g_WritebackTGSMethods; Dy::SolverContext cache; cache.mThresholdStreamIndex = 0; @@ -2054,100 +1901,76 @@ void immediate::PxSolveConstraintsTGS(const PxConstraintBatchHeader* batchHeader cache.Z = Z; cache.deltaV = deltaV; + cache.doFriction = true; + + Dy::FeatherstoneArticulation** articulations = reinterpret_cast(solverArticulations); - struct Articulations + struct TGS { - static PX_FORCE_INLINE void solveInternalConstraints(const float dt, const float invDt, const PxU32 nbSolverArticulations, Dy::FeatherstoneArticulation** solverArticulations, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV, - const PxReal elapsedTime, bool velIter) + static PX_FORCE_INLINE void solveArticulationInternalConstraints(float dt, float invDt, PxU32 nbSolverArticulations, Dy::FeatherstoneArticulation** solverArticulations, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV, + PxReal elapsedTime, bool velIter) { - for(PxU32 a = 0; a(solverArticulations[a]); + immArticulation* immArt = static_cast(*solverArticulations++); immArt->immSolveInternalConstraints(dt, invDt, Z, deltaV, elapsedTime, velIter, true); } } - - static PX_FORCE_INLINE void stepArticulations(const float dt, const PxReal totalInvDt, const PxU32 nbSolverArticulations, Dy::FeatherstoneArticulation** solverArticulations, Cm::SpatialVectorF* deltaV) - { - for(PxU32 a = 0; a(solverArticulations[a]); - immArt->recordDeltaMotion(immArt->getSolverDesc(), dt, deltaV, totalInvDt); - } - } - - static PX_FORCE_INLINE void saveVelocities(const PxReal totalInvDt, const PxU32 nbSolverArticulations, Dy::FeatherstoneArticulation** solverArticulations) - { - for (PxU32 a = 0; a < nbSolverArticulations; a++) - { - immArticulation* immArt = static_cast(solverArticulations[a]); - immArt->saveVelocityTGS(immArt->getSolverDesc(), totalInvDt); - } - } }; const PxReal invTotalDt = 1.0f/(dt*nbPositionIterations); PxReal elapsedTime = 0.0f; - for(PxU32 i = nbPositionIterations; i>1; --i) + + while(nbPositionIterations--) { - Articulations::solveInternalConstraints(dt, invDt, nbSolverArticulations, reinterpret_cast(solverArticulations), Z, deltaV, elapsedTime, false); + TGS::solveArticulationInternalConstraints(dt, invDt, nbSolverArticulations, articulations, Z, deltaV, elapsedTime, false); - cache.doFriction = true; - for(PxU32 a = 0; a(solverArticulations[j]); + immArt->recordDeltaMotion(immArt->getSolverDesc(), dt, deltaV, invTotalDt); + } + } - Articulations::stepArticulations(dt, invTotalDt, nbSolverArticulations, reinterpret_cast(solverArticulations), deltaV); elapsedTime += dt; } - cache.doFriction = true; - - Articulations::solveInternalConstraints(dt, invDt, nbSolverArticulations, reinterpret_cast(solverArticulations), Z, deltaV, elapsedTime, false); - - for(PxU32 a = 0; a(articulations[a]); + immArt->saveVelocityTGS(immArt, invTotalDt); } - - for(PxU32 j = 0; j < nbSolverBodies; ++j) - Dy::integrateCoreStep(solverBodies[j], txInertias[j], dt); - - Articulations::stepArticulations(dt, invTotalDt, nbSolverArticulations, reinterpret_cast(solverArticulations), deltaV); - elapsedTime += dt; - Articulations::saveVelocities(invTotalDt, nbSolverArticulations, reinterpret_cast(solverArticulations)); - - for(PxU32 i = nbVelocityIterations; i>1; --i) + while(nbVelocityIterations--) { - Articulations::solveInternalConstraints(dt, invDt, nbSolverArticulations, reinterpret_cast(solverArticulations), Z, deltaV, elapsedTime, true); - for(PxU32 a = 0; a(solverArticulations), Z, deltaV, elapsedTime, true); - - for(PxU32 a = 0; acreateGpuKernelWranglerManager(contextManager, *PxGetErrorCallback(), gpuComputeVersion); + mGpuWranglerManagers = mPxGpu->getGpuKernelWranglerManager(contextManager); if(!mGpuWranglerManagers) return false; diff --git a/physx/source/lowlevel/api/include/PxsFEMClothMaterialCore.h b/physx/source/lowlevel/api/include/PxsFEMClothMaterialCore.h index 81c833276..f0c4b1199 100644 --- a/physx/source/lowlevel/api/include/PxsFEMClothMaterialCore.h +++ b/physx/source/lowlevel/api/include/PxsFEMClothMaterialCore.h @@ -34,34 +34,18 @@ namespace physx { - PX_ALIGN_PREFIX(16) struct PxsFEMClothMaterialAuxData - { - // derived quantities (computed internally) - float lambda; //4 - float mu; //8 - float padding[2]; //16 - }PX_ALIGN_SUFFIX(16); - PX_ALIGN_PREFIX(16) struct PxsFEMClothMaterialData { PxReal youngs; //4 PxReal poissons; //8 PxReal dynamicFriction; //12 PxReal thickness; //16 - PxReal elasticityDamping; //20 - PxReal bendingDamping; //24 - PxReal padding[2]; //32 - - PX_CUDA_CALLABLE PxsFEMClothMaterialData() : - youngs (1.e+6f), - poissons (0.45f), - dynamicFriction (0.0f), - thickness (0.0f), - elasticityDamping (0.0f), - bendingDamping (0.0f) - {} - PxsFEMClothMaterialData(const PxEMPTY) {} + PX_CUDA_CALLABLE PxsFEMClothMaterialData() + : youngs(1.e+6f), poissons(0.45f), dynamicFriction(0.0f), thickness(0.0f) + {} + + PxsFEMClothMaterialData(const PxEMPTY) {} }PX_ALIGN_SUFFIX(16); diff --git a/physx/source/lowlevel/api/include/PxsFEMSoftBodyMaterialCore.h b/physx/source/lowlevel/api/include/PxsFEMSoftBodyMaterialCore.h index 0908a3045..dbddf6c47 100644 --- a/physx/source/lowlevel/api/include/PxsFEMSoftBodyMaterialCore.h +++ b/physx/source/lowlevel/api/include/PxsFEMSoftBodyMaterialCore.h @@ -34,6 +34,20 @@ namespace physx { + + PX_FORCE_INLINE PX_CUDA_CALLABLE PxU16 toUniformU16(PxReal f) + { + f = PxClamp(f, 0.0f, 1.0f); + return PxU16(f * 65535.0f); + } + + PX_FORCE_INLINE PX_CUDA_CALLABLE PxReal toUniformReal(PxU16 v) + { + return PxReal(v) * (1.0f / 65535.0f); + } + + + PX_ALIGN_PREFIX(16) struct PxsFEMSoftBodyMaterialAuxData { // derived for co-rotational (computed internally) @@ -52,7 +66,8 @@ namespace physx PxReal poissons; //8 PxReal dynamicFriction; //12 PxReal damping; //16 - PxReal dampingScale; //20 + PxU16 dampingScale; //20, known to be in the range of 0...1. Mapped to integer range 0...65535 + PxU16 materialModel; //22 PxReal deformThreshold; //24 PxReal deformLowLimitRatio; //28 PxReal deformHighLimitRatio; //32 @@ -62,6 +77,8 @@ namespace physx poissons (0.45f), dynamicFriction (0.0f), damping (0.0f), + //dampingScale (0), + materialModel (PxFEMSoftBodyMaterialModel::eCO_ROTATIONAL), deformThreshold (PX_MAX_F32), deformLowLimitRatio (1.0f), deformHighLimitRatio(1.0f) diff --git a/physx/source/lowlevel/api/include/PxsMaterialManager.h b/physx/source/lowlevel/api/include/PxsMaterialManager.h index 4c5f65288..fed952e0c 100644 --- a/physx/source/lowlevel/api/include/PxsMaterialManager.h +++ b/physx/source/lowlevel/api/include/PxsMaterialManager.h @@ -146,10 +146,6 @@ namespace physx { }; - class PxsCustomMaterialManager : public PxsMaterialManagerT - { - }; - template class PxsMaterialManagerIterator { diff --git a/physx/source/lowlevel/api/include/PxsPBDMaterialCore.h b/physx/source/lowlevel/api/include/PxsPBDMaterialCore.h index e4881ebfc..ddaab2492 100644 --- a/physx/source/lowlevel/api/include/PxsPBDMaterialCore.h +++ b/physx/source/lowlevel/api/include/PxsPBDMaterialCore.h @@ -34,16 +34,6 @@ namespace physx { - //Technically, this doesn't need the PxsParticleMaterialData types, but this allows us - //to have a common base and opens the scope for rigid-particle interactions. - struct PxsCustomMaterialData : public PxsParticleMaterialData - { - PxsCustomMaterialData() {} // PT: TODO: ctor leaves things uninitialized, is that by design? - PxsCustomMaterialData(const PxEMPTY) {} - - void* userData; //24 - }; - struct PxsPBDMaterialData : public PxsParticleMaterialData { PxsPBDMaterialData() {} // PT: TODO: ctor leaves things uninitialized, is that by design? @@ -62,7 +52,6 @@ namespace physx }; typedef MaterialCoreT PxsPBDMaterialCore; - typedef MaterialCoreT PxsCustomMaterialCore; } //namespace phyxs diff --git a/physx/source/lowlevel/api/include/PxvDynamics.h b/physx/source/lowlevel/api/include/PxvDynamics.h index 866075e9d..e4895590b 100644 --- a/physx/source/lowlevel/api/include/PxvDynamics.h +++ b/physx/source/lowlevel/api/include/PxvDynamics.h @@ -46,13 +46,6 @@ Dynamics interface. struct PxsRigidCore { -//= 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. -//================================================================================================== - PxsRigidCore() : mFlags(0), solverIterationCounts(0) {} PxsRigidCore(const PxEMPTY) : mFlags(PxEmpty) {} @@ -72,14 +65,7 @@ PX_COMPILE_TIME_ASSERT(sizeof(PxsRigidCore) == 32); struct PxsBodyCore : public PxsRigidCore { -//= 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. -//================================================================================================== - - PxsBodyCore() : PxsRigidCore() { kinematicLink = PxU8(0); } + PxsBodyCore() : PxsRigidCore() { fixedBaseLink = PxU8(0); } PxsBodyCore(const PxEMPTY) : PxsRigidCore(PxEmpty) {} PX_FORCE_INLINE const PxTransform& getBody2Actor() const { return body2Actor; } @@ -127,7 +113,7 @@ struct PxsBodyCore : public PxsRigidCore PxU8 isFastMoving; //This could be a single bit but it's a u8 at the moment for simplicity's sake PxU8 disableGravity; //This could be a single bit but it's a u8 at the moment for simplicity's sake PxRigidDynamicLockFlags lockFlags; //This is u8. - PxU8 kinematicLink; //160 This indicates whether the articulation link is kinematic link. All fits into 16 byte alignment + PxU8 fixedBaseLink; //160 This indicates whether the articulation link has PxArticulationFlag::eFIX_BASE. All fits into 16 byte alignment // PT: moved from Sc::BodyCore ctor - we don't want to duplicate all this in immediate mode PX_FORCE_INLINE void init( const PxTransform& bodyPose, diff --git a/physx/source/lowlevel/api/include/PxvGeometry.h b/physx/source/lowlevel/api/include/PxvGeometry.h index 8d3e9f958..1d558e437 100644 --- a/physx/source/lowlevel/api/include/PxvGeometry.h +++ b/physx/source/lowlevel/api/include/PxvGeometry.h @@ -67,12 +67,6 @@ namespace physx struct MaterialIndicesStruct { -//= 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_SERIALIZATION MaterialIndicesStruct(const PxEMPTY) {} static void getBinaryMetaData(PxOutputStream& stream); @@ -151,12 +145,6 @@ class InvalidGeometry : public PxGeometry class GeometryUnion { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION GeometryUnion(const PxEMPTY) {} @@ -219,19 +207,13 @@ class GeometryUnion struct PxsShapeCore { -//= 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_SERIALIZATION PxsShapeCore() { setDensityForFluid(800.0f); } - PxsShapeCore(const PxEMPTY) : mGeometry(PxEmpty) {} + +// PX_SERIALIZATION + PxsShapeCore(const PxEMPTY) : mShapeCoreFlags(PxEmpty), mGeometry(PxEmpty) {} //~PX_SERIALIZATION #if PX_WINDOWS_FAMILY // PT: to avoid "error: offset of on non-standard-layout type" on Linux diff --git a/physx/source/lowlevel/api/include/PxvGlobals.h b/physx/source/lowlevel/api/include/PxvGlobals.h index d3f32f436..f61699044 100644 --- a/physx/source/lowlevel/api/include/PxvGlobals.h +++ b/physx/source/lowlevel/api/include/PxvGlobals.h @@ -90,21 +90,13 @@ extern PxvOffsetTable gPxvOffsetTable; /*! Initialize low-level implementation. */ - void PxvInit(const PxvOffsetTable& offsetTable); - /*! Shut down low-level implementation. */ void PxvTerm(); -/*! -Initialize low-level implementation. -*/ - -void PxvRegisterHeightFields(); - #if PX_SUPPORT_GPU_PHYSX class PxPhysXGpu* PxvGetPhysXGpu(bool createIfNeeded); void PxvReleasePhysXGpu(PxPhysXGpu*); diff --git a/physx/source/lowlevel/api/src/px_globals.cpp b/physx/source/lowlevel/api/src/px_globals.cpp index 2c6904cc7..1c2b52577 100644 --- a/physx/source/lowlevel/api/src/px_globals.cpp +++ b/physx/source/lowlevel/api/src/px_globals.cpp @@ -63,6 +63,7 @@ namespace physx { //forward declare stuff from PxPhysXGpuModuleLoader.cpp void PxLoadPhysxGPUModule(const char* appGUID); + void PxUnloadPhysxGPUModule(); typedef physx::PxPhysXGpu* (PxCreatePhysXGpu_FUNC)(); extern PxCreatePhysXGpu_FUNC* g_PxCreatePhysXGpu_Func; @@ -88,6 +89,7 @@ namespace physx void PxvReleasePhysXGpu(PxPhysXGpu* gpu) { PX_ASSERT(gpu==gPxPhysXGpu); + PxUnloadPhysxGPUModule(); PX_RELEASE(gpu); gPxPhysXGpu = NULL; } @@ -136,7 +138,8 @@ template<> void PxsFEMSoftBodyMaterialCore::getBinaryMetaData(PxOutputStream& st PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, poissons, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, dynamicFriction, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, damping, 0) - PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, dampingScale, 0) + PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxU16, dampingScale, 0) + PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxU16, materialModel, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, deformThreshold, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, deformLowLimitRatio, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMSoftBodyMaterialCore, PxReal, deformHighLimitRatio, 0) @@ -155,9 +158,6 @@ template<> void PxsFEMClothMaterialCore::getBinaryMetaData(PxOutputStream& strea PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMClothMaterialCore, PxReal, poissons, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMClothMaterialCore, PxReal, dynamicFriction, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMClothMaterialCore, PxReal, thickness, 0) - PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMClothMaterialCore, PxReal, elasticityDamping, 0) - PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMClothMaterialCore, PxReal, bendingDamping, 0) - PX_DEF_BIN_METADATA_ITEMS(stream, PxsFEMClothMaterialCore, PxReal, padding, PxMetaDataFlag::ePADDING, 2) // MaterialCore PX_DEF_BIN_METADATA_ITEM(stream, PxsFEMClothMaterialCore, PxFEMClothMaterial, mMaterial, PxMetaDataFlag::ePTR) @@ -191,18 +191,6 @@ template<> void PxsPBDMaterialCore::getBinaryMetaData(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, PxsPBDMaterialCore, PxU16, mMaterialIndex, PxMetaDataFlag::eHANDLE) } -template<> void PxsCustomMaterialCore::getBinaryMetaData(PxOutputStream& stream) -{ - PX_DEF_BIN_METADATA_CLASS(stream, PxsCustomMaterialCore) - - // MaterialData - PX_DEF_BIN_METADATA_ITEM(stream, PxsCustomMaterialCore, void, userData, PxMetaDataFlag::ePTR) - - // MaterialCore - PX_DEF_BIN_METADATA_ITEM(stream, PxsCustomMaterialCore, PxPBDMaterial, mMaterial, PxMetaDataFlag::ePTR) - PX_DEF_BIN_METADATA_ITEM(stream, PxsCustomMaterialCore, PxU16, mMaterialIndex, PxMetaDataFlag::eHANDLE) -} - template<> void PxsFLIPMaterialCore::getBinaryMetaData(PxOutputStream& stream) { PX_DEF_BIN_METADATA_CLASS(stream, PxsFLIPMaterialCore) diff --git a/physx/source/lowlevel/common/include/pipeline/PxcContactCache.h b/physx/source/lowlevel/common/include/pipeline/PxcContactCache.h index 26b3c044c..cc2c3bb9c 100644 --- a/physx/source/lowlevel/common/include/pipeline/PxcContactCache.h +++ b/physx/source/lowlevel/common/include/pipeline/PxcContactCache.h @@ -38,7 +38,7 @@ namespace physx class PxcNpThreadContext; bool PxcCacheLocalContacts( PxcNpThreadContext& context, Gu::Cache& pairContactCache, - const PxTransform& tm0, const PxTransform& tm1, + const PxTransform32& tm0, const PxTransform32& tm1, const PxcContactMethod conMethod, const PxGeometry& shape0, const PxGeometry& shape1); diff --git a/physx/source/lowlevel/common/include/pipeline/PxcNpContactPrepShared.h b/physx/source/lowlevel/common/include/pipeline/PxcNpContactPrepShared.h index 09fc9b323..c34ace285 100644 --- a/physx/source/lowlevel/common/include/pipeline/PxcNpContactPrepShared.h +++ b/physx/source/lowlevel/common/include/pipeline/PxcNpContactPrepShared.h @@ -47,8 +47,8 @@ static const PxReal PXC_SAME_NORMAL = 0.999f; //Around 6 degrees PxU32 writeCompressedContact(const PxContactPoint* const PX_RESTRICT contactPoints, const PxU32 numContactPoints, PxcNpThreadContext* threadContext, PxU16& writtenContactCount, PxU8*& outContactPatches, PxU8*& outContactPoints, PxU16& compressedContactSize, PxReal*& contactForces, PxU32 contactForceByteSize, - const PxsMaterialManager* materialManager, bool hasModifiableContacts, bool forceNoResponse, PxsMaterialInfo* PX_RESTRICT pMaterial, PxU8& numPatches, - PxU32 additionalHeaderSize = 0, PxsConstraintBlockManager* manager = NULL, PxcConstraintBlockStream* blockStream = NULL, bool insertAveragePoint = false, + const PxsMaterialManager* materialManager, bool hasModifiableContacts, bool forceNoResponse, const PxsMaterialInfo* PX_RESTRICT pMaterial, PxU8& numPatches, + PxU32 additionalHeaderSize = 0, PxsConstraintBlockManager* manager = NULL, PxcConstraintBlockStream* blockStream = NULL, bool insertAveragePoint = false, PxcDataStreamPool* pool = NULL, PxcDataStreamPool* patchStreamPool = NULL, PxcDataStreamPool* forcePool = NULL, const bool isMeshType = false); } diff --git a/physx/source/lowlevel/common/src/pipeline/PxcContactCache.cpp b/physx/source/lowlevel/common/src/pipeline/PxcContactCache.cpp index 68921df35..2db261b7d 100644 --- a/physx/source/lowlevel/common/src/pipeline/PxcContactCache.cpp +++ b/physx/source/lowlevel/common/src/pipeline/PxcContactCache.cpp @@ -297,7 +297,7 @@ static PX_FORCE_INLINE PxReal maxComponentDeltaRot(const PxTransform& t0, const } bool physx::PxcCacheLocalContacts( PxcNpThreadContext& context, Cache& pairContactCache, - const PxTransform& tm0, const PxTransform& tm1, + const PxTransform32& tm0, const PxTransform32& tm1, const PxcContactMethod conMethod, const PxGeometry& shape0, const PxGeometry& shape1) { diff --git a/physx/source/lowlevel/common/src/pipeline/PxcContactMethodImpl.cpp b/physx/source/lowlevel/common/src/pipeline/PxcContactMethodImpl.cpp index 48cf76e41..d4d2eb463 100644 --- a/physx/source/lowlevel/common/src/pipeline/PxcContactMethodImpl.cpp +++ b/physx/source/lowlevel/common/src/pipeline/PxcContactMethodImpl.cpp @@ -86,9 +86,6 @@ static bool PxcPCMContactGeometryCustomGeometry (GU_CONTACT_METHOD_ARGS) { retur #undef ARGS -#define DYNAMIC_CONTACT_REGISTRATION(x) PxcInvalidContactPair -//#define DYNAMIC_CONTACT_REGISTRATION(x) x - namespace physx { //Table of contact methods for different shape-type combinations @@ -104,7 +101,7 @@ PxcContactMethod g_ContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH PxcContactSphereMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcContactSphereHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcContactSphereHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM PxcContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, @@ -134,7 +131,7 @@ PxcContactMethod g_ContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH PxcContactCapsuleMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcContactCapsuleHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcContactCapsuleHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM PxcContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, @@ -149,7 +146,7 @@ PxcContactMethod g_ContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH PxcContactBoxMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcContactBoxHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcContactBoxHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM PxcContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, @@ -164,7 +161,7 @@ PxcContactMethod g_ContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH PxcContactConvexMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcContactConvexHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcContactConvexHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM PxcContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, @@ -266,17 +263,17 @@ PxcContactMethod g_PCMContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = { //PxGeometryType::eSPHERE { - PxcPCMContactSphereSphere, //PxGeometryType::eSPHERE - PxcPCMContactSpherePlane, //PxGeometryType::ePLANE - PxcPCMContactSphereCapsule, //PxGeometryType::eCAPSULE - PxcPCMContactSphereBox, //PxGeometryType::eBOX - PxcPCMContactSphereConvex, //PxGeometryType::eCONVEXMESH - PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM - PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH - PxcPCMContactSphereMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcPCMContactSphereHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this - PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM - PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM + PxcPCMContactSphereSphere, //PxGeometryType::eSPHERE + PxcPCMContactSpherePlane, //PxGeometryType::ePLANE + PxcPCMContactSphereCapsule, //PxGeometryType::eCAPSULE + PxcPCMContactSphereBox, //PxGeometryType::eBOX + PxcPCMContactSphereConvex, //PxGeometryType::eCONVEXMESH + PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM + PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH + PxcPCMContactSphereMesh, //PxGeometryType::eTRIANGLEMESH + PxcPCMContactSphereHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM + PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::ePLANE @@ -296,47 +293,47 @@ PxcContactMethod g_PCMContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = //PxGeometryType::eCAPSULE { - 0, //PxGeometryType::eSPHERE - 0, //PxGeometryType::ePLANE - PxcPCMContactCapsuleCapsule, //PxGeometryType::eCAPSULE - PxcPCMContactCapsuleBox, //PxGeometryType::eBOX - PxcPCMContactCapsuleConvex, //PxGeometryType::eCONVEXMESH - PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM - PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH - PxcPCMContactCapsuleMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcPCMContactCapsuleHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this - PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM - PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + 0, //PxGeometryType::ePLANE + PxcPCMContactCapsuleCapsule, //PxGeometryType::eCAPSULE + PxcPCMContactCapsuleBox, //PxGeometryType::eBOX + PxcPCMContactCapsuleConvex, //PxGeometryType::eCONVEXMESH + PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM + PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH + PxcPCMContactCapsuleMesh, //PxGeometryType::eTRIANGLEMESH + PxcPCMContactCapsuleHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM + PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::eBOX { - 0, //PxGeometryType::eSPHERE - 0, //PxGeometryType::ePLANE - 0, //PxGeometryType::eCAPSULE - PxcPCMContactBoxBox, //PxGeometryType::eBOX - PxcPCMContactBoxConvex, //PxGeometryType::eCONVEXMESH - PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM - PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH - PxcPCMContactBoxMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcPCMContactBoxHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this - PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM - PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + 0, //PxGeometryType::ePLANE + 0, //PxGeometryType::eCAPSULE + PxcPCMContactBoxBox, //PxGeometryType::eBOX + PxcPCMContactBoxConvex, //PxGeometryType::eCONVEXMESH + PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM + PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH + PxcPCMContactBoxMesh, //PxGeometryType::eTRIANGLEMESH + PxcPCMContactBoxHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM + PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::eCONVEXMESH { - 0, //PxGeometryType::eSPHERE - 0, //PxGeometryType::ePLANE - 0, //PxGeometryType::eCAPSULE - 0, //PxGeometryType::eBOX - PxcPCMContactConvexConvex, //PxGeometryType::eCONVEXMESH - PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM - PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH - PxcPCMContactConvexMesh, //PxGeometryType::eTRIANGLEMESH - DYNAMIC_CONTACT_REGISTRATION(PxcPCMContactConvexHeightField), //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this - PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM - PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM + 0, //PxGeometryType::eSPHERE + 0, //PxGeometryType::ePLANE + 0, //PxGeometryType::eCAPSULE + 0, //PxGeometryType::eBOX + PxcPCMContactConvexConvex, //PxGeometryType::eCONVEXMESH + PxcInvalidContactPair, //PxGeometryType::ePARTICLESYSTEM + PxcInvalidContactPair, //PxGeometryType::eTETRAHEDRONMESH + PxcPCMContactConvexMesh, //PxGeometryType::eTRIANGLEMESH + PxcPCMContactConvexHeightField, //PxGeometryType::eHEIGHTFIELD //TODO: make HF midphase that will mask this + PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM + PxcPCMContactGeometryCustomGeometry, //PxGeometryType::eCUSTOM }, //PxGeometryType::ePARTICLESYSTEM @@ -411,7 +408,7 @@ PxcContactMethod g_PCMContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = 0, //PxGeometryType::eTRIANGLEMESH 0, //PxGeometryType::eHEIGHTFIELD PxcInvalidContactPair, //PxGeometryType::eHAIRSYSTEM - PxcPCMContactGeometryCustomGeometry,//PxGeometryType::eCUSTOM + PxcInvalidContactPair, //PxGeometryType::eCUSTOM }, //PxGeometryType::eCUSTOM @@ -431,17 +428,4 @@ PxcContactMethod g_PCMContactMethodTable[][PxGeometryType::eGEOMETRY_COUNT] = }; PX_COMPILE_TIME_ASSERT(sizeof(g_PCMContactMethodTable) / sizeof(g_PCMContactMethodTable[0]) == PxGeometryType::eGEOMETRY_COUNT); -void PxvRegisterHeightFields() -{ - g_ContactMethodTable[PxGeometryType::eSPHERE][PxGeometryType::eHEIGHTFIELD] = PxcContactSphereHeightField; - g_ContactMethodTable[PxGeometryType::eCAPSULE][PxGeometryType::eHEIGHTFIELD] = PxcContactCapsuleHeightField; - g_ContactMethodTable[PxGeometryType::eBOX][PxGeometryType::eHEIGHTFIELD] = PxcContactBoxHeightField; - g_ContactMethodTable[PxGeometryType::eCONVEXMESH][PxGeometryType::eHEIGHTFIELD] = PxcContactConvexHeightField; - - g_PCMContactMethodTable[PxGeometryType::eSPHERE][PxGeometryType::eHEIGHTFIELD] = PxcPCMContactSphereHeightField; - g_PCMContactMethodTable[PxGeometryType::eCAPSULE][PxGeometryType::eHEIGHTFIELD] = PxcPCMContactCapsuleHeightField; - g_PCMContactMethodTable[PxGeometryType::eBOX][PxGeometryType::eHEIGHTFIELD] = PxcPCMContactBoxHeightField; - g_PCMContactMethodTable[PxGeometryType::eCONVEXMESH][PxGeometryType::eHEIGHTFIELD] = PxcPCMContactConvexHeightField; -} - } diff --git a/physx/source/lowlevel/common/src/pipeline/PxcMaterialMethodImpl.cpp b/physx/source/lowlevel/common/src/pipeline/PxcMaterialMethodImpl.cpp index 6a0174fe4..c1c396f33 100644 --- a/physx/source/lowlevel/common/src/pipeline/PxcMaterialMethodImpl.cpp +++ b/physx/source/lowlevel/common/src/pipeline/PxcMaterialMethodImpl.cpp @@ -86,7 +86,7 @@ static void PxcGetMaterialMesh(const PxsShapeCore* shape, const PxU32 index, Pxc for(PxU32 i=0; igetTriangleMaterialIndex(contact.featureIndex1); + const PxU32 localMaterialIndex = eaMaterialIndices ? eaMaterialIndices[contact.internalFaceIndex1] : 0;//shapeMesh.triangleMesh->getTriangleMaterialIndex(contact.featureIndex1); (&materialInfo[i].mMaterialIndex0)[index] = indices[localMaterialIndex]; } } @@ -111,7 +111,7 @@ static void PxcGetMaterialShapeMesh(const PxsShapeCore* shape0, const PxsShapeCo PxContactPoint& contact = contactBuffer.contacts[i]; materialInfo[i].mMaterialIndex0 = materialIndex0; - const PxU32 localMaterialIndex = eaMaterialIndices[contact.internalFaceIndex1];//shapeMesh.triangleMesh->getTriangleMaterialIndex(contact.featureIndex1); + const PxU32 localMaterialIndex = eaMaterialIndices ? eaMaterialIndices[contact.internalFaceIndex1] : 0;//shapeMesh.triangleMesh->getTriangleMaterialIndex(contact.featureIndex1); materialInfo[i].mMaterialIndex1 = indices[localMaterialIndex]; } } @@ -137,7 +137,7 @@ static void PxcGetMaterialSoftBodyMesh(const PxsShapeCore* shape0, const PxsShap PxContactPoint& contact = contactBuffer.contacts[i]; materialInfo[i].mMaterialIndex0 = materialIndex0; - const PxU32 localMaterialIndex = eaMaterialIndices[contact.internalFaceIndex1];//shapeMesh.triangleMesh->getTriangleMaterialIndex(contact.featureIndex1); + const PxU32 localMaterialIndex = eaMaterialIndices ? eaMaterialIndices[contact.internalFaceIndex1] : 0;//shapeMesh.triangleMesh->getTriangleMaterialIndex(contact.featureIndex1); //contact.featureIndex1 = shapeMesh.materials.indices[localMaterialIndex]; materialInfo[i].mMaterialIndex1 = indices[localMaterialIndex]; } diff --git a/physx/source/lowlevel/common/src/pipeline/PxcNpBatch.cpp b/physx/source/lowlevel/common/src/pipeline/PxcNpBatch.cpp index bb6a10305..98bb78dd6 100644 --- a/physx/source/lowlevel/common/src/pipeline/PxcNpBatch.cpp +++ b/physx/source/lowlevel/common/src/pipeline/PxcNpBatch.cpp @@ -46,6 +46,8 @@ using namespace physx; using namespace Gu; +PX_COMPILE_TIME_ASSERT(sizeof(PxsCachedTransform)==sizeof(PxTransform32)); + static void startContacts(PxsContactManagerOutput& output, PxcNpThreadContext& context) { context.mContactBuffer.reset(); @@ -372,8 +374,8 @@ static PX_FORCE_INLINE void discreteNarrowPhase(PxcNpThreadContext& context, con startContacts(output, context); - const PxTransform* tm0 = &cachedTransform0->transform; - const PxTransform* tm1 = &cachedTransform1->transform; + const PxTransform32* tm0 = reinterpret_cast(cachedTransform0); + const PxTransform32* tm1 = reinterpret_cast(cachedTransform1); PX_ASSERT(tm0->isSane() && tm1->isSane()); const PxGeometry& contactShape0 = shape0->mGeometry.getGeometry(); @@ -415,17 +417,20 @@ static PX_FORCE_INLINE void discreteNarrowPhase(PxcNpThreadContext& context, con conMethod(contactShape0, contactShape1, *tm0, *tm1, context.mNarrowPhaseParams, cache, context.mContactBuffer, &context.mRenderOutput); } - const PxcGetMaterialMethod materialMethod = g_GetMaterialMethodTable[type0][type1]; - if(materialMethod) + if(context.mContactBuffer.count) { - LOCAL_PROFILE_ZONE("materialMethod", contextID); - materialMethod(shape0, shape1, context, materialInfo); - } + const PxcGetMaterialMethod materialMethod = g_GetMaterialMethodTable[type0][type1]; + if(materialMethod) + { + LOCAL_PROFILE_ZONE("materialMethod", contextID); + materialMethod(shape0, shape1, context, materialInfo); + } - if(flip) - { - LOCAL_PROFILE_ZONE("flipContacts", contextID); - flipContacts(context, materialInfo); + if(flip) + { + LOCAL_PROFILE_ZONE("flipContacts", contextID); + flipContacts(context, materialInfo); + } } if(!useLegacyCodepath) diff --git a/physx/source/lowlevel/common/src/pipeline/PxcNpContactPrepShared.cpp b/physx/source/lowlevel/common/src/pipeline/PxcNpContactPrepShared.cpp index 8b50d7aee..62697b8f9 100644 --- a/physx/source/lowlevel/common/src/pipeline/PxcNpContactPrepShared.cpp +++ b/physx/source/lowlevel/common/src/pipeline/PxcNpContactPrepShared.cpp @@ -80,8 +80,8 @@ struct StridePatch PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT contactPoints, const PxU32 numContactPoints, PxcNpThreadContext* threadContext, PxU16& writtenContactCount, PxU8*& outContactPatches, PxU8*& outContactPoints, PxU16& compressedContactSize, PxReal*& outContactForces, PxU32 contactForceByteSize, - const PxsMaterialManager* materialManager, bool hasModifiableContacts, bool forceNoResponse, PxsMaterialInfo* PX_RESTRICT pMaterial, PxU8& numPatches, - PxU32 additionalHeaderSize, PxsConstraintBlockManager* manager, PxcConstraintBlockStream* blockStream, bool insertAveragePoint, + const PxsMaterialManager* materialManager, bool hasModifiableContacts, bool forceNoResponse, const PxsMaterialInfo* PX_RESTRICT pMaterial, PxU8& numPatches, + PxU32 additionalHeaderSize, PxsConstraintBlockManager* manager, PxcConstraintBlockStream* blockStream, bool insertAveragePoint, PxcDataStreamPool* contactStreamPool, PxcDataStreamPool* patchStreamPool, PxcDataStreamPool* forceStreamPool, const bool isMeshType) { if(numContactPoints == 0) @@ -101,13 +101,7 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont StridePatch* stridePatches = &strPatches[0]; PxU32 numStrideHeaders = 1; - - /*const bool hasInternalFaceIndex = contactPoints[0].internalFaceIndex0 != PXC_CONTACT_NO_FACE_INDEX || - contactPoints[0].internalFaceIndex1 != PXC_CONTACT_NO_FACE_INDEX;*/ - const bool isModifiable = !forceNoResponse && hasModifiableContacts; - PxU32 totalUniquePatches = 1; - PxU32 totalContactPoints = numContactPoints; PxU32 strideStart = 0; @@ -187,6 +181,7 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont //Calculate the number of patches/points required + const bool isModifiable = !forceNoResponse && hasModifiableContacts; const PxU32 patchHeaderSize = sizeof(PxContactPatch) * (isModifiable ? totalContactPoints : totalUniquePatches) + additionalHeaderSize; const PxU32 pointSize = totalContactPoints * (isModifiable ? sizeof(PxModifiableContact) : sizeof(PxContact)); @@ -272,7 +267,6 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont } totalRequiredSize = alignedRequiredSize; - } PxPrefetchLine(patchData); @@ -300,8 +294,6 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont #endif compressedContactSize = PxTo16(totalRequiredSize); - - //PxU32 startIndex = 0; //Extract first material @@ -320,9 +312,35 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont outContactPoints = contactData; outContactForces = forceData; + struct Local + { + static PX_FORCE_INLINE void fillPatch(PxContactPatch* PX_RESTRICT patch, const StridePatch& rootPatch, const PxVec3& normal, + PxU32 currentIndex, PxReal staticFriction, PxReal dynamicFriction, PxReal combinedRestitution, PxReal combinedDamping, + PxU32 materialFlags, PxU32 flags, PxU16 matIndex0, PxU16 matIndex1 + ) + { + patch->mMassModification.linear0 = 1.0f; + patch->mMassModification.linear1 = 1.0f; + patch->mMassModification.angular0 = 1.0f; + patch->mMassModification.angular1 = 1.0f; + PX_ASSERT(PxAbs(normal.magnitude() - 1) < 1e-3f); + patch->normal = normal; + patch->restitution = combinedRestitution; + patch->dynamicFriction = dynamicFriction; + patch->staticFriction = staticFriction; + patch->damping = combinedDamping; + patch->startContactIndex = PxTo8(currentIndex); + //KS - we could probably compress this further into the header but the complexity might not be worth it + patch->nbContacts = rootPatch.totalCount; + patch->materialFlags = PxU8(materialFlags); + patch->internalFlags = PxU8(flags); + patch->materialIndex0 = matIndex0; + patch->materialIndex1 = matIndex1; + } + }; + if(isModifiable) { - PxU32 flags = PxU32(isModifiable ? PxContactPatch::eMODIFIABLE : 0) | (forceNoResponse ? PxContactPatch::eFORCE_NO_RESPONSE : 0) | (isMeshType ? PxContactPatch::eHAS_FACE_INDICES : 0); @@ -336,9 +354,7 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont StridePatch& rootPatch = stridePatches[a]; if(rootPatch.isRoot) { - PxContactPatch* PX_RESTRICT patch = patches++; - - PxU32 startIndex = rootPatch.startIndex; + const PxU32 startIndex = rootPatch.startIndex; const PxU16 matIndex0 = pMaterial[startIndex].mMaterialIndex0; const PxU16 matIndex1 = pMaterial[startIndex].mMaterialIndex1; @@ -350,22 +366,8 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont origMatIndex1 = matIndex1; } - patch->nbContacts = rootPatch.totalCount; - - patch->startContactIndex = PxTo8(currentIndex); - patch->materialFlags = PxU8(materialFlags); - patch->staticFriction = staticFriction; - patch->dynamicFriction = dynamicFriction; - patch->restitution = combinedRestitution; - patch->damping = combinedDamping; - patch->materialIndex0 = matIndex0; - patch->materialIndex1 = matIndex1; - patch->normal = contactPoints[0].normal; - patch->mMassModification.mInvMassScale0 = 1.0f; - patch->mMassModification.mInvMassScale1 = 1.0f; - patch->mMassModification.mInvInertiaScale0 = 1.0f; - patch->mMassModification.mInvInertiaScale1 = 1.0f; - patch->internalFlags = PxU8(flags); + PxContactPatch* PX_RESTRICT patch = patches++; + Local::fillPatch(patch, rootPatch, contactPoints[startIndex].normal, currentIndex, staticFriction, dynamicFriction, combinedRestitution, combinedDamping, materialFlags, flags, matIndex0, matIndex1); //const PxU32 endIndex = strideHeader[a]; const PxU32 totalCountThisPatch = rootPatch.totalCount; @@ -397,7 +399,7 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont patch->nbContacts++; point->contact = avgPt * recipCount; point->separation = avgPen * recipCount; - point->normal = contactPoints[0].normal; + point->normal = contactPoints[startIndex].normal; point->maxImpulse = PX_MAX_REAL; point->targetVelocity = PxVec3(0.0f); point->staticFriction = staticFriction; @@ -456,8 +458,10 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont if(rootPatch.isRoot) { - const PxU16 matIndex0 = pMaterial[rootPatch.startIndex].mMaterialIndex0; - const PxU16 matIndex1 = pMaterial[rootPatch.startIndex].mMaterialIndex1; + const PxU32 startIndex = rootPatch.startIndex; + + const PxU16 matIndex0 = pMaterial[startIndex].mMaterialIndex0; + const PxU16 matIndex1 = pMaterial[startIndex].mMaterialIndex1; if(matIndex0 != origMatIndex0 || matIndex1 != origMatIndex1) { combineMaterials(materialManager, matIndex0, matIndex1, staticFriction, dynamicFriction, combinedRestitution, materialFlags, combinedDamping); @@ -467,23 +471,8 @@ PxU32 physx::writeCompressedContact(const PxContactPoint* const PX_RESTRICT cont } PxContactPatch* PX_RESTRICT patch = patches++; - patch->normal = contactPoints[rootPatch.startIndex].normal; - PX_ASSERT(PxAbs(patch->normal.magnitude() - 1) < 1e-3f); - patch->nbContacts = rootPatch.totalCount; - patch->startContactIndex = PxTo8(currentIndex); - //KS - we could probably compress this further into the header but the complexity might not be worth it - patch->staticFriction = staticFriction; - patch->dynamicFriction = dynamicFriction; - patch->restitution = combinedRestitution; - patch->damping = combinedDamping; - patch->materialIndex0 = matIndex0; - patch->materialIndex1 = matIndex1; - patch->materialFlags = PxU8(materialFlags); - patch->internalFlags = PxU8(flags); - patch->mMassModification.mInvMassScale0 = 1.0f; - patch->mMassModification.mInvMassScale1 = 1.0f; - patch->mMassModification.mInvInertiaScale0 = 1.0f; - patch->mMassModification.mInvInertiaScale1 = 1.0f; + Local::fillPatch(patch, rootPatch, contactPoints[startIndex].normal, currentIndex, staticFriction, dynamicFriction, combinedRestitution, combinedDamping, materialFlags, flags, matIndex0, matIndex1); + if(insertAveragePoint && (rootPatch.totalCount) > 1) { patch->nbContacts++; diff --git a/physx/source/lowlevel/common/src/pipeline/PxcNpMemBlockPool.cpp b/physx/source/lowlevel/common/src/pipeline/PxcNpMemBlockPool.cpp index a43dab3f2..04340c90f 100644 --- a/physx/source/lowlevel/common/src/pipeline/PxcNpMemBlockPool.cpp +++ b/physx/source/lowlevel/common/src/pipeline/PxcNpMemBlockPool.cpp @@ -35,22 +35,22 @@ using namespace physx; -PxcNpMemBlockPool::PxcNpMemBlockPool(PxcScratchAllocator& allocator): - mConstraints("PxcNpMemBlockPool::mConstraints"), - mExceptionalConstraints("PxcNpMemBlockPool::mExceptionalConstraints"), - mNpCacheActiveStream(0), - mFrictionActiveStream(0), - mCCDCacheActiveStream(0), - mContactIndex(0), - mAllocatedBlocks(0), - mMaxBlocks(0), - mUsedBlocks(0), - mMaxUsedBlocks(0), - mScratchBlockAddr(0), - mNbScratchBlocks(0), - mScratchAllocator(allocator), - mPeakConstraintAllocations(0), - mConstraintAllocations(0) +PxcNpMemBlockPool::PxcNpMemBlockPool(PxcScratchAllocator& allocator) : + mConstraints("PxcNpMemBlockPool::mConstraints"), + mExceptionalConstraints("PxcNpMemBlockPool::mExceptionalConstraints"), + mNpCacheActiveStream(0), + mFrictionActiveStream(0), + mCCDCacheActiveStream(0), + mContactIndex(0), + mAllocatedBlocks(0), + mMaxBlocks(0), + mUsedBlocks(0), + mMaxUsedBlocks(0), + mScratchBlockAddr(0), + mNbScratchBlocks(0), + mScratchAllocator(allocator), + mPeakConstraintAllocations(0), + mConstraintAllocations(0) { } @@ -209,7 +209,7 @@ PxcNpMemBlock* PxcNpMemBlockPool::acquire(PxcNpMemBlockArray& trackingArray, PxU if(mAllocatedBlocks == mMaxBlocks) { #if PX_CHECKED - PxGetFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + PxGetFoundation().error(PxErrorCode::eDEBUG_WARNING, PX_FL, "Reached maximum number of allocated blocks so 16k block allocation will fail!"); #endif return NULL; @@ -218,7 +218,7 @@ PxcNpMemBlock* PxcNpMemBlockPool::acquire(PxcNpMemBlockArray& trackingArray, PxU #if PX_CHECKED if(mInitialBlocks) { - PxGetFoundation().error(PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, + PxGetFoundation().error(PxErrorCode::eDEBUG_WARNING, PX_FL, "Number of required 16k memory blocks has exceeded the initial number of blocks. Allocator is being called. Consider increasing the number of pre-allocated 16k blocks."); } #endif diff --git a/physx/source/lowlevel/software/include/PxsCCD.h b/physx/source/lowlevel/software/include/PxsCCD.h index 5b750de70..9d3c19634 100644 --- a/physx/source/lowlevel/software/include/PxsCCD.h +++ b/physx/source/lowlevel/software/include/PxsCCD.h @@ -30,7 +30,6 @@ #include "foundation/PxHashMap.h" #include "foundation/PxUserAllocated.h" #include "GuCCDSweepConvexMesh.h" -#include "PxsIslandSim.h" #ifndef PXS_CCD_H #define PXS_CCD_H @@ -99,21 +98,9 @@ counter to determine if the shape needs its transforms re-calculated. This avoid */ struct PxsCCDShape : public Gu::CCDShape { -public: const PxsShapeCore* mShapeCore; //Shape core (can be shared) const PxsRigidCore* mRigidCore; //Rigid body core PxNodeIndex mNodeIndex; - - /** - \brief Returns the world-space pose for this shape - \param[in] atom The rigid body that this CCD shape is associated with - */ - PxTransform getAbsPose(const PxsRigidBody* atom) const; - /** - \brief Returns the world-space previous pose for this shape - \param[in] atom The rigid body that this CCD shape is associated with - */ - PxTransform getLastCCDAbsPose(const PxsRigidBody* atom) const; }; /** @@ -595,10 +582,7 @@ class PxsCCDContext : public PxUserAllocated PX_NOCOPY(PxsCCDContext) }; - } - - #endif diff --git a/physx/source/lowlevel/software/include/PxsContactManager.h b/physx/source/lowlevel/software/include/PxsContactManager.h index 070f2952e..41d74dfc6 100644 --- a/physx/source/lowlevel/software/include/PxsContactManager.h +++ b/physx/source/lowlevel/software/include/PxsContactManager.h @@ -141,10 +141,8 @@ class PxsContactManager friend class Dy::DynamicsContext; friend struct PxsCCDPair; - friend class PxsIslandManager; friend class PxsCCDContext; friend class Sc::ShapeInteraction; - //friend class Sc::SoftBodyShapeInteraction; }; } diff --git a/physx/source/lowlevel/software/include/PxsContactManagerState.h b/physx/source/lowlevel/software/include/PxsContactManagerState.h index 5bbad066c..f77809226 100644 --- a/physx/source/lowlevel/software/include/PxsContactManagerState.h +++ b/physx/source/lowlevel/software/include/PxsContactManagerState.h @@ -76,9 +76,6 @@ namespace physx PxU8 prevPatches; //Previous number of patches PxU16 nbContacts; //Num contacts PxU16 flags; //Not really part of outputs, but we have 4 bytes of padding, so why not? -#if PX_X86 - PxU32 pad[3]; -#endif PX_FORCE_INLINE PxU32* getInternalFaceIndice() { @@ -95,14 +92,6 @@ namespace physx PxU8 unused; //Unused } PX_ALIGN_SUFFIX(4); - struct PX_ALIGN_PREFIX(4) PxsContactManagerPersistency - { - PxU8 mPrevPatches; - PxU8 mNbFrictionPatches; - PxU8 mNbPrevFrictionPatches; - PxU8 pad; - } PX_ALIGN_SUFFIX(4); - struct PX_ALIGN_PREFIX(8) PxsTorsionalFrictionData { PxReal mTorsionalPatchRadius; diff --git a/physx/source/lowlevel/software/include/PxsContext.h b/physx/source/lowlevel/software/include/PxsContext.h index ea33e7b26..c3d86b16f 100644 --- a/physx/source/lowlevel/software/include/PxsContext.h +++ b/physx/source/lowlevel/software/include/PxsContext.h @@ -92,13 +92,12 @@ class PxsContext : public PxUserAllocated, public PxcNpContext { PX_NOCOPY(PxsContext) public: - PxsContext( const PxSceneDesc& desc, PxTaskManager*, Cm::FlushPool&, - PxCudaContextManager*, const PxU32 poolSlabSize, PxU64 contextID); + PxsContext( const PxSceneDesc& desc, PxTaskManager*, Cm::FlushPool&, PxCudaContextManager*, PxU32 poolSlabSize, PxU64 contextID); ~PxsContext(); void createTransformCache(PxVirtualAllocatorCallback& allocatorCallback); - PxsContactManager* createContactManager(PxsContactManager* contactManager, const bool useCCD); + PxsContactManager* createContactManager(PxsContactManager* contactManager, bool useCCD); void createCache(Gu::Cache& cache, PxGeometryType::Enum geomType0, PxGeometryType::Enum geomType1); void destroyCache(Gu::Cache& cache); void destroyContactManager(PxsContactManager* cm); @@ -131,11 +130,6 @@ class PxsContext : public PxUserAllocated, public PxcNpContext PxvContactManagerTouchEvent* lostTouch, PxI32& lostTouchCount, PxvContactManagerTouchEvent* ccdTouch, PxI32& ccdTouchCount); - bool fillManagerTouchEvents2( - PxvContactManagerTouchEvent* newTouch, PxI32& newTouchCount, - PxvContactManagerTouchEvent* lostTouch, PxI32& lostTouchCount, - PxvContactManagerTouchEvent* ccdTouch, PxI32& ccdTouchCount); - void beginUpdate(); // PX_ENABLE_SIM_STATS @@ -184,10 +178,8 @@ class PxsContext : public PxUserAllocated, public PxcNpContext PX_FORCE_INLINE PxvNphaseImplementationContext* getNphaseFallbackImplementationContext() const { return mNpFallbackImplementationContext; } PX_FORCE_INLINE void setNphaseFallbackImplementationContext(PxvNphaseImplementationContext* ctx) { mNpFallbackImplementationContext = ctx; } - PxU32 getTotalCompressedContactSize() const { return mTotalCompressedCacheSize; } - PxU32 getMaxPatchCount() const { return mMaxPatches; } - - PX_FORCE_INLINE PxcThreadCoherentCache& getNpThreadContextPool() { return mNpThreadContextPool; } + PxU32 getTotalCompressedContactSize() const { return mTotalCompressedCacheSize; } + PxU32 getMaxPatchCount() const { return mMaxPatches; } PX_FORCE_INLINE PxcNpThreadContext* getNpThreadContext() { @@ -296,14 +288,13 @@ class PxsContext : public PxUserAllocated, public PxcNpContext PxU32 mMaxPatches; PxU32 mTotalCompressedCacheSize; - PxU64 mContextID; + const PxU64 mContextID; friend class PxsCCDContext; friend class PxsNphaseImplementationContext; friend class PxgNphaseImplementationContext; //FDTODO ideally it shouldn't be here.. }; - PX_FORCE_INLINE void PxsContext::clearManagerTouchEvents() { mContactManagerTouchEvent.clear(); @@ -313,7 +304,6 @@ PX_FORCE_INLINE void PxsContext::clearManagerTouchEvents() } } - } #endif diff --git a/physx/source/lowlevel/software/include/PxsIslandManagerTypes.h b/physx/source/lowlevel/software/include/PxsIslandManagerTypes.h index 812b12e1b..2fd66e1b2 100644 --- a/physx/source/lowlevel/software/include/PxsIslandManagerTypes.h +++ b/physx/source/lowlevel/software/include/PxsIslandManagerTypes.h @@ -31,13 +31,10 @@ namespace physx { - class PxsContactManager; -class PxsRigidBody; namespace Dy { struct Constraint; - class Articulation; } typedef PxU32 NodeType; @@ -47,33 +44,6 @@ typedef PxU32 IslandType; #define INVALID_EDGE 0xffffffff #define INVALID_ISLAND 0xffffffff -//----------------------------------------------------------------------------// - -template class PxsIslandManagerHook -{ - friend class PxsIslandManager; - T index; - -public: - - static const T INVALID = INVLD; - - PX_FORCE_INLINE PxsIslandManagerHook(): index(INVLD) {} - PX_FORCE_INLINE PxsIslandManagerHook(const T id): index(id) {} - PX_FORCE_INLINE PxsIslandManagerHook(const PxsIslandManagerHook& src) : index(src.index) {} - PX_FORCE_INLINE ~PxsIslandManagerHook(){} - - PX_FORCE_INLINE bool isManaged() const { return index!=INVLD; } - -private: -}; - -typedef PxsIslandManagerHook PxsIslandManagerNodeHook; -typedef PxsIslandManagerHook PxsIslandManagerEdgeHook; -typedef PxsIslandManagerHook PxsIslandManagerIslandHook; - -//----------------------------------------------------------------------------// - class PxsIslandIndices { public: @@ -87,11 +57,8 @@ class PxsIslandIndices EdgeType constraints; }; -//----------------------------------------------------------------------------// - typedef PxU64 PxsNodeType; - /** \brief Each contact manager or constraint references two separate bodies, where a body can be a dynamic rigid body, a kinematic rigid body, an articulation or a static. @@ -125,8 +92,8 @@ struct PxsIndexedInteraction */ union { - PxsNodeType solverBody0; - PxsNodeType articulation0; + PxsNodeType solverBody0; + PxsNodeType articulation0; }; /** @@ -143,8 +110,8 @@ struct PxsIndexedInteraction */ union { - PxsNodeType solverBody1; - PxsNodeType articulation1; + PxsNodeType solverBody1; + PxsNodeType articulation1; }; /** @@ -192,45 +159,6 @@ struct PxsIndexedConstraint : public PxsIndexedInteraction PX_COMPILE_TIME_ASSERT(0==(sizeof(PxsIndexedConstraint) & 0x0f)); #endif -//----------------------------------------------------------------------------// - -/** -\brief Any sleeping contact pair that finds itself in an awake island after 1st pass island gen -must participate in 2nd pass narrowphase so that contacts can be generated. - -\note Contact managers in sleeping pairs are NULL until PxsIslandManager::setWokenPairContactManagers is complete. - -@see PxsIslandManager::getNarrowPhaseSecondPassContactManagers, PxsIslandManager::getNumNarrowPhaseSecondPassContactManagers, -PxsIslandManager::setWokenPairContactManagers -*/ -struct PxsNarrowPhaseSecondPassContactManager -{ - /** - \brief The contact manager that is to participate in 2nd pass narrowphase. - - \note This pointer is NULL after 1st pass island gen and remains NULL until PxsIslandManager::setWokenPairContactManagers - completes. - */ - PxsContactManager* mCM; - - /** - \brief The corresponding entry in PxsIslandObjects::contactManagers. - - \note All sleeping pairs have a null contact manager during 1st pass island gen. After 1st pass island gen completes, - the bodies to be woken are externally processed. Waking up bodies generates contact managers and passes the pointer to the - corresponding edge. So that the contact manager can be efficiently passed to PxsIslandObjects we store mEdgeId and mSolverCMId. - The contact manager pointers are set in PxsIslandManager::setWokenPairContactManagers - */ - EdgeType mSolverCMId; //Keeps a track of which entries in the solver islands temporarily have a null contact manager - - /** - \brief The internal id of the corresponding edge. - */ - EdgeType mEdgeId; -}; - - } //namespace physx - -#endif //PXS_ISLAND_MANAGER_TYPES_H +#endif diff --git a/physx/source/lowlevel/software/include/PxsIslandSim.h b/physx/source/lowlevel/software/include/PxsIslandSim.h index d722e1ca6..925dd95d5 100644 --- a/physx/source/lowlevel/software/include/PxsIslandSim.h +++ b/physx/source/lowlevel/software/include/PxsIslandSim.h @@ -38,7 +38,6 @@ namespace physx { - namespace Dy { struct Constraint; @@ -51,6 +50,7 @@ namespace Dy #endif } +// PT: TODO: fw declaring an Sc class here is not good namespace Sc { class ArticulationSim; @@ -63,13 +63,11 @@ struct PartitionEdge; namespace IG { - //This index is #define IG_INVALID_ISLAND 0xFFFFFFFFu #define IG_INVALID_EDGE 0xFFFFFFFFu #define IG_INVALID_LINK 0xFFu - typedef PxU32 IslandId; typedef PxU32 EdgeIndex; typedef PxU32 EdgeInstanceIndex; @@ -93,7 +91,6 @@ struct Edge eEDGE_TYPE_COUNT }; - enum EdgeState { eINSERTED =1<<0, @@ -105,15 +102,12 @@ struct Edge eACTIVATING =1<<6 }; - //NodeIndex mNode1, mNode2; EdgeType mEdgeType; PxU16 mEdgeState; EdgeIndex mNextIslandEdge, mPrevIslandEdge; - - PX_FORCE_INLINE void setInserted() { mEdgeState |= (eINSERTED); } PX_FORCE_INLINE void clearInserted() { mEdgeState &= (~eINSERTED); } @@ -177,7 +171,7 @@ class HandleManager return mCurrentHandle++; } - bool isNotFreeHandle(Handle handle) + bool isNotFreeHandle(Handle handle) const { for(PxU32 a = 0; a < mFreeHandles.size(); ++a) { @@ -197,7 +191,7 @@ class HandleManager mFreeHandles.pushBack(handle); } - bool isValidHandle(Handle handle) + bool isValidHandle(Handle handle) const { return handle < mCurrentHandle; } @@ -207,7 +201,6 @@ class HandleManager class Node { - public: enum NodeType { @@ -219,6 +212,7 @@ class Node eHAIRSYSTEM_TYPE, eTYPE_COUNT }; + enum State { eREADY_FOR_SLEEPING = 1u << 0, //! Ready to go to sleep @@ -229,6 +223,7 @@ class Node eACTIVATING = 1u << 5, //! Is in the activating list eDEACTIVATING = 1u << 6 //! It is being forced to deactivate this frame }; + EdgeInstanceIndex mFirstEdgeIndex; PxU8 mFlags; @@ -243,7 +238,6 @@ class Node //to be in the active kinematics list PxU32 mActiveRefCount; - //A node can correspond with either a rigid body or an articulation or softBody union { @@ -257,8 +251,6 @@ class Node #endif }; - - PX_FORCE_INLINE Node() : mFirstEdgeIndex(IG_INVALID_EDGE), mFlags(eDELETED), mType(eRIGID_BODY_TYPE), mStaticTouchCount(0), mActiveRefCount(0), mRigidBody(NULL) { @@ -296,44 +288,28 @@ class Node PX_FORCE_INLINE void setDeactivating() { mFlags |= eDEACTIVATING; } PX_FORCE_INLINE void clearDeactivating() { mFlags &= (~eDEACTIVATING); } - //Activates a body/node. - PX_FORCE_INLINE void setIsReadyForSleeping() { mFlags |= eREADY_FOR_SLEEPING; } - - PX_FORCE_INLINE void clearIsReadyForSleeping(){ mFlags &= (~eREADY_FOR_SLEEPING);} - - PX_FORCE_INLINE void setIsDeleted(){mFlags |= eDELETED; } - - PX_FORCE_INLINE void setKinematicFlag() {PX_ASSERT(!isKinematic()); mFlags |= eKINEMATIC;} - - PX_FORCE_INLINE void clearKinematicFlag(){ PX_ASSERT(isKinematic()); mFlags &= (~eKINEMATIC);} - - PX_FORCE_INLINE void markDirty(){mFlags |= eDIRTY;} - - PX_FORCE_INLINE void clearDirty(){mFlags &= (~eDIRTY);} + PX_FORCE_INLINE void setIsReadyForSleeping() { mFlags |= eREADY_FOR_SLEEPING; } + PX_FORCE_INLINE void clearIsReadyForSleeping() { mFlags &= (~eREADY_FOR_SLEEPING); } + PX_FORCE_INLINE void setIsDeleted() { mFlags |= eDELETED; } + PX_FORCE_INLINE void setKinematicFlag() { PX_ASSERT(!isKinematic()); mFlags |= eKINEMATIC; } + PX_FORCE_INLINE void clearKinematicFlag() { PX_ASSERT(isKinematic()); mFlags &= (~eKINEMATIC); } + PX_FORCE_INLINE void markDirty() { mFlags |= eDIRTY; } + PX_FORCE_INLINE void clearDirty() { mFlags &= (~eDIRTY); } public: - PX_FORCE_INLINE bool isActive() const { return !!(mFlags & eACTIVE); } - - PX_FORCE_INLINE bool isActiveOrActivating() const { return !!(mFlags & (eACTIVE | eACTIVATING)); } - - PX_FORCE_INLINE bool isActivating() const { return !!(mFlags & eACTIVATING); } - - PX_FORCE_INLINE bool isDeactivating() const { return !!(mFlags & eDEACTIVATING); } - - PX_FORCE_INLINE bool isKinematic() const { return !!(mFlags & eKINEMATIC); } - - PX_FORCE_INLINE bool isDeleted() const { return !!(mFlags & eDELETED); } - - PX_FORCE_INLINE bool isDirty() const { return !!(mFlags & eDIRTY); } - - PX_FORCE_INLINE bool isReadyForSleeping() const { return !!(mFlags & eREADY_FOR_SLEEPING); } - - PX_FORCE_INLINE NodeType getNodeType() const { return NodeType(mType); } + PX_FORCE_INLINE bool isActive() const { return !!(mFlags & eACTIVE); } + PX_FORCE_INLINE bool isActiveOrActivating() const { return !!(mFlags & (eACTIVE | eACTIVATING)); } + PX_FORCE_INLINE bool isActivating() const { return !!(mFlags & eACTIVATING); } + PX_FORCE_INLINE bool isDeactivating() const { return !!(mFlags & eDEACTIVATING); } + PX_FORCE_INLINE bool isKinematic() const { return !!(mFlags & eKINEMATIC); } + PX_FORCE_INLINE bool isDeleted() const { return !!(mFlags & eDELETED); } + PX_FORCE_INLINE bool isDirty() const { return !!(mFlags & eDIRTY); } + PX_FORCE_INLINE bool isReadyForSleeping() const { return !!(mFlags & eREADY_FOR_SLEEPING); } + PX_FORCE_INLINE NodeType getNodeType() const { return NodeType(mType); } friend class SimpleIslandManager; - }; struct Island @@ -407,84 +383,82 @@ struct NodeComparator NodeComparator& operator = (const NodeComparator&); }; - class IslandSim { - HandleManager mIslandHandles; //! Handle manager for islands + PX_NOCOPY(IslandSim) - PxArray mNodes; //! The nodes used in the constraint graph - PxArray mActiveNodeIndex; //! The active node index for each node - Cm::BlockArray mEdges; - Cm::BlockArray mEdgeInstances; //! Edges used to connect nodes in the constraint graph - PxArray mIslands; //! The array of islands - PxArray mIslandStaticTouchCount; //! Array of static touch counts per-island + HandleManager mIslandHandles; //! Handle manager for islands + PxArray mNodes; //! The nodes used in the constraint graph + PxArray mActiveNodeIndex; //! The active node index for each node + Cm::BlockArray mEdges; + Cm::BlockArray mEdgeInstances; //! Edges used to connect nodes in the constraint graph + PxArray mIslands; //! The array of islands + PxArray mIslandStaticTouchCount; //! Array of static touch counts per-island - PxArray mActiveNodes[Node::eTYPE_COUNT]; //! An array of active nodes - PxArray mActiveKinematicNodes; //! An array of active or referenced kinematic nodes - PxArray mActivatedEdges[Edge::eEDGE_TYPE_COUNT]; //! An array of active edges + PxArray mActiveNodes[Node::eTYPE_COUNT]; //! An array of active nodes + PxArray mActiveKinematicNodes; //! An array of active or referenced kinematic nodes + PxArray mActivatedEdges[Edge::eEDGE_TYPE_COUNT]; //! An array of active edges - PxU32 mActiveEdgeCount[Edge::eEDGE_TYPE_COUNT]; + PxU32 mActiveEdgeCount[Edge::eEDGE_TYPE_COUNT]; - PxArray mHopCounts; //! The observed number of "hops" from a given node to its root node. May be inaccurate but used to accelerate searches. - PxArray mFastRoute; //! The observed last route from a given node to the root node. We try the fast route (unless its broken) before trying others. + PxArray mHopCounts; //! The observed number of "hops" from a given node to its root node. May be inaccurate but used to accelerate searches. + PxArray mFastRoute; //! The observed last route from a given node to the root node. We try the fast route (unless its broken) before trying others. - PxArray mIslandIds; //! The array of per-node island ids + PxArray mIslandIds; //! The array of per-node island ids - PxBitMap mIslandAwake; //! Indicates whether an island is awake or not + PxBitMap mIslandAwake; //! Indicates whether an island is awake or not - PxBitMap mActiveContactEdges; + PxBitMap mActiveContactEdges; //An array of active islands - PxArray mActiveIslands; + PxArray mActiveIslands; - PxU32 mInitialActiveNodeCount[Edge::eEDGE_TYPE_COUNT]; + PxU32 mInitialActiveNodeCount[Edge::eEDGE_TYPE_COUNT]; - PxArray mNodesToPutToSleep[Node::eTYPE_COUNT]; + PxArray mNodesToPutToSleep[Node::eTYPE_COUNT]; //Input to this frame's island management (changed nodes/edges) //Input list of changes observed this frame. If there no changes, no work to be done. - PxArray mDirtyEdges[Edge::eEDGE_TYPE_COUNT]; + PxArray mDirtyEdges[Edge::eEDGE_TYPE_COUNT]; //Dirty nodes. These nodes lost at least one connection so we need to recompute islands from these nodes - //PxArray mDirtyNodes; - PxBitMap mDirtyMap; - PxU32 mLastMapIndex; + //PxArray mDirtyNodes; + PxBitMap mDirtyMap; + PxU32 mLastMapIndex; //An array of nodes to activate - PxArray mActivatingNodes; - PxArray mDestroyedEdges; - PxArray mTempIslandIds; + PxArray mActivatingNodes; + PxArray mDestroyedEdges; + PxArray mTempIslandIds; - //Temporary, transient data used for traversals. TODO - move to PxsSimpleIslandManager. Or if we keep it here, we can //process multiple island simulations in parallel - Cm::PriorityQueue - mPriorityQueue; //! Priority queue used for graph traversal - PxArray mVisitedNodes; //! The list of nodes visited in the current traversal - PxBitMap mVisitedState; //! Indicates whether a node has been visited - PxArray mIslandSplitEdges[Edge::eEDGE_TYPE_COUNT]; + Cm::PriorityQueue mPriorityQueue; //! Priority queue used for graph traversal + PxArray mVisitedNodes; //! The list of nodes visited in the current traversal + PxBitMap mVisitedState; //! Indicates whether a node has been visited + PxArray mIslandSplitEdges[Edge::eEDGE_TYPE_COUNT]; - PxArray mDeactivatingEdges[Edge::eEDGE_TYPE_COUNT]; + PxArray mDeactivatingEdges[Edge::eEDGE_TYPE_COUNT]; - PxArray* mFirstPartitionEdges; - Cm::BlockArray& mEdgeNodeIndices; - PxArray* mDestroyedPartitionEdges; + PxArray* mFirstPartitionEdges; + Cm::BlockArray& mEdgeNodeIndices; + PxArray* mDestroyedPartitionEdges; - PxU32* mNpIndexPtr; + PxU32* mNpIndexPtr; - PxU64 mContextId; + const PxU64 mContextId; public: IslandSim(PxArray* firstPartitionEdges, Cm::BlockArray& edgeNodeIndices, PxArray* destroyedPartitionEdges, PxU64 contextID); ~IslandSim() {} - void resize(const PxU32 nbNodes, const PxU32 nbContactManagers, const PxU32 nbConstraints); + //void resize(const PxU32 nbNodes, const PxU32 nbContactManagers, const PxU32 nbConstraints); void addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive, PxNodeIndex nodeIndex); - void addArticulation(Sc::ArticulationSim* articulation, Dy::FeatherstoneArticulation* llArtic, bool isActive, PxNodeIndex nodeIndex); + void addArticulation(Dy::FeatherstoneArticulation* llArtic, bool isActive, PxNodeIndex nodeIndex); #if PX_SUPPORT_GPU_PHYSX void addSoftBody(Dy::SoftBody* llArtic, bool isActive, PxNodeIndex nodeIndex); @@ -496,7 +470,7 @@ class IslandSim void addHairSystem(Dy::HairSystem* llHairSystem, bool isActive, PxNodeIndex nodeIndex); #endif - void addContactManager(PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, EdgeIndex handle); + //void addContactManager(PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, EdgeIndex handle); void addConstraint(Dy::Constraint* constraint, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, EdgeIndex handle); @@ -549,6 +523,7 @@ class IslandSim return node.mLLArticulation; } + // PT: this one is questionable here Sc::ArticulationSim* getArticulationSim(PxNodeIndex nodeIndex) const; #if PX_SUPPORT_GPU_PHYSX @@ -623,12 +598,9 @@ class IslandSim void setDynamic(PxNodeIndex nodeIndex); - PX_FORCE_INLINE void setEdgeNodeIndexPtr(PxU32* ptr) { mNpIndexPtr = ptr; } - PX_FORCE_INLINE PxNodeIndex getNodeIndex1(IG::EdgeIndex index) const { return mEdgeNodeIndices[2 * index]; } PX_FORCE_INLINE PxNodeIndex getNodeIndex2(IG::EdgeIndex index) const { return mEdgeNodeIndices[2 * index + 1]; } - PX_FORCE_INLINE PxU32* getEdgeNodeIndexPtr() const { return mNpIndexPtr; } PX_FORCE_INLINE PxU64 getContextId() const { return mContextId; } PxU32 getNbIslands() const { return mIslandStaticTouchCount.size(); } @@ -637,8 +609,7 @@ class IslandSim const PxU32* getIslandIds() const { return mIslandIds.begin(); } - bool checkInternalConsistency(); - + bool checkInternalConsistency() const; PX_INLINE void activateNode_ForGPUSolver(PxNodeIndex index) { @@ -652,6 +623,11 @@ class IslandSim node.setIsReadyForSleeping(); } + // PT: these ones are strange, used to store an unrelated ptr from the outside, and only for GPU + // Why do we store that here? What happens on the CPU ? + PX_FORCE_INLINE void setEdgeNodeIndexPtr(PxU32* ptr) { mNpIndexPtr = ptr; } + PX_FORCE_INLINE PxU32* getEdgeNodeIndexPtr() const { return mNpIndexPtr; } + private: void insertNewEdges(); @@ -675,10 +651,6 @@ class IslandSim void mergeIslandsInternal(Island& island0, Island& island1, IslandId islandId0, IslandId islandId1, PxNodeIndex node0, PxNodeIndex node1); - - IslandSim& operator = (const IslandSim&); - IslandSim(const IslandSim&); - void unwindRoute(PxU32 traversalIndex, PxNodeIndex lastNode, PxU32 hopCount, IslandId id); void activateIsland(IslandId island); @@ -691,7 +663,7 @@ class IslandSim bool findRoute(PxNodeIndex startNode, PxNodeIndex targetNode, IslandId islandId); - bool isPathTo(PxNodeIndex startNode, PxNodeIndex targetNode); + bool isPathTo(PxNodeIndex startNode, PxNodeIndex targetNode) const; void addNode(bool isActive, bool isKinematic, Node::NodeType type, PxNodeIndex nodeIndex); @@ -871,7 +843,6 @@ class IslandSim node.mActiveRefCount++; } } - } void removeEdgeFromActivatingList(EdgeIndex index); @@ -962,19 +933,15 @@ class IslandSim friend class SimpleIslandManager; friend class ThirdPassTask; - }; - - } - struct PartitionIndexData { - PxU16 mPartitionIndex; //! The current partition this edge is in. Used to find the edge efficiently. PxU8 is probably too small (256 partitions max) but PxU16 should be more than enough - PxU8 mPatchIndex; //! The patch index for this partition edge. There may be multiple entries for a given edge if there are multiple patches. - PxU8 mCType; //! The type of constraint this is - PxU32 mPartitionEntryIndex; //! index of partition edges for this partition + PxU16 mPartitionIndex; //! The current partition this edge is in. Used to find the edge efficiently. PxU8 is probably too small (256 partitions max) but PxU16 should be more than enough + PxU8 mPatchIndex; //! The patch index for this partition edge. There may be multiple entries for a given edge if there are multiple patches. + PxU8 mCType; //! The type of constraint this is + PxU32 mPartitionEntryIndex; //! index of partition edges for this partition }; struct PartitionNodeData @@ -985,23 +952,21 @@ struct PartitionNodeData PxU32 mNextIndex1; }; - #define INVALID_PARTITION_INDEX 0xFFFF struct PartitionEdge { - IG::EdgeIndex mEdgeIndex; //! The edge index into the island manager. Used to identify the contact manager/constraint - PxNodeIndex mNode0; //! The node index for node 0. Can be obtained from the edge index alternatively - PxNodeIndex mNode1; //! The node idnex for node 1. Can be obtained from the edge index alternatively - bool mInfiniteMass0; //! Whether body 0 is kinematic - bool mArticulation0; //! Whether body 0 is an articulation link - bool mInfiniteMass1; //! Whether body 1 is kinematic - bool mArticulation1; //! Whether body 1 is an articulation link - - PartitionEdge* mNextPatch; //! for the contact manager has more than 1 patch, we have next patch's edge and previous patch's edge to connect to this edge + IG::EdgeIndex mEdgeIndex; //! The edge index into the island manager. Used to identify the contact manager/constraint + PxNodeIndex mNode0; //! The node index for node 0. Can be obtained from the edge index alternatively + PxNodeIndex mNode1; //! The node idnex for node 1. Can be obtained from the edge index alternatively + bool mInfiniteMass0; //! Whether body 0 is kinematic + bool mArticulation0; //! Whether body 0 is an articulation link + bool mInfiniteMass1; //! Whether body 1 is kinematic + bool mArticulation1; //! Whether body 1 is an articulation link - PxU32 mUniqueIndex; //! a unique ID for this edge + PartitionEdge* mNextPatch; //! for the contact manager has more than 1 patch, we have next patch's edge and previous patch's edge to connect to this edge + PxU32 mUniqueIndex; //! a unique ID for this edge //KS - This constructor explicitly does not set mUniqueIndex. It is filled in by the pool allocator and this constructor //is called afterwards. We do not want to stomp the uniqueIndex value diff --git a/physx/source/lowlevel/software/include/PxsKernelWrangler.h b/physx/source/lowlevel/software/include/PxsKernelWrangler.h index 59277889e..16edc4f0d 100644 --- a/physx/source/lowlevel/software/include/PxsKernelWrangler.h +++ b/physx/source/lowlevel/software/include/PxsKernelWrangler.h @@ -34,6 +34,7 @@ namespace physx { + class PxCudaContextManager; class KernelWrangler; class PxErrorCallback; @@ -42,6 +43,7 @@ namespace physx public: virtual ~PxsKernelWranglerManager(){} virtual KernelWrangler* getKernelWrangler() = 0; + virtual PxCudaContextManager* getCudaContextManager() = 0; }; } #endif \ No newline at end of file diff --git a/physx/source/lowlevel/software/include/PxsNphaseCommon.h b/physx/source/lowlevel/software/include/PxsNphaseCommon.h index 1893a8271..a4d4b647d 100644 --- a/physx/source/lowlevel/software/include/PxsNphaseCommon.h +++ b/physx/source/lowlevel/software/include/PxsNphaseCommon.h @@ -38,8 +38,7 @@ namespace physx struct PxsContactManagerBase { static const PxU32 NEW_CONTACT_MANAGER_MASK = 0x80000000; - static const PxU32 MaxBucketBits = 6; - static const PxU32 GPU_NP_OFFSET = 32;// GPU_BUCKET_ID::eCount; + static const PxU32 MaxBucketBits = 7; const PxU32 mBucketId; diff --git a/physx/source/lowlevel/software/include/PxsNphaseImplementationContext.h b/physx/source/lowlevel/software/include/PxsNphaseImplementationContext.h index 8f4673a6e..3d557573f 100644 --- a/physx/source/lowlevel/software/include/PxsNphaseImplementationContext.h +++ b/physx/source/lowlevel/software/include/PxsNphaseImplementationContext.h @@ -72,107 +72,98 @@ struct PxsContactManagers : PxsContactManagerBase PX_NOCOPY(PxsContactManagers) }; -class PxsNphaseImplementationContext: public PxvNphaseImplementationContextUsableAsFallback +class PxsNphaseImplementationContext : public PxvNphaseImplementationContextUsableAsFallback { public: - static PxsNphaseImplementationContext* create(PxsContext& context, IG::IslandSim* islandSim, PxVirtualAllocatorCallback* allocator); - - PxsNphaseImplementationContext(PxsContext& context, IG::IslandSim* islandSim, PxVirtualAllocatorCallback* callback, PxU32 index = 0) : + PxsNphaseImplementationContext(PxsContext& context, IG::IslandSim* islandSim, PxVirtualAllocatorCallback* callback, PxU32 index, bool gpu) : PxvNphaseImplementationContextUsableAsFallback (context), mNarrowPhasePairs (index, callback), mNewNarrowPhasePairs (index, callback), mModifyCallback (NULL), - mIslandSim(islandSim) {} + mIslandSim (islandSim), + mGPU (gpu) + {} - virtual void destroy(); + // PxvNphaseImplementationContext + virtual void destroy() PX_OVERRIDE; virtual void updateContactManager(PxReal dt, bool hasBoundsArrayChanged, bool hasContactDistanceChanged, PxBaseTask* continuation, - PxBaseTask* firstPassContinuation, Cm::FanoutTask* updateBoundAndShape); - virtual void postBroadPhaseUpdateContactManager(PxBaseTask*) {} - virtual void secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation); - - virtual void registerContactManager(PxsContactManager* cm, Sc::ShapeInteraction* shapeInteraction, PxI32 touching, PxU32 numPatches); + PxBaseTask* firstPassContinuation, Cm::FanoutTask* updateBoundAndShape) PX_OVERRIDE; + virtual void postBroadPhaseUpdateContactManager(PxBaseTask*) PX_OVERRIDE {} + virtual void secondPassUpdateContactManager(PxReal dt, PxBaseTask* continuation) PX_OVERRIDE; + virtual void fetchUpdateContactManager() PX_OVERRIDE {} + virtual void registerContactManager(PxsContactManager* cm, Sc::ShapeInteraction* shapeInteraction, PxI32 touching, PxU32 numPatches) PX_OVERRIDE; // virtual void registerContactManagers(PxsContactManager** cm, Sc::ShapeInteraction** shapeInteractions, PxU32 nbContactManagers, PxU32 maxContactManagerId); - virtual void unregisterContactManager(PxsContactManager* cm); - virtual void unregisterContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs); - - virtual void refreshContactManager(PxsContactManager* cm); - virtual void refreshContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs); - - virtual void registerShape(const PxNodeIndex& /*nodeIndex*/, const PxsShapeCore& /*shapeCore*/, const PxU32 /*transformCacheID*/, PxActor* /*actor*/, const bool /*isFemCloth*/) {} - virtual void unregisterShape(const PxsShapeCore& /*shapeCore*/, const PxU32 /*transformCacheID*/, const bool /*isFemCloth*/) {} - - virtual void registerAggregate(const PxU32 /*transformCacheID*/) {} - - virtual void updateShapeMaterial(const PxsShapeCore&) {} - virtual void updateShapeContactOffset(const PxsShapeCore&) {} - - virtual void registerMaterial(const PxsMaterialCore&) {} - virtual void updateMaterial(const PxsMaterialCore&) {} - virtual void unregisterMaterial(const PxsMaterialCore&) {} + virtual void unregisterContactManager(PxsContactManager* cm) PX_OVERRIDE; + virtual void refreshContactManager(PxsContactManager* cm) PX_OVERRIDE; - virtual void registerMaterial(const PxsFEMSoftBodyMaterialCore&) {} - virtual void updateMaterial(const PxsFEMSoftBodyMaterialCore&) {} - virtual void unregisterMaterial(const PxsFEMSoftBodyMaterialCore&) {} + virtual void registerShape(const PxNodeIndex& /*nodeIndex*/, const PxsShapeCore& /*shapeCore*/, const PxU32 /*transformCacheID*/, PxActor* /*actor*/, const bool /*isFemCloth*/) PX_OVERRIDE {} + virtual void unregisterShape(const PxsShapeCore& /*shapeCore*/, const PxU32 /*transformCacheID*/, const bool /*isFemCloth*/) PX_OVERRIDE {} - virtual void registerMaterial(const PxsFEMClothMaterialCore&) {} - virtual void updateMaterial(const PxsFEMClothMaterialCore&) {} - virtual void unregisterMaterial(const PxsFEMClothMaterialCore&) {} + virtual void registerAggregate(const PxU32 /*transformCacheID*/) PX_OVERRIDE {} - virtual void registerMaterial(const PxsPBDMaterialCore&) {} - virtual void updateMaterial(const PxsPBDMaterialCore&) {} - virtual void unregisterMaterial(const PxsPBDMaterialCore&) {} + virtual void registerMaterial(const PxsMaterialCore&) PX_OVERRIDE {} + virtual void updateMaterial(const PxsMaterialCore&) PX_OVERRIDE {} + virtual void unregisterMaterial(const PxsMaterialCore&) PX_OVERRIDE {} - virtual void registerMaterial(const PxsFLIPMaterialCore&) {} - virtual void updateMaterial(const PxsFLIPMaterialCore&) {} - virtual void unregisterMaterial(const PxsFLIPMaterialCore&) {} + virtual void registerMaterial(const PxsFEMSoftBodyMaterialCore&) PX_OVERRIDE {} + virtual void updateMaterial(const PxsFEMSoftBodyMaterialCore&) PX_OVERRIDE {} + virtual void unregisterMaterial(const PxsFEMSoftBodyMaterialCore&) PX_OVERRIDE {} - virtual void registerMaterial(const PxsMPMMaterialCore&) {} - virtual void updateMaterial(const PxsMPMMaterialCore&) {} - virtual void unregisterMaterial(const PxsMPMMaterialCore&) {} + virtual void registerMaterial(const PxsFEMClothMaterialCore&) PX_OVERRIDE {} + virtual void updateMaterial(const PxsFEMClothMaterialCore&) PX_OVERRIDE {} + virtual void unregisterMaterial(const PxsFEMClothMaterialCore&) PX_OVERRIDE {} - virtual void registerMaterial(const PxsCustomMaterialCore&) {} - virtual void updateMaterial(const PxsCustomMaterialCore&) {} - virtual void unregisterMaterial(const PxsCustomMaterialCore&) {} + virtual void registerMaterial(const PxsPBDMaterialCore&) PX_OVERRIDE {} + virtual void updateMaterial(const PxsPBDMaterialCore&) PX_OVERRIDE {} + virtual void unregisterMaterial(const PxsPBDMaterialCore&) PX_OVERRIDE {} - virtual void appendContactManagers(); - virtual void appendContactManagersFallback(PxsContactManagerOutput* cmOutputs); + virtual void registerMaterial(const PxsFLIPMaterialCore&) PX_OVERRIDE {} + virtual void updateMaterial(const PxsFLIPMaterialCore&) PX_OVERRIDE {} + virtual void unregisterMaterial(const PxsFLIPMaterialCore&) PX_OVERRIDE {} - virtual void removeContactManagersFallback(PxsContactManagerOutput* cmOutputs); + virtual void registerMaterial(const PxsMPMMaterialCore&) PX_OVERRIDE {} + virtual void updateMaterial(const PxsMPMMaterialCore&) PX_OVERRIDE {} + virtual void unregisterMaterial(const PxsMPMMaterialCore&) PX_OVERRIDE {} - virtual void setContactModifyCallback(PxContactModifyCallback* callback) { mModifyCallback = callback; } + virtual void updateShapeMaterial(const PxsShapeCore&) PX_OVERRIDE {} - virtual PxsContactManagerOutputIterator getContactManagerOutputs(); + virtual void startNarrowPhaseTasks() PX_OVERRIDE {} - virtual PxsContactManagerOutput& getNewContactManagerOutput(PxU32 npIndex); + virtual void appendContactManagers() PX_OVERRIDE; - virtual void acquireContext(){} - virtual void releaseContext(){} - virtual void preallocateNewBuffers(PxU32 /*nbNewPairs*/, PxU32 /*maxIndex*/) { /*TODO - implement if it's useful to do so*/} + virtual PxsContactManagerOutput& getNewContactManagerOutput(PxU32 npIndex) PX_OVERRIDE; - virtual PxsContactManagerOutputCounts* getFoundPatchOutputCounts() { return mCmFoundLostOutputCounts.begin(); } - virtual PxsContactManager** getFoundPatchManagers() { return mCmFoundLost.begin(); } - virtual PxU32 getNbFoundPatchManagers() { return mCmFoundLost.size(); } + virtual PxsContactManagerOutputIterator getContactManagerOutputs() PX_OVERRIDE; + virtual void setContactModifyCallback(PxContactModifyCallback* callback) PX_OVERRIDE { mModifyCallback = callback; } - void processContactManager(PxReal dt, PxsContactManagerOutput* cmOutputs, PxBaseTask* continuation); - void processContactManagerSecondPass(PxReal dt, PxBaseTask* continuation); - void fetchUpdateContactManager() {} + virtual void acquireContext() PX_OVERRIDE {} + virtual void releaseContext() PX_OVERRIDE {} + virtual void preallocateNewBuffers(PxU32 /*nbNewPairs*/, PxU32 /*maxIndex*/) PX_OVERRIDE { /*TODO - implement if it's useful to do so*/} + virtual void lock() PX_OVERRIDE { mContactManagerMutex.lock(); } + virtual void unlock() PX_OVERRIDE { mContactManagerMutex.unlock(); } - void appendNewLostPairs(); - - void startNarrowPhaseTasks() {} + virtual PxsContactManagerOutputCounts* getFoundPatchOutputCounts() PX_OVERRIDE { return mCmFoundLostOutputCounts.begin(); } + virtual PxsContactManager** getFoundPatchManagers() PX_OVERRIDE { return mCmFoundLost.begin(); } + virtual PxU32 getNbFoundPatchManagers() PX_OVERRIDE { return mCmFoundLost.size(); } - virtual void lock() { mContactManagerMutex.lock(); } - virtual void unlock() { mContactManagerMutex.unlock(); } + virtual PxsContactManagerOutput* getGPUContactManagerOutputBase() PX_OVERRIDE { return NULL; } + virtual PxReal* getGPURestDistances() PX_OVERRIDE { return NULL; } + virtual Sc::ShapeInteraction** getGPUShapeInteractions() PX_OVERRIDE { return NULL; } + virtual PxsTorsionalFrictionData* getGPUTorsionalData() PX_OVERRIDE { return NULL; } + //~PxvNphaseImplementationContext - virtual Sc::ShapeInteraction** getShapeInteractions() { return mNarrowPhasePairs.mShapeInteractions.begin(); } - virtual PxReal* getRestDistances() { return mNarrowPhasePairs.mRestDistances.begin(); } - virtual PxsTorsionalFrictionData* getTorsionalData() { return mNarrowPhasePairs.mTorsionalProperties.begin(); } + // PxvNphaseImplementationFallback + virtual void processContactManager(PxReal dt, PxsContactManagerOutput* cmOutputs, PxBaseTask* continuation) PX_OVERRIDE; + virtual void processContactManagerSecondPass(PxReal dt, PxBaseTask* continuation) PX_OVERRIDE; + virtual void unregisterContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs) PX_OVERRIDE; + virtual void refreshContactManagerFallback(PxsContactManager* cm, PxsContactManagerOutput* cmOutputs) PX_OVERRIDE; + virtual void appendContactManagersFallback(PxsContactManagerOutput* cmOutputs) PX_OVERRIDE; + virtual void removeContactManagersFallback(PxsContactManagerOutput* cmOutputs) PX_OVERRIDE; + virtual Sc::ShapeInteraction** getShapeInteractions() PX_OVERRIDE { return mNarrowPhasePairs.mShapeInteractions.begin(); } + virtual PxReal* getRestDistances() PX_OVERRIDE { return mNarrowPhasePairs.mRestDistances.begin(); } + virtual PxsTorsionalFrictionData* getTorsionalData() PX_OVERRIDE { return mNarrowPhasePairs.mTorsionalProperties.begin(); } + //~PxvNphaseImplementationFallback - virtual PxsContactManagerOutput* getGPUContactManagerOutputBase() { return NULL; } - virtual PxReal* getGPURestDistances() { return NULL; } - virtual Sc::ShapeInteraction** getGPUShapeInteractions() { return NULL; } - virtual PxsTorsionalFrictionData* getGPUTorsionalData() { return NULL; } - PxArray mRemovedContactManagers; PxsContactManagers mNarrowPhasePairs; PxsContactManagers mNewNarrowPhasePairs; @@ -187,6 +178,9 @@ class PxsNphaseImplementationContext: public PxvNphaseImplementationContextUsabl PxArray mCmFoundLostOutputCounts; PxArray mCmFoundLost; + + const bool mGPU; + private: void unregisterContactManagerInternal(PxU32 npIndex, PxsContactManagers& managers, PxsContactManagerOutput* cmOutputs); @@ -196,6 +190,8 @@ class PxsNphaseImplementationContext: public PxvNphaseImplementationContextUsabl cms.mOutputContactManagers.forceSize_Unsafe(cms.mOutputContactManagers.size()-1); } + void appendNewLostPairs(); + PX_NOCOPY(PxsNphaseImplementationContext) }; diff --git a/physx/source/lowlevel/software/include/PxsRigidBody.h b/physx/source/lowlevel/software/include/PxsRigidBody.h index 78b20da47..7c8febfe8 100644 --- a/physx/source/lowlevel/software/include/PxsRigidBody.h +++ b/physx/source/lowlevel/software/include/PxsRigidBody.h @@ -55,7 +55,7 @@ class PxsRigidBody // PT: this flag is now only used on the GPU. For the CPU the data is now stored directly in PxsBodyCore. eDISABLE_GRAVITY_GPU = 1 << 5, eSPECULATIVE_CCD = 1 << 6, - eENABLE_GYROSCROPIC = 1 << 7, + eENABLE_GYROSCOPIC = 1 << 7, //KS - copied here for GPU simulation to avoid needing to pass another set of flags around. eLOCK_LINEAR_X = 1 << (PX_INTERNAL_LOCK_FLAG_START), eLOCK_LINEAR_Y = 1 << (PX_INTERNAL_LOCK_FLAG_START + 1), @@ -122,7 +122,9 @@ class PxsRigidBody PX_FORCE_INLINE PxU32 isUnfreezeThisFrame() const { return PxU32(mInternalFlags & eUNFREEZE_THIS_FRAME); } PX_FORCE_INLINE void clearFreezeFlag() { mInternalFlags &= ~eFREEZE_THIS_FRAME; } PX_FORCE_INLINE void clearUnfreezeFlag() { mInternalFlags &= ~eUNFREEZE_THIS_FRAME; } - PX_FORCE_INLINE void clearAllFrameFlags() { mInternalFlags &= ~(eFREEZE_THIS_FRAME | eUNFREEZE_THIS_FRAME | eACTIVATE_THIS_FRAME | eDEACTIVATE_THIS_FRAME); } + PX_FORCE_INLINE void clearAllFrameFlags() { mInternalFlags &= ~(eFREEZE_THIS_FRAME | eUNFREEZE_THIS_FRAME | eACTIVATE_THIS_FRAME | eDEACTIVATE_THIS_FRAME); } + + PX_FORCE_INLINE void resetSleepFilter() { sleepAngVelAcc = sleepLinVelAcc = PxVec3(0.0f); } // PT: implemented in PxsCCD.cpp: void advanceToToi(PxReal toi, PxReal dt, bool clip); diff --git a/physx/source/lowlevel/software/include/PxsSimpleIslandManager.h b/physx/source/lowlevel/software/include/PxsSimpleIslandManager.h index 4bb65f903..ce3764d34 100644 --- a/physx/source/lowlevel/software/include/PxsSimpleIslandManager.h +++ b/physx/source/lowlevel/software/include/PxsSimpleIslandManager.h @@ -36,13 +36,13 @@ namespace physx { +// PT: TODO: fw declaring an Sc class here is not good namespace Sc { class Interaction; } namespace IG { - class SimpleIslandManager; class ThirdPassTask : public Cm::Task @@ -91,7 +91,6 @@ class SimpleIslandManager : public PxUserAllocated //An array of destroyed nodes PxArray mDestroyedNodes; Cm::BlockArray mInteractions; - //Edges destroyed this frame PxArray mDestroyedEdges; @@ -124,7 +123,7 @@ class SimpleIslandManager : public PxUserAllocated void removeNode(const PxNodeIndex index); - PxNodeIndex addArticulation(Sc::ArticulationSim* articulation, Dy::FeatherstoneArticulation* llArtic, bool isActive); + PxNodeIndex addArticulation(Dy::FeatherstoneArticulation* llArtic, bool isActive); #if PX_SUPPORT_GPU_PHYSX PxNodeIndex addSoftBody(Dy::SoftBody* llSoftBody, bool isActive); @@ -197,7 +196,6 @@ class SimpleIslandManager : public PxUserAllocated bool checkInternalConsistency(); - private: friend class ThirdPassTask; @@ -208,8 +206,6 @@ class SimpleIslandManager : public PxUserAllocated PX_NOCOPY(SimpleIslandManager) }; - - } } diff --git a/physx/source/lowlevel/software/include/PxsSimulationController.h b/physx/source/lowlevel/software/include/PxsSimulationController.h index 670e7a97d..5faf31a9f 100644 --- a/physx/source/lowlevel/software/include/PxsSimulationController.h +++ b/physx/source/lowlevel/software/include/PxsSimulationController.h @@ -70,11 +70,6 @@ namespace physx #endif } - namespace Cm - { - class EventProfiler; - } - namespace Bp { class BoundsArray; @@ -106,6 +101,8 @@ namespace physx class PxgParticleSystemCore; struct PxConeLimitedConstraint; + struct PxsShapeCore; + class PxPhysXGpu; struct PxgSolverConstraintManagerConstants; @@ -113,243 +110,252 @@ namespace physx class PxsSimulationControllerCallback : public PxUserAllocated { public: - virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) = 0; + virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) = 0; virtual PxU32 getNbCcdBodies() = 0; virtual ~PxsSimulationControllerCallback() {} }; - class PxsSimulationController : public PxUserAllocated { public: - PxsSimulationController(PxsSimulationControllerCallback* callback): mCallback(callback){} - virtual ~PxsSimulationController(){} - - virtual void addJoint(const PxU32 edgeIndex, Dy::Constraint* constraint, IG::IslandSim& islandSim, PxArray& jointIndices, - PxPinnedArray& managerIter, PxU32 uniqueId) = 0; - virtual void removeJoint(const PxU32 edgeIndex, Dy::Constraint* constraint, PxArray& jointIndices, IG::IslandSim& islandSim) = 0; - virtual void addShape(PxsShapeSim* shapeSim, const PxU32 index) = 0; - virtual void reinsertShape(PxsShapeSim* shapeSim, const PxU32 index) = 0; + PxsSimulationController(PxsSimulationControllerCallback* callback, PxIntBool gpu) : mCallback(callback), mGPU(gpu) {} + virtual ~PxsSimulationController(){} + + virtual void addJoint(const PxU32 /*edgeIndex*/, Dy::Constraint* /*constraint*/, IG::IslandSim& /*islandSim*/, PxArray& /*jointIndices*/, + PxPinnedArray& /*managerIter*/, PxU32 /*uniqueId*/){} + virtual void removeJoint(const PxU32 /*edgeIndex*/, Dy::Constraint* /*constraint*/, PxArray& /*jointIndices*/, IG::IslandSim& /*islandSim*/){} + virtual void addShape(PxsShapeSim* /*shapeSim*/, const PxU32 /*index*/){} + virtual void reinsertShape(PxsShapeSim* /*shapeSim*/, const PxU32 /*index*/) {} virtual void updateShape(PxsShapeSim& /*shapeSim*/, const PxNodeIndex& /*index*/) {} - virtual void removeShape(const PxU32 index) = 0; + virtual void removeShape(const PxU32 /*index*/){} - virtual void addDynamic(PxsRigidBody* rigidBody, const PxNodeIndex& nodeIndex) = 0; - virtual void addDynamics(PxsRigidBody** rigidBody, const PxU32* nodeIndex, PxU32 nbToProcess) = 0; - virtual void addArticulation(Dy::FeatherstoneArticulation* articulation, const PxNodeIndex& nodeIndex) = 0; - virtual void releaseArticulation(Dy::FeatherstoneArticulation* articulation, const PxNodeIndex& nodeIndex) = 0; - virtual void releaseDeferredArticulationIds() = 0; + virtual void addDynamic(PxsRigidBody* /*rigidBody*/, const PxNodeIndex& /*nodeIndex*/){} + virtual void addDynamics(PxsRigidBody** /*rigidBody*/, const PxU32* /*nodeIndex*/, PxU32 /*nbBodies*/) {} + virtual void addArticulation(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void releaseArticulation(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void releaseDeferredArticulationIds() {} #if PX_SUPPORT_GPU_PHYSX - virtual void addSoftBody(Dy::SoftBody* softBody, const PxNodeIndex& nodeIndex) = 0; - virtual void releaseSoftBody(Dy::SoftBody* softBody) = 0; - virtual void releaseDeferredSoftBodyIds() = 0; - virtual void activateSoftbody(Dy::SoftBody*) = 0; - virtual void deactivateSoftbody(Dy::SoftBody*) = 0; - virtual void activateSoftbodySelfCollision(Dy::SoftBody*) = 0; - virtual void deactivateSoftbodySelfCollision(Dy::SoftBody*) = 0; - virtual void setSoftBodyWakeCounter(Dy::SoftBody*) = 0; - - virtual void addParticleFilter(Dy::SoftBody*softBodySystem, Dy::ParticleSystem* particleSystem, - PxU32 particleId, PxU32 userBufferId, PxU32 tetId) = 0; - virtual void removeParticleFilter(Dy::SoftBody* softBodySystem, - const Dy::ParticleSystem* particleSystem, PxU32 particleId, PxU32 userBufferId, PxU32 tetId) = 0; - - virtual PxU32 addParticleAttachment(Dy::SoftBody*softBodySystem, const Dy::ParticleSystem* particleSystem, - PxU32 particleId, PxU32 userBufferId, PxU32 tetId, const PxVec4& barycentrics, const bool isActive) = 0; - virtual void removeParticleAttachment(Dy::SoftBody* softBody, PxU32 handle) = 0; - - virtual void addRigidFilter(Dy::SoftBody*softBodySystem, const PxNodeIndex& softBodyNodeIndex, - const PxNodeIndex& rigidNodeIndex, PxU32 vertIndex) = 0; - virtual void removeRigidFilter(Dy::SoftBody* softBodySystem, - const PxNodeIndex& rigidNodeIndex, PxU32 vertIndex) = 0; - - virtual PxU32 addRigidAttachment(Dy::SoftBody*softBodySystem, const PxNodeIndex& softBodyNodeIndex, - PxsRigidBody* rigidBody, const PxNodeIndex& rigidNodeIndex, PxU32 vertIndex, const PxVec3& actorSpacePose, - PxConeLimitedConstraint* constraint, const bool isActive) = 0; - virtual void removeRigidAttachment(Dy::SoftBody* softBody, PxU32 handle) = 0; - - virtual void addTetRigidFilter(Dy::SoftBody* softBodySystem, - const PxNodeIndex& rigidNodeIndex, PxU32 tetId) = 0; - - virtual PxU32 addTetRigidAttachment(Dy::SoftBody* softBodySystem, - PxsRigidBody* rigidBody, const PxNodeIndex& rigidNodeIndex, PxU32 tetIdx, - const PxVec4& barycentrics, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint, - const bool isActive) = 0; - - virtual void removeTetRigidFilter(Dy::SoftBody* softBody, - const PxNodeIndex& rigidNodeIndex, PxU32 tetId) = 0; - - virtual void addSoftBodyFilter(Dy::SoftBody* softBody0, Dy::SoftBody* softBody1, PxU32 tetIdx0, - PxU32 tetIdx1) = 0; - virtual void removeSoftBodyFilter(Dy::SoftBody* softBody0, Dy::SoftBody* softBody1, PxU32 tetIdx0, - PxU32 tetId1) = 0; - virtual void addSoftBodyFilters(Dy::SoftBody* softBody0, Dy::SoftBody* softBody1, PxU32* tetIndices0, PxU32* tetIndices1, - PxU32 tetIndicesSize) = 0; - virtual void removeSoftBodyFilters(Dy::SoftBody* softBody0, Dy::SoftBody* softBody1, PxU32* tetIndices0, PxU32* tetIndices1, - PxU32 tetIndicesSize) = 0; - - virtual PxU32 addSoftBodyAttachment(Dy::SoftBody* softBody0, Dy::SoftBody* softBody1, PxU32 tetIdx0, PxU32 tetIdx1, - const PxVec4& tetBarycentric0, const PxVec4& tetBarycentric1, PxConeLimitedConstraint* constraint, const bool isActive) = 0; - virtual void removeSoftBodyAttachment(Dy::SoftBody* softBody0, PxU32 handle) = 0; - - virtual void addClothFilter(Dy::SoftBody* softBody, Dy::FEMCloth* cloth, PxU32 triIdx, - PxU32 tetIdx) = 0; - virtual void removeClothFilter(Dy::SoftBody* softBody, Dy::FEMCloth*, PxU32 triId, - PxU32 tetId) = 0; - - virtual PxU32 addClothAttachment(Dy::SoftBody* softBody, Dy::FEMCloth* cloth, PxU32 triIdx, - const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, PxConeLimitedConstraint* constraint, - const bool isActive) = 0; - virtual void removeClothAttachment(Dy::SoftBody* softBody,PxU32 handle) = 0; - - virtual void addFEMCloth(Dy::FEMCloth* femCloth, const PxNodeIndex& nodeIndex) = 0; - virtual void releaseFEMCloth(Dy::FEMCloth* femCloth) = 0; - virtual void releaseDeferredFEMClothIds() = 0; - virtual void activateCloth(Dy::FEMCloth* femCloth) = 0; - virtual void deactivateCloth(Dy::FEMCloth* femCloth) = 0; - virtual void setClothWakeCounter(Dy::FEMCloth*) = 0; - - virtual void addRigidFilter(Dy::FEMCloth* cloth, - const PxNodeIndex& rigidNodeIndex, PxU32 vertId) = 0; - - virtual void removeRigidFilter(Dy::FEMCloth* cloth, - const PxNodeIndex& rigidNodeIndex, PxU32 vertId) = 0; - - virtual PxU32 addRigidAttachment(Dy::FEMCloth* cloth, const PxNodeIndex& clothNodeIndex, - PxsRigidBody* rigidBody, const PxNodeIndex& rigidNodeIndex, PxU32 vertIndex, const PxVec3& actorSpacePose, - PxConeLimitedConstraint* constraint, const bool isActive) = 0; - virtual void removeRigidAttachment(Dy::FEMCloth* cloth, PxU32 handle) = 0; - - virtual void addTriRigidFilter(Dy::FEMCloth* cloth, - const PxNodeIndex& rigidNodeIndex, PxU32 triIdx) = 0; - - virtual void removeTriRigidFilter(Dy::FEMCloth* cloth, - const PxNodeIndex& rigidNodeIndex, PxU32 triIdx) = 0; - - virtual PxU32 addTriRigidAttachment(Dy::FEMCloth* cloth, - PxsRigidBody* rigidBody, const PxNodeIndex& rigidNodeIndex, PxU32 triIdx, const PxVec4& barycentrics, - const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint, - const bool isActive) = 0; - - virtual void removeTriRigidAttachment(Dy::FEMCloth* cloth, PxU32 handle) = 0; - - virtual void addClothFilter(Dy::FEMCloth* cloth0, Dy::FEMCloth* cloth1, PxU32 triIdx0, PxU32 triIdx1) = 0; - virtual void removeClothFilter(Dy::FEMCloth* cloth0, Dy::FEMCloth* cloth1, PxU32 triIdx0, PxU32 triId1) = 0; - - virtual PxU32 addTriClothAttachment(Dy::FEMCloth* cloth0, Dy::FEMCloth* cloth1, PxU32 triIdx0, PxU32 triIdx1, - const PxVec4& triBarycentric0, const PxVec4& triBarycentric1, const bool addToActive) = 0; - - virtual void removeTriClothAttachment(Dy::FEMCloth* cloth0, PxU32 handle) = 0; - - - virtual void addParticleSystem(Dy::ParticleSystem* particleSystem, const PxNodeIndex& nodeIndex, PxParticleSolverType::Enum type) = 0; - virtual void releaseParticleSystem(Dy::ParticleSystem* particleSystem, PxParticleSolverType::Enum type) = 0; - virtual void releaseDeferredParticleSystemIds() = 0; - - virtual void addHairSystem(Dy::HairSystem* hairSystem, const PxNodeIndex& nodeIndex) = 0; - virtual void releaseHairSystem(Dy::HairSystem* hairSystem) = 0; - virtual void releaseDeferredHairSystemIds() = 0; - virtual void activateHairSystem(Dy::HairSystem*) = 0; - virtual void deactivateHairSystem(Dy::HairSystem*) = 0; - virtual void setHairSystemWakeCounter(Dy::HairSystem*) = 0; + virtual void addSoftBody(Dy::SoftBody* /*softBody*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void releaseSoftBody(Dy::SoftBody* /*softBody*/) {} + virtual void releaseDeferredSoftBodyIds() {} + virtual void activateSoftbody(Dy::SoftBody*) {} + virtual void deactivateSoftbody(Dy::SoftBody*) {} + virtual void activateSoftbodySelfCollision(Dy::SoftBody*) {} + virtual void deactivateSoftbodySelfCollision(Dy::SoftBody*) {} + virtual void setSoftBodyWakeCounter(Dy::SoftBody*) {} + + virtual void addParticleFilter(Dy::SoftBody* /*softBodySystem*/, Dy::ParticleSystem* /*particleSystem*/, + PxU32 /*particleId*/, PxU32 /*userBufferId*/, PxU32 /*tetId*/) {} + virtual void removeParticleFilter(Dy::SoftBody* /*softBodySystem*/, + const Dy::ParticleSystem* /*particleSystem*/, PxU32 /*particleId*/, PxU32 /*userBufferId*/, PxU32 /*tetId*/) {} + + virtual PxU32 addParticleAttachment(Dy::SoftBody* /*softBodySystem*/, const Dy::ParticleSystem* /*particleSystem*/, + PxU32 /*particleId*/, PxU32 /*userBufferId*/, PxU32 /*tetId*/, const PxVec4& /*barycentrics*/, const bool /*isActive*/) { return 0; } + virtual void removeParticleAttachment(Dy::SoftBody* /*softBody*/, PxU32 /*handle*/) {} + + virtual void addRigidFilter(Dy::SoftBody* /*softBodySystem*/, const PxNodeIndex& /*softBodyNodeIndex*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*vertIndex*/) {} + virtual void removeRigidFilter(Dy::SoftBody* /*softBodySystem*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*vertIndex*/) {} + + virtual PxU32 addRigidAttachment(Dy::SoftBody* /*softBodySystem*/, const PxNodeIndex& /*softBodyNodeIndex*/, + PxsRigidBody* /*rigidBody*/, const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*vertIndex*/, const PxVec3& /*actorSpacePose*/, + PxConeLimitedConstraint* /*constraint*/, const bool /*isActive*/) { return 0; } + virtual void removeRigidAttachment(Dy::SoftBody* /*softBody*/, PxU32 /*handle*/) {} + + virtual void addTetRigidFilter(Dy::SoftBody* /*softBodySystem*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*tetId*/) {} + + virtual PxU32 addTetRigidAttachment(Dy::SoftBody* /*softBodySystem*/, + PxsRigidBody* /*rigidBody*/, const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*tetIdx*/, + const PxVec4& /*barycentrics*/, const PxVec3& /*actorSpacePose*/, PxConeLimitedConstraint* /*constraint*/, + const bool /*isActive*/) { return 0; } + + virtual void removeTetRigidFilter(Dy::SoftBody* /*softBody*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*tetId*/) {} + + virtual void addSoftBodyFilter(Dy::SoftBody* /*softBody0*/, Dy::SoftBody* /*softBody1*/, PxU32 /*tetIdx0*/, + PxU32 /*tetIdx1*/) {} + virtual void removeSoftBodyFilter(Dy::SoftBody* /*softBody0*/, Dy::SoftBody* /*softBody1*/, PxU32 /*tetIdx0*/, + PxU32 /*tetId1*/) {} + virtual void addSoftBodyFilters(Dy::SoftBody* /*softBody0*/, Dy::SoftBody* /*softBody1*/, PxU32* /*tetIndices0*/, PxU32* /*tetIndices1*/, + PxU32 /*tetIndicesSize*/) {} + virtual void removeSoftBodyFilters(Dy::SoftBody* /*softBody0*/, Dy::SoftBody* /*softBody1*/, PxU32* /*tetIndices0*/, PxU32* /*tetIndices1*/, + PxU32 /*tetIndicesSize*/) {} + + virtual PxU32 addSoftBodyAttachment(Dy::SoftBody* /*softBody0*/, Dy::SoftBody* /*softBody1*/, PxU32 /*tetIdx0*/, PxU32 /*tetIdx1*/, + const PxVec4& /*tetBarycentric0*/, const PxVec4& /*tetBarycentric1*/, + PxConeLimitedConstraint* /*constraint*/, PxReal /*constraintOffset*/, const bool /*isActive*/) { return 0; } + + virtual void removeSoftBodyAttachment(Dy::SoftBody* /*softBody0*/, PxU32 /*handle*/) {} + + virtual void addClothFilter(Dy::SoftBody* /*softBody*/, Dy::FEMCloth* /*cloth*/, PxU32 /*triIdx*/, + PxU32 /*tetIdx*/) {} + virtual void removeClothFilter(Dy::SoftBody* /*softBody*/, Dy::FEMCloth*, PxU32 /*triId*/, + PxU32 /*tetId*/) {} + + virtual PxU32 addClothAttachment(Dy::SoftBody* /*softBody*/, Dy::FEMCloth* /*cloth*/, PxU32 /*triIdx*/, + const PxVec4& /*triBarycentric*/, PxU32 /*tetIdx*/, const PxVec4& /*tetBarycentric*/, + PxConeLimitedConstraint* /*constraint*/, PxReal /*constraintOffset*/, + const bool /*isActive*/) { return 0; } + + virtual void removeClothAttachment(Dy::SoftBody* /*softBody*/,PxU32 /*handle*/) {} + + virtual void addFEMCloth(Dy::FEMCloth* /*femCloth*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void releaseFEMCloth(Dy::FEMCloth* /*femCloth*/) {} + virtual void releaseDeferredFEMClothIds() {} + virtual void activateCloth(Dy::FEMCloth* /*femCloth*/) {} + virtual void deactivateCloth(Dy::FEMCloth* /*femCloth*/) {} + virtual void setClothWakeCounter(Dy::FEMCloth*) {} + + virtual void addRigidFilter(Dy::FEMCloth* /*cloth*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*vertId*/) {} + + virtual void removeRigidFilter(Dy::FEMCloth* /*cloth*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*vertId*/) {} + + virtual PxU32 addRigidAttachment(Dy::FEMCloth* /*cloth*/, const PxNodeIndex& /*clothNodeIndex*/, + PxsRigidBody* /*rigidBody*/, const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*vertIndex*/, const PxVec3& /*actorSpacePose*/, + PxConeLimitedConstraint* /*constraint*/, const bool /*isActive*/) { return 0; } + virtual void removeRigidAttachment(Dy::FEMCloth* /*cloth*/, PxU32 /*handle*/) {} + + virtual void addTriRigidFilter(Dy::FEMCloth* /*cloth*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*triIdx*/) {} + + virtual void removeTriRigidFilter(Dy::FEMCloth* /*cloth*/, + const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*triIdx*/) {} + + virtual PxU32 addTriRigidAttachment(Dy::FEMCloth* /*cloth*/, + PxsRigidBody* /*rigidBody*/, const PxNodeIndex& /*rigidNodeIndex*/, PxU32 /*triIdx*/, const PxVec4& /*barycentrics*/, + const PxVec3& /*actorSpacePose*/, PxConeLimitedConstraint* /*constraint*/, + const bool /*isActive*/) { return 0; } + + virtual void removeTriRigidAttachment(Dy::FEMCloth* /*cloth*/, PxU32 /*handle*/) {} + + virtual void addClothFilter(Dy::FEMCloth* /*cloth0*/, Dy::FEMCloth* /*cloth1*/, PxU32 /*triIdx0*/, PxU32 /*triIdx1*/) {} + virtual void removeClothFilter(Dy::FEMCloth* /*cloth0*/, Dy::FEMCloth* /*cloth1*/, PxU32 /*triIdx0*/, PxU32 /*triIdx1*/) {} + + virtual PxU32 addTriClothAttachment(Dy::FEMCloth* /*cloth0*/, Dy::FEMCloth* /*cloth1*/, PxU32 /*triIdx0*/, PxU32 /*triIdx1*/, + const PxVec4& /*triBarycentric0*/, const PxVec4& /*triBarycentric1*/, const bool /*addToActive*/) { return 0; } + + virtual void removeTriClothAttachment(Dy::FEMCloth* /*cloth*/, PxU32 /*handle*/) {} + + virtual void addParticleSystem(Dy::ParticleSystem* /*particleSystem*/, const PxNodeIndex& /*nodeIndex*/, PxParticleSolverType::Enum /*type*/) {} + virtual void releaseParticleSystem(Dy::ParticleSystem* /*particleSystem*/, PxParticleSolverType::Enum /*type*/) {} + virtual void releaseDeferredParticleSystemIds() {} + + virtual void addHairSystem(Dy::HairSystem* /*hairSystem*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void releaseHairSystem(Dy::HairSystem* /*hairSystem*/) {} + virtual void releaseDeferredHairSystemIds() {} + virtual void activateHairSystem(Dy::HairSystem*) {} + virtual void deactivateHairSystem(Dy::HairSystem*) {} + virtual void setHairSystemWakeCounter(Dy::HairSystem*) {} #endif - virtual void flush() = 0; - - virtual void updateDynamic(Dy::FeatherstoneArticulation* articulation, const PxNodeIndex& nodeIndex) = 0; - virtual void updateJoint(const PxU32 edgeIndex, Dy::Constraint* constraint) = 0; - virtual void updateBodies(PxsRigidBody** rigidBodies, PxU32* nodeIndices, const PxU32 nbBodies) = 0; - virtual void updateBodies(PxBaseTask* continuation) = 0; - virtual void updateShapes(PxBaseTask* continuation) = 0; - virtual void preIntegrateAndUpdateBound(PxBaseTask* continuation, const PxVec3 gravity, const PxReal dt) = 0; - virtual void updateParticleSystemsAndSoftBodies() = 0; - virtual void sortContacts() = 0; - virtual void update(PxBitMapPinned& changedHandleMap) = 0; - virtual void updateArticulation(Dy::FeatherstoneArticulation* articulation, const PxNodeIndex& nodeIndex) = 0; - virtual void updateArticulationJoint(Dy::FeatherstoneArticulation* articulation, const PxNodeIndex& nodeIndex) = 0; - virtual void updateArticulationExtAccel(Dy::FeatherstoneArticulation* articulation, const PxNodeIndex& nodeIndex) = 0; - virtual void updateArticulationAfterIntegration(PxsContext* llContext, Bp::AABBManagerBase* aabbManager, PxArray& ccdBodies, - PxBaseTask* continuation, IG::IslandSim& islandSim, const float dt) = 0; - - virtual void mergeChangedAABBMgHandle(const PxU32 maxAABBMgHandles, const bool suppressedReadback) = 0; - virtual void gpuDmabackData(PxsTransformCache& cache, Bp::BoundsArray& boundArray, PxBitMapPinned& changedAABBMgrHandles, bool suppressReadback) = 0; - virtual void updateScBodyAndShapeSim(PxsTransformCache& cache, Bp::BoundsArray& boundArray, PxBaseTask* continuation) = 0; - virtual PxU32* getActiveBodies() = 0; - virtual PxU32* getDeactiveBodies() = 0; - virtual void** getRigidBodies() = 0; - virtual PxU32 getNbBodies() = 0; - - virtual PxU32* getUnfrozenShapes() = 0; - virtual PxU32* getFrozenShapes() = 0; - virtual PxsShapeSim** getShapeSims() = 0; - virtual PxU32 getNbFrozenShapes() = 0; - virtual PxU32 getNbUnfrozenShapes() = 0; - virtual PxU32 getNbShapes() = 0; - - virtual void clear() = 0; - virtual void setBounds(Bp::BoundsArray* boundArray) = 0; - virtual void reserve(const PxU32 nbBodies) = 0; - - virtual PxU32 getArticulationRemapIndex(const PxU32 nodeIndex) = 0; + virtual void flush() {} + + virtual void updateDynamic(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void updateJoint(const PxU32 /*edgeIndex*/, Dy::Constraint* /*constraint*/){} + virtual void updateBodies(PxsRigidBody** /*rigidBodies*/, PxU32* /*nodeIndices*/, const PxU32 /*nbBodies*/) {} +// virtual void updateBody(PxsRigidBody* /*rigidBody*/, const PxU32 /*nodeIndex*/) {} + virtual void updateBodies(PxBaseTask* /*continuation*/){} + virtual void updateShapes(PxBaseTask* /*continuation*/) {} + virtual void preIntegrateAndUpdateBound(PxBaseTask* /*continuation*/, const PxVec3 /*gravity*/, const PxReal /*dt*/){} + virtual void updateParticleSystemsAndSoftBodies(){} + virtual void sortContacts(){} + virtual void update(PxBitMapPinned& /*changedHandleMap*/){} + virtual void updateArticulation(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void updateArticulationJoint(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} +// virtual void updateArticulationTendon(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void updateArticulationExtAccel(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} + virtual void updateArticulationAfterIntegration(PxsContext* /*llContext*/, Bp::AABBManagerBase* /*aabbManager*/, + PxArray& /*ccdBodies*/, PxBaseTask* /*continuation*/, IG::IslandSim& /*islandSim*/, float /*dt*/) {} + + virtual void mergeChangedAABBMgHandle(const PxU32 /*maxAABBMgHandles*/, const bool /*enableDirectGPUAPI*/) {} + virtual void gpuDmabackData(PxsTransformCache& /*cache*/, Bp::BoundsArray& /*boundArray*/, PxBitMapPinned& /*changedAABBMgrHandles*/, bool /*enableDirectGPUAPI*/){} + virtual void updateScBodyAndShapeSim(PxsTransformCache& cache, Bp::BoundsArray& boundArray, PxBaseTask* continuation) = 0; + virtual PxU32* getActiveBodies() { return NULL; } + virtual PxU32* getDeactiveBodies() { return NULL; } + virtual void** getRigidBodies() { return NULL; } + virtual PxU32 getNbBodies() { return 0; } + + virtual PxU32* getUnfrozenShapes() { return NULL; } + virtual PxU32* getFrozenShapes() { return NULL; } + virtual PxsShapeSim** getShapeSims() { return NULL; } + virtual PxU32 getNbFrozenShapes() { return 0; } + virtual PxU32 getNbUnfrozenShapes() { return 0; } + virtual PxU32 getNbShapes() { return 0; } + + virtual void clear() { } + virtual void setBounds(Bp::BoundsArray* /*boundArray*/){} + virtual void reserve(const PxU32 /*nbBodies*/) {} + + virtual PxU32 getArticulationRemapIndex(const PxU32 /*nodeIndex*/) { return PX_INVALID_U32;} //virtual void setParticleSystemManager(PxgParticleSystemCore* psCore) = 0; - virtual void copyArticulationData(void* data, void* index, PxArticulationGpuDataType::Enum dataType, const PxU32 nbCopyArticulations, void* copyEvent) = 0; - virtual void applyArticulationData(void* data, void* index, PxArticulationGpuDataType::Enum dataType, const PxU32 nbUpdatedArticulations, - void* waitEvent, void* signalEvent) = 0; + virtual void copyArticulationData(void* /*jointData*/, void* /*index*/, PxArticulationGpuDataType::Enum /*dataType*/, const PxU32 /*nbUpdatedArticulations*/, void* /*copyEvent*/) {} + virtual void applyArticulationData(void* /*data*/, void* /*index*/, PxArticulationGpuDataType::Enum /*dataType*/, const PxU32 /*nbUpdatedArticulations*/, void* /*waitEvent*/, void* /*signalEvent*/) {} //KS - the methods below here should probably be wrapped in if PX_SUPPORT_GPU_PHYSX + // PT: isn't the whole class only needed for GPU anyway? - virtual void copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent) = 0; - virtual void applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbUpdatedSoftBodies, const PxU32 maxSize, void* applyEvent) = 0; - virtual void copyContactData(Dy::Context* dyContext, void* data, const PxU32 maxContactPairs, void* numContactPairs, void* copyEvent) = 0; - virtual void copyBodyData(PxGpuBodyData* data, PxGpuActorPair* index, const PxU32 nbUpdatedActors, void* copyEvent) = 0; - virtual void applyActorData(void* data, PxGpuActorPair* index, PxActorCacheFlag::Enum flag, const PxU32 nbUpdatedActors, void* waitEvent, void* signalEvent) = 0; - - virtual void syncParticleData() = 0; + virtual void copySoftBodyData(void** /*data*/, void* /*dataSizes*/, void* /*softBodyIndices*/, PxSoftBodyGpuDataFlag::Enum /*flag*/, const PxU32 /*nbCopySoftBodies*/, const PxU32 /*maxSize*/, void* /*copyEvent*/) {} + virtual void applySoftBodyData(void** /*data*/, void* /*dataSizes*/, void* /*softBodyIndices*/, PxSoftBodyGpuDataFlag::Enum /*flag*/, const PxU32 /*nbUpdatedSoftBodies*/, const PxU32 /*maxSize*/, void* /*applyEvent*/) {} + virtual void copyContactData(Dy::Context* /*dyContext*/, void* /*data*/, const PxU32 /*maxContactPairs*/, void* /*numContactPairs*/, void* /*copyEvent*/) {} + virtual void copyBodyData(PxGpuBodyData* /*data*/, PxGpuActorPair* /*index*/, const PxU32 /*nbCopyActors*/, void* /*copyEvent*/){} + virtual void applyActorData(void* /*data*/, PxGpuActorPair* /*index*/, PxActorCacheFlag::Enum /*flag*/, const PxU32 /*nbUpdatedActors*/, void* /*waitEvent*/, void* /*signalEvent*/) {} - virtual void updateBoundsAndShapes(Bp::AABBManagerBase& aabbManager, const bool useGpuBp, const bool useDirectApi) = 0; + virtual void evaluateSDFDistances(const PxU32* /*sdfShapeIds*/, const PxU32 /*nbShapes*/, const PxVec4* /*samplePointsConcatenated*/, + const PxU32* /*samplePointCountPerShape*/, const PxU32 /*maxPointCount*/, PxVec4* /*localGradientAndSDFConcatenated*/, void* /*event*/) {} + virtual PxU32 getInternalShapeIndex(const PxsShapeCore& /*shapeCore*/) { return PX_INVALID_U32; } - virtual void computeDenseJacobians(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; - virtual void computeGeneralizedMassMatrices(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; - virtual void computeGeneralizedGravityForces(const PxIndexDataPair* indices, PxU32 nbIndices, const PxVec3& gravity, void* computeEvent) = 0; - virtual void computeCoriolisAndCentrifugalForces(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; - virtual void applyParticleBufferData(const PxU32* indices, const PxGpuParticleBufferIndexPair* indexPairs, const PxParticleBufferFlags* flags, PxU32 nbUpdatedBuffers, void* waitEvent, void* signalEvent) = 0; + virtual void syncParticleData() {} - virtual void flushInsertions() = 0; + virtual void updateBoundsAndShapes(Bp::AABBManagerBase& /*aabbManager*/, bool/* useGpuBp*/, bool /*useDirectApi*/){} -#if PX_SUPPORT_GPU_PHYSX - virtual PxU32 getNbDeactivatedFEMCloth() const = 0; - virtual PxU32 getNbActivatedFEMCloth() const = 0; + virtual void computeDenseJacobians(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, void* /*computeEvent*/){} + virtual void computeGeneralizedMassMatrices(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, void* /*computeEvent*/){} + virtual void computeGeneralizedGravityForces(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, const PxVec3& /*gravity*/, void* /*computeEvent*/){} + virtual void computeCoriolisAndCentrifugalForces(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, void* /*computeEvent*/) {} + virtual void applyParticleBufferData(const PxU32* /*indices*/, const PxGpuParticleBufferIndexPair* /*indexPairs*/, const PxParticleBufferFlags* /*flags*/, PxU32 /*nbUpdatedBuffers*/, void* /*waitEvent*/, void* /*signalEvent*/) {} - virtual Dy::FEMCloth** getDeactivatedFEMCloths() const = 0; - virtual Dy::FEMCloth** getActivatedFEMCloths() const = 0; + virtual void flushInsertions() {} +#if PX_SUPPORT_GPU_PHYSX + virtual PxU32 getNbDeactivatedFEMCloth() const { return 0; } + virtual PxU32 getNbActivatedFEMCloth() const { return 0; } - virtual PxU32 getNbDeactivatedSoftbodies() const = 0; - virtual PxU32 getNbActivatedSoftbodies() const = 0; + virtual Dy::FEMCloth** getDeactivatedFEMCloths() const { return NULL; } + virtual Dy::FEMCloth** getActivatedFEMCloths() const { return NULL; } - virtual const PxReal* getSoftBodyWakeCounters() const = 0; + virtual PxU32 getNbDeactivatedSoftbodies() const { return 0; } + virtual PxU32 getNbActivatedSoftbodies() const { return 0; } - virtual Dy::SoftBody** getDeactivatedSoftbodies() const = 0; - virtual Dy::SoftBody** getActivatedSoftbodies() const = 0; + virtual const PxReal* getSoftBodyWakeCounters() const { return NULL; } + virtual const PxReal* getHairSystemWakeCounters() const { return NULL; } - virtual bool hasFEMCloth() const = 0; - virtual bool hasSoftBodies() const = 0; + virtual Dy::SoftBody** getDeactivatedSoftbodies() const { return NULL; } + virtual Dy::SoftBody** getActivatedSoftbodies() const { return NULL; } - virtual PxU32 getNbDeactivatedHairSystems() const = 0; - virtual PxU32 getNbActivatedHairSystems() const = 0; - virtual Dy::HairSystem** getDeactivatedHairSystems() const = 0; - virtual Dy::HairSystem** getActivatedHairSystems() const = 0; - virtual bool hasHairSystems() const = 0; + virtual bool hasFEMCloth() const { return false; } + virtual bool hasSoftBodies() const { return false; } + virtual PxU32 getNbDeactivatedHairSystems() const { return 0; } + virtual PxU32 getNbActivatedHairSystems() const { return 0; } + virtual Dy::HairSystem** getDeactivatedHairSystems() const { return NULL; } + virtual Dy::HairSystem** getActivatedHairSystems() const { return NULL; } + virtual bool hasHairSystems() const { return false; } #endif - virtual void* getMPMDataPointer(const Dy::ParticleSystem& psLL, PxMPMParticleDataFlag::Enum flags) = 0; - virtual void* getSparseGridDataPointer(const Dy::ParticleSystem& psLL, PxSparseGridDataFlag::Enum flags, PxParticleSolverType::Enum type) = 0; + virtual void* getMPMDataPointer(const Dy::ParticleSystem& /*psLL*/, PxMPMParticleDataFlag::Enum /*flags*/) { return NULL; } + virtual void* getSparseGridDataPointer(const Dy::ParticleSystem& /*psLL*/, PxSparseGridDataFlag::Enum /*flags*/, PxParticleSolverType::Enum /*type*/) { return NULL; } protected: - PxsSimulationControllerCallback* mCallback; + PxsSimulationControllerCallback* mCallback; + public: + const PxIntBool mGPU; // PT: true for GPU version, used to quickly skip calls for CPU version }; } diff --git a/physx/source/lowlevel/software/include/PxvNphaseImplementationContext.h b/physx/source/lowlevel/software/include/PxvNphaseImplementationContext.h index dc5402a81..8c9dc8f38 100644 --- a/physx/source/lowlevel/software/include/PxvNphaseImplementationContext.h +++ b/physx/source/lowlevel/software/include/PxvNphaseImplementationContext.h @@ -44,19 +44,12 @@ namespace physx { - namespace IG { - class SimpleIslandManager; class IslandSim; typedef PxU32 EdgeIndex; } -namespace Dy -{ - class Context; -} - namespace Cm { class FanoutTask; @@ -76,7 +69,6 @@ class PxsContactManager; struct PxsContactManagerOutput; struct PxsTorsionalFrictionData; - class PxsContactManagerOutputIterator { PxU32 mOffsets[1<(rigidCore); - return bodyCore->body2World * bodyCore->getBody2Actor().getInverse() *shapeCore->getTransform(); + trInvTr(out, bodyCore->body2World, bodyCore->getBody2Actor(), shapeCore->getTransform()); } else - { - return rigidCore->body2World * shapeCore->getTransform(); - } + trTr(out, rigidCore->body2World, shapeCore->getTransform()); +} + +// \brief Returns the world-space pose for this shape +// \param[in] atom The rigid body that this CCD shape is associated with +static void getAbsPose(PxTransform32& out, const PxsCCDShape* ccdShape, const PxsRigidBody* atom) +{ + // PT: TODO: refactor with ShapeSim version (SIMD) - or with redundant getShapeAbsPose() above in this same file! + // PT: TODO: simplify code when shape local pose = idt + if(atom) + trInvTr(out, atom->getPose(), atom->getCore().getBody2Actor(), ccdShape->mShapeCore->getTransform()); + else + trTr(out, ccdShape->mRigidCore->body2World, ccdShape->mShapeCore->getTransform()); +} + +// \brief Returns the world-space previous pose for this shape +// \param[in] atom The rigid body that this CCD shape is associated with +static void getLastCCDAbsPose(PxTransform32& out, const PxsCCDShape* ccdShape, const PxsRigidBody* atom) +{ + // PT: TODO: refactor with ShapeSim version (SIMD) + // PT: TODO: simplify code when shape local pose = idt + // PT:: tag: scalar transform*transform + trInvTr(out, atom->getLastCCDTransform(), atom->getCore().getBody2Actor(), ccdShape->mShapeCore->getTransform()); } PxsCCDContext::PxsCCDContext(PxsContext* context, Dy::ThresholdStream& thresholdStream, PxvNphaseImplementationContext& nPhaseContext, PxReal ccdThreshold) : @@ -338,23 +371,6 @@ PxsCCDContext::~PxsCCDContext() { } -PxTransform PxsCCDShape::getAbsPose(const PxsRigidBody* atom) const -{ - // PT: TODO: refactor with ShapeSim version (SIMD) - or with redundant getShapeAbsPose() above in this same file! - // PT: TODO: simplify code when shape local pose = idt - if(atom) - return atom->getPose() * atom->getCore().getBody2Actor().getInverse() * mShapeCore->getTransform(); - else - return mRigidCore->body2World * mShapeCore->getTransform(); -} - -PxTransform PxsCCDShape::getLastCCDAbsPose(const PxsRigidBody* atom) const -{ - // PT: TODO: refactor with ShapeSim version (SIMD) - // PT: TODO: simplify code when shape local pose = idt - return atom->getLastCCDTransform() * atom->getCore().getBody2Actor().getInverse() * mShapeCore->getTransform(); -} - PxReal PxsCCDPair::sweepFindToi(PxcNpThreadContext& context, PxReal dt, PxU32 pass, PxReal ccdThreshold) { printSeparator("findToi", pass, mBa0, mG0, NULL, PxGeometryType::eGEOMETRY_COUNT); @@ -379,16 +395,11 @@ PxReal PxsCCDPair::sweepFindToi(PxcNpThreadContext& context, PxReal dt, PxU32 pa atom1 = mBa0; } - PX_ALIGN(16, PxTransform tm0); - PX_ALIGN(16, PxTransform tm1); - PX_ALIGN(16, PxTransform lastTm0); - PX_ALIGN(16, PxTransform lastTm1); - - tm0 = ccdShape0->mCurrentTransform; - lastTm0 = ccdShape0->mPrevTransform; + const PxTransform32 tm0(ccdShape0->mCurrentTransform); + const PxTransform32 lastTm0(ccdShape0->mPrevTransform); - tm1 = ccdShape1->mCurrentTransform; - lastTm1 = ccdShape1->mPrevTransform; + const PxTransform32 tm1(ccdShape1->mCurrentTransform); + const PxTransform32 lastTm1(ccdShape1->mPrevTransform); const PxVec3 trA = tm0.p - lastTm0.p; const PxVec3 trB = tm1.p - lastTm1.p; @@ -522,51 +533,39 @@ PxReal PxsCCDPair::sweepFindToi(PxcNpThreadContext& context, PxReal dt, PxU32 pa return toi; } -void PxsCCDPair::updateShapes() +static void updateShape(PxsRigidBody* body, PxsCCDShape* shape) { - if(mBa0) + if(body) { //If the CCD shape's update count doesn't match the body's update count, this shape needs its transforms and bounds re-calculated - if(mBa0->mCCD->mUpdateCount != mCCDShape0->mUpdateCount) + if(body->mCCD->mUpdateCount != shape->mUpdateCount) { - const PxTransform tm0 = mCCDShape0->getAbsPose(mBa0); - const PxTransform lastTm0 = mCCDShape0->getLastCCDAbsPose(mBa0); - - const PxVec3 trA = tm0.p - lastTm0.p; + PxTransform32 tm; + getAbsPose(tm, shape, body); - PxVec3p origin, extents; - computeBoundsWithCCDThreshold(origin, extents, mCCDShape0->mShapeCore->mGeometry.getGeometry(), tm0); + PxTransform32 lastTm; + getLastCCDAbsPose(lastTm, shape, body); - mCCDShape0->mCenter = origin - trA; - mCCDShape0->mExtents = extents; - mCCDShape0->mPrevTransform = lastTm0; - mCCDShape0->mCurrentTransform = tm0; - mCCDShape0->mUpdateCount = mBa0->mCCD->mUpdateCount; - } - } - - if(mBa1) - { - //If the CCD shape's update count doesn't match the body's update count, this shape needs its transforms and bounds re-calculated - if(mBa1->mCCD->mUpdateCount != mCCDShape1->mUpdateCount) - { - const PxTransform tm1 = mCCDShape1->getAbsPose(mBa1); - const PxTransform lastTm1 = mCCDShape1->getLastCCDAbsPose(mBa1); - - const PxVec3 trB = tm1.p - lastTm1.p; + const PxVec3 trA = tm.p - lastTm.p; PxVec3p origin, extents; - computeBoundsWithCCDThreshold(origin, extents, mCCDShape1->mShapeCore->mGeometry.getGeometry(), tm1); + computeBoundsWithCCDThreshold(origin, extents, shape->mShapeCore->mGeometry.getGeometry(), tm); - mCCDShape1->mCenter = origin - trB; - mCCDShape1->mExtents = extents; - mCCDShape1->mPrevTransform = lastTm1; - mCCDShape1->mCurrentTransform = tm1; - mCCDShape1->mUpdateCount = mBa1->mCCD->mUpdateCount; + shape->mCenter = origin - trA; + shape->mExtents = extents; + shape->mPrevTransform = lastTm; + shape->mCurrentTransform = tm; + shape->mUpdateCount = body->mCCD->mUpdateCount; } } } +void PxsCCDPair::updateShapes() +{ + updateShape(mBa0, mCCDShape0); + updateShape(mBa1, mCCDShape1); +} + PxReal PxsCCDPair::sweepEstimateToi(PxReal ccdThreshold) { //Update shape transforms if necessary @@ -798,7 +797,7 @@ bool PxsCCDPair::sweepAdvanceToToi(PxReal dt, bool clipTrajectoryToToi) } //const PxVec3 fricJ = -vPerp.getNormalized() * (fricResponse/impulseDivisor); - const PxVec3 fricJ = tDir * (fricResponse); + const PxVec3 fricJ = tDir * (fricResponse); j = jImp * mMinToiNormal + fricJ; } else @@ -1106,10 +1105,10 @@ class PxsCCDAdvanceTask : public Cm::Task PxContactPatch* patch = reinterpret_cast(dataBuffer); PxModifiableContact* point = reinterpret_cast(patch + 1); - patch->mMassModification.mInvInertiaScale0 = 1.f; - patch->mMassModification.mInvInertiaScale1 = 1.f; - patch->mMassModification.mInvMassScale0 = 1.f; - patch->mMassModification.mInvMassScale1 = 1.f; + patch->mMassModification.linear0 = 1.f; + patch->mMassModification.linear1 = 1.f; + patch->mMassModification.angular0 = 1.f; + patch->mMassModification.angular1 = 1.f; patch->normal = pair.mMinToiNormal; @@ -1422,6 +1421,55 @@ static PX_FORCE_INLINE bool pairNeedsCCD(const PxsContactManager* cm) } } +static PxsCCDShape* processShape( + PxVec3& tr, PxReal& threshold, PxsCCDShape* ccdShape, + const PxsRigidCore* const rc, const PxsShapeCore* const sc, const PxsRigidBody* const ba, + const PxsContactManager* const cm, IG::IslandSim& islandSim, PxsCCDShapeArray& mCCDShapes, PxHashMap& mMap, bool flag) +{ + if(ccdShape == NULL) + { + //If we hadn't already created ccdShape, create one + ccdShape = &mCCDShapes.pushBack(); + ccdShape->mRigidCore = rc; + ccdShape->mShapeCore = sc; + ccdShape->mGeometry = &sc->mGeometry.getGeometry(); + + mMap.insert(PxsRigidShapePair(rc, sc), ccdShape); + + PxTransform32 tm; + getAbsPose(tm, ccdShape, ba); + + PxTransform32 oldTm; + if(ba) + getLastCCDAbsPose(oldTm, ccdShape, ba); + else + oldTm = tm; + + tr = tm.p - oldTm.p; + + PxVec3p origin, extents; + //Compute the shape's bounds and CCD threshold + threshold = computeBoundsWithCCDThreshold(origin, extents, sc->mGeometry.getGeometry(), tm); + + //Set up the CCD shape + ccdShape->mCenter = origin - tr; + ccdShape->mExtents = extents; + ccdShape->mFastMovingThreshold = threshold; + ccdShape->mPrevTransform = oldTm; + ccdShape->mCurrentTransform = tm; + ccdShape->mUpdateCount = 0; + ccdShape->mNodeIndex = flag ? islandSim.getNodeIndex2(cm->getWorkUnit().mEdgeIndex) + : islandSim.getNodeIndex1(cm->getWorkUnit().mEdgeIndex); + } + else + { + //We had already created the shape, so extract the threshold and translation components + threshold = ccdShape->mFastMovingThreshold; + tr = ccdShape->mCurrentTransform.p - ccdShape->mPrevTransform.p; + } + return ccdShape; +} + void PxsCCDContext::updateCCD(PxReal dt, PxBaseTask* continuation, IG::IslandSim& islandSim, bool disableResweep, PxI32 numFastMovingShapes) { //Flag to run a slightly less-accurate version of CCD that will ensure that objects don't tunnel through the static world but is not as reliable for dynamic-dynamic collisions @@ -1505,75 +1553,8 @@ void PxsCCDContext::updateCCD(PxReal dt, PxBaseTask* continuation, IG::IslandSim PxVec3 trA(0.0f); PxVec3 trB(0.0f); - if(ccdShape0 == NULL) - { - //If we hadn't already created ccdShape, create one - ccdShape0 = &mCCDShapes.pushBack(); - mMap.insert(PxsRigidShapePair(rc0, sc0), ccdShape0); - - ccdShape0->mRigidCore = rc0; - ccdShape0->mShapeCore = sc0; - ccdShape0->mGeometry = &sc0->mGeometry.getGeometry(); - - const PxTransform tm0 = ccdShape0->getAbsPose(ba0); - const PxTransform oldTm0 = ba0 ? ccdShape0->getLastCCDAbsPose(ba0) : tm0; - - trA = tm0.p - oldTm0.p; - - PxVec3p origin, extents; - //Compute the shape's bounds and CCD threshold - threshold0 = computeBoundsWithCCDThreshold(origin, extents, sc0->mGeometry.getGeometry(), tm0); - - //Set up the CCD shape - ccdShape0->mCenter = origin - trA; - ccdShape0->mExtents = extents; - ccdShape0->mFastMovingThreshold = threshold0; - ccdShape0->mPrevTransform = oldTm0; - ccdShape0->mCurrentTransform = tm0; - ccdShape0->mUpdateCount = 0; - ccdShape0->mNodeIndex = islandSim.getNodeIndex1(cm->getWorkUnit().mEdgeIndex); - } - else - { - //We had already created the shape, so extract the threshold and translation components - threshold0 = ccdShape0->mFastMovingThreshold; - trA = ccdShape0->mCurrentTransform.p - ccdShape0->mPrevTransform.p; - } - - if(ccdShape1 == NULL) - { - //If the CCD shape was not already constructed, create it - ccdShape1 = &mCCDShapes.pushBack(); - ccdShape1->mRigidCore = rc1; - ccdShape1->mShapeCore = sc1; - ccdShape1->mGeometry = &sc1->mGeometry.getGeometry(); - - mMap.insert(PxsRigidShapePair(rc1, sc1), ccdShape1); - - const PxTransform tm1 = ccdShape1->getAbsPose(ba1); - const PxTransform oldTm1 = ba1 ? ccdShape1->getLastCCDAbsPose(ba1) : tm1; - - trB = tm1.p - oldTm1.p; - - PxVec3p origin, extents; - //Compute the shape's bounds and CCD threshold - threshold1 = computeBoundsWithCCDThreshold(origin, extents, sc1->mGeometry.getGeometry(), tm1); - - //Set up the CCD shape - ccdShape1->mCenter = origin - trB; - ccdShape1->mExtents = extents; - ccdShape1->mFastMovingThreshold = threshold1; - ccdShape1->mPrevTransform = oldTm1; - ccdShape1->mCurrentTransform = tm1; - ccdShape1->mUpdateCount = 0; - ccdShape1->mNodeIndex = islandSim.getNodeIndex2(cm->getWorkUnit().mEdgeIndex); - } - else - { - //CCD shape already constructed so just extract thresholds and trB components - threshold1 = ccdShape1->mFastMovingThreshold; - trB = ccdShape1->mCurrentTransform.p - ccdShape1->mPrevTransform.p; - } + ccdShape0 = processShape(trA, threshold0, ccdShape0, rc0, sc0, ba0, cm, islandSim, mCCDShapes, mMap, false); + ccdShape1 = processShape(trB, threshold1, ccdShape1, rc1, sc1, ba1, cm, islandSim, mCCDShapes, mMap, true); { //Initialize the CCD bodies @@ -2147,8 +2128,8 @@ void PxsCCDContext::runCCDModifiableContact(PxModifiableContact* PX_RESTRICT con p.actor[1] = rigid1 != NULL ? gPxvOffsetTable.convertPxsRigidCore2PxRigidBody(rigidCore1) : gPxvOffsetTable.convertPxsRigidCore2PxRigidStatic(rigidCore1); - p.transform[0] = getShapeAbsPose(shapeCore0, rigidCore0, PxU32(rigid0 != NULL)); - p.transform[1] = getShapeAbsPose(shapeCore1, rigidCore1, PxU32(rigid1 != NULL)); + getShapeAbsPose(p.transform[0], shapeCore0, rigidCore0, rigid0); + getShapeAbsPose(p.transform[1], shapeCore1, rigidCore1, rigid1); static_cast(p.contacts) = PxcContactSet(contactCount, contacts); diff --git a/physx/source/lowlevel/software/src/PxsContactManager.cpp b/physx/source/lowlevel/software/src/PxsContactManager.cpp index 9321a2f07..29836deb8 100644 --- a/physx/source/lowlevel/software/src/PxsContactManager.cpp +++ b/physx/source/lowlevel/software/src/PxsContactManager.cpp @@ -27,15 +27,10 @@ // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #include "PxsContactManager.h" -#include "PxsRigidBody.h" -#include "PxcContactMethodImpl.h" -#include "PxvManager.h" -#include "PxsIslandSim.h" using namespace physx; -PxsContactManager::PxsContactManager(PxsContext*, PxU32 index) /*: - mUserData (NULL)*/ +PxsContactManager::PxsContactManager(PxsContext*, PxU32 index) { mFlags = 0; diff --git a/physx/source/lowlevel/software/src/PxsContext.cpp b/physx/source/lowlevel/software/src/PxsContext.cpp index c081bc3e9..c03e6e2d6 100644 --- a/physx/source/lowlevel/software/src/PxsContext.cpp +++ b/physx/source/lowlevel/software/src/PxsContext.cpp @@ -53,22 +53,21 @@ using namespace physx; -PxsContext::PxsContext(const PxSceneDesc& desc, PxTaskManager* taskManager, Cm::FlushPool& taskPool, PxCudaContextManager* cudaContextManager, - const PxU32 poolSlabSize, PxU64 contextID) : - mNpThreadContextPool (this), - mContactManagerPool ("mContactManagerPool", this, poolSlabSize), - mManifoldPool ("mManifoldPool", poolSlabSize), - mSphereManifoldPool ("mSphereManifoldPool", poolSlabSize), - mContactModifyCallback (NULL), - mNpImplementationContext (NULL), +PxsContext::PxsContext(const PxSceneDesc& desc, PxTaskManager* taskManager, Cm::FlushPool& taskPool, PxCudaContextManager* cudaContextManager, PxU32 poolSlabSize, PxU64 contextID) : + mNpThreadContextPool (this), + mContactManagerPool ("mContactManagerPool", this, poolSlabSize), + mManifoldPool ("mManifoldPool", poolSlabSize), + mSphereManifoldPool ("mSphereManifoldPool", poolSlabSize), + mContactModifyCallback (NULL), + mNpImplementationContext (NULL), mNpFallbackImplementationContext(NULL), - mTaskManager (taskManager), - mTaskPool (taskPool), - mCudaContextManager (cudaContextManager), - mPCM (desc.flags & PxSceneFlag::eENABLE_PCM), - mContactCache (false), - mCreateAveragePoint (desc.flags & PxSceneFlag::eENABLE_AVERAGE_POINT), - mContextID (contextID) + mTaskManager (taskManager), + mTaskPool (taskPool), + mCudaContextManager (cudaContextManager), + mPCM (desc.flags & PxSceneFlag::eENABLE_PCM), + mContactCache (false), + mCreateAveragePoint (desc.flags & PxSceneFlag::eENABLE_AVERAGE_POINT), + mContextID (contextID) { clearManagerTouchEvents(); mVisualizationCullingBox.setEmpty(); @@ -262,7 +261,7 @@ void PxsContext::createTransformCache(PxVirtualAllocatorCallback& allocatorCallb mTransformCache = PX_NEW(PxsTransformCache)(allocatorCallback); } -PxsContactManager* PxsContext::createContactManager(PxsContactManager* contactManager, const bool useCCD) +PxsContactManager* PxsContext::createContactManager(PxsContactManager* contactManager, bool useCCD) { PxsContactManager* cm = contactManager? contactManager : mContactManagerPool.get(); if(cm) @@ -580,61 +579,6 @@ bool PxsContext::fillManagerTouchEvents(PxvContactManagerTouchEvent* newTouch, P return true; } -bool PxsContext::fillManagerTouchEvents2(PxvContactManagerTouchEvent* newTouch, PxI32& newTouchCount, PxvContactManagerTouchEvent* lostTouch, PxI32& lostTouchCount, - PxvContactManagerTouchEvent* ccdTouch, PxI32& ccdTouchCount) -{ - const PxvContactManagerTouchEvent* newTouchStart = newTouch; - const PxvContactManagerTouchEvent* lostTouchStart = lostTouch; - const PxvContactManagerTouchEvent* ccdTouchStart = ccdTouch; - - const PxvContactManagerTouchEvent* newTouchEnd = newTouch + newTouchCount; - const PxvContactManagerTouchEvent* lostTouchEnd = lostTouch + lostTouchCount; - const PxvContactManagerTouchEvent* ccdTouchEnd = ccdTouch + ccdTouchCount; - - PX_UNUSED(newTouchEnd); - PX_UNUSED(lostTouchEnd); - PX_UNUSED(ccdTouchEnd); - - PxsContactManagerOutputCounts* counts = getNphaseImplementationContext()->getFoundPatchOutputCounts(); - PxsContactManager** managers = getNphaseImplementationContext()->getFoundPatchManagers(); - PxU32 nbFoundLost = getNphaseImplementationContext()->getNbFoundPatchManagers(); - - for (PxU32 i = 0; i < nbFoundLost; ++i) - { - //PxsContactManager* cm = managers[i]; - //if (cm->getTouchStatus()) - if (counts[i].statusFlag & PxcNpWorkUnitStatusFlag::eHAS_TOUCH) - { - //if (!cm->getHasCCDRetouch()) - if (!(counts[i].statusFlag & PxcNpWorkUnitStatusFlag::eHAS_CCD_RETOUCH)) - { - PX_ASSERT(newTouch < newTouchEnd); - newTouch->setCMTouchEventUserData(managers[i]->getShapeInteraction()); - newTouch++; - } - else - { - PX_ASSERT(ccdTouch); - PX_ASSERT(ccdTouch < ccdTouchEnd); - ccdTouch->setCMTouchEventUserData(managers[i]->getShapeInteraction()); - managers[i]->clearCCDRetouch(); - ccdTouch++; - } - } - else - { - PX_ASSERT(lostTouch < lostTouchEnd); - lostTouch->setCMTouchEventUserData(managers[i]->getShapeInteraction()); - lostTouch++; - } - } - - newTouchCount = PxI32(newTouch - newTouchStart); - lostTouchCount = PxI32(lostTouch - lostTouchStart); - ccdTouchCount = PxI32(ccdTouch - ccdTouchStart); - return true; -} - void PxsContext::beginUpdate() { #if PX_ENABLE_SIM_STATS diff --git a/physx/source/lowlevel/software/src/PxsDefaultMemoryManager.cpp b/physx/source/lowlevel/software/src/PxsDefaultMemoryManager.cpp index cef140925..93c1cace1 100644 --- a/physx/source/lowlevel/software/src/PxsDefaultMemoryManager.cpp +++ b/physx/source/lowlevel/software/src/PxsDefaultMemoryManager.cpp @@ -26,7 +26,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#include "PxsDefaultMemoryManager.h" // PT: TODO: remove this empty file? #include "PxsMemoryManager.h" #include "foundation/PxAllocator.h" #include "foundation/PxArray.h" diff --git a/physx/source/lowlevel/software/src/PxsIslandSim.cpp b/physx/source/lowlevel/software/src/PxsIslandSim.cpp index 25e738bd4..71998c096 100644 --- a/physx/source/lowlevel/software/src/PxsIslandSim.cpp +++ b/physx/source/lowlevel/software/src/PxsIslandSim.cpp @@ -34,39 +34,36 @@ #define IG_SANITY_CHECKS 0 -namespace physx +using namespace physx; +using namespace IG; + +IslandSim::IslandSim(PxArray* firstPartitionEdges, Cm::BlockArray& edgeNodeIndices, PxArray* destroyedPartitionEdges, PxU64 contextID) : + mNodes ("IslandSim::mNodes"), + mActiveNodeIndex ("IslandSim::mActiveNodeIndex"), + mIslands ("IslandSim::mIslands"), + mIslandStaticTouchCount ("IslandSim.activeStaticTouchCount"), + mActiveKinematicNodes ("IslandSim::mActiveKinematicNodes"), + mHopCounts ("IslandSim::mHopCounts"), + mFastRoute ("IslandSim::mFastRoute"), + mIslandIds ("IslandSim::mIslandIds"), + mActiveIslands ("IslandSim::mActiveIslands"), + mLastMapIndex (0), + mActivatingNodes ("IslandSim::mActivatingNodes"), + mDestroyedEdges ("IslandSim::mDestroyedEdges"), + mTempIslandIds ("IslandSim::mTempIslandIds"), + mVisitedNodes ("IslandSim::mVisitedNodes"), + mFirstPartitionEdges (firstPartitionEdges), + mEdgeNodeIndices (edgeNodeIndices), + mDestroyedPartitionEdges(destroyedPartitionEdges), + mContextId (contextID) { -namespace IG -{ - - IslandSim::IslandSim(PxArray* firstPartitionEdges, Cm::BlockArray& edgeNodeIndices, - PxArray* destroyedPartitionEdges, PxU64 contextID) : - mNodes("IslandSim::mNodes"), - mActiveNodeIndex("IslandSim::mActiveNodeIndex"), - mIslands("IslandSim::mIslands"), - mIslandStaticTouchCount("IslandSim.activeStaticTouchCount"), - mActiveKinematicNodes("IslandSim::mActiveKinematicNodes"), - mHopCounts("IslandSim::mHopCounts"), - mFastRoute("IslandSim::,FastRoute"), - mIslandIds("IslandSim::mIslandIds"), - mActiveIslands("IslandSim::mActiveIslands"), - mLastMapIndex(0), - mActivatingNodes("IslandSim::mActivatingNodes"), - mDestroyedEdges("IslandSim::mDestroyedEdges"), - mTempIslandIds("IslandSim::mTempIslandIds"), - mVisitedNodes("IslandSim::mVisitedNodes"), - mFirstPartitionEdges(firstPartitionEdges), - mEdgeNodeIndices(edgeNodeIndices), - mDestroyedPartitionEdges(destroyedPartitionEdges), - mContextId(contextID) + mNpIndexPtr = NULL; + for (PxU32 i = 0; i < Edge::eEDGE_TYPE_COUNT; ++i) { - mNpIndexPtr = NULL; - for (PxU32 i = 0; i < Edge::eEDGE_TYPE_COUNT; ++i) - { - mInitialActiveNodeCount[i] = 0; - mActiveEdgeCount[i] = 0; - } + mInitialActiveNodeCount[i] = 0; + mActiveEdgeCount[i] = 0; } +} #if PX_ENABLE_ASSERTS template @@ -81,7 +78,7 @@ static bool contains(PxArray& arr, const Thing& thing) } #endif -void IslandSim::resize(const PxU32 nbNodes, const PxU32 nbContactManagers, const PxU32 nbConstraints) +/*void IslandSim::resize(const PxU32 nbNodes, const PxU32 nbContactManagers, const PxU32 nbConstraints) { PxU32 totalEdges = nbContactManagers + nbConstraints; mNodes.reserve(nbNodes); @@ -89,11 +86,12 @@ void IslandSim::resize(const PxU32 nbNodes, const PxU32 nbContactManagers, const mEdges.reserve(totalEdges); mActiveContactEdges.resize(totalEdges); mEdgeInstances.reserve(totalEdges*2); -} +}*/ void IslandSim::addNode(bool isActive, bool isKinematic, Node::NodeType type, PxNodeIndex nodeIndex) { - PxU32 handle = nodeIndex.index(); + // PT: the nodeIndex is assigned by the SimpleIslandManager one level higher. + const PxU32 handle = nodeIndex.index(); if(handle == mNodes.capacity()) { const PxU32 newCapacity = PxMax(2*mNodes.capacity(), 256u); @@ -113,7 +111,6 @@ void IslandSim::addNode(bool isActive, bool isKinematic, Node::NodeType type, Px mActiveNodeIndex[handle] = PX_INVALID_NODE; - Node& node = mNodes[handle]; node.mType = PxTo8(type); //Ensure that the node is not currently being used. @@ -129,7 +126,7 @@ void IslandSim::addNode(bool isActive, bool isKinematic, Node::NodeType type, Px if(!isKinematic) { - IslandId islandHandle = mIslandHandles.getHandle(); + const IslandId islandHandle = mIslandHandles.getHandle(); if(islandHandle == mIslands.capacity()) { @@ -149,9 +146,7 @@ void IslandSim::addNode(bool isActive, bool isKinematic, Node::NodeType type, Px } if(isActive) - { activateNode(nodeIndex); - } } void IslandSim::addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive, PxNodeIndex nodeIndex) @@ -161,19 +156,13 @@ void IslandSim::addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive node.mRigidBody = body; } -void IslandSim::addArticulation(Sc::ArticulationSim* /*articulation*/, Dy::FeatherstoneArticulation* llArtic, bool isActive, PxNodeIndex nodeIndex) +void IslandSim::addArticulation(Dy::FeatherstoneArticulation* llArtic, bool isActive, PxNodeIndex nodeIndex) { addNode(isActive, false, Node::eARTICULATION_TYPE, nodeIndex); Node& node = mNodes[nodeIndex.index()]; node.mLLArticulation = llArtic; } -Sc::ArticulationSim* IslandSim::getArticulationSim(PxNodeIndex nodeIndex) const -{ - void* userData = getLLArticulation(nodeIndex)->getUserData(); - return reinterpret_cast(userData); -} - #if PX_SUPPORT_GPU_PHYSX void IslandSim::addSoftBody(Dy::SoftBody* llSoftBody, bool isActive, PxNodeIndex nodeIndex) { @@ -204,6 +193,12 @@ void IslandSim::addHairSystem(Dy::HairSystem* llHairSystem, bool isActive, PxNod } #endif +Sc::ArticulationSim* IslandSim::getArticulationSim(PxNodeIndex nodeIndex) const +{ + void* userData = getLLArticulation(nodeIndex)->getUserData(); + return reinterpret_cast(userData); +} + void IslandSim::connectEdge(EdgeInstance& instance, EdgeInstanceIndex edgeIndex, Node& source, PxNodeIndex /*destination*/) { PX_ASSERT(instance.mNextEdge == IG_INVALID_EDGE); @@ -221,7 +216,9 @@ void IslandSim::connectEdge(EdgeInstance& instance, EdgeInstanceIndex edgeIndex, } void IslandSim::addConnection(PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Edge::EdgeType edgeType, EdgeIndex handle) -{ +{ + // PT: the EdgeIndex is assigned by the SimpleIslandManager one level higher. + PX_UNUSED(nodeHandle1); PX_UNUSED(nodeHandle2); if(handle >= mEdges.capacity()) @@ -283,7 +280,7 @@ void IslandSim::addConnection(PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, void IslandSim::addConnectionToGraph(EdgeIndex handle) { - EdgeInstanceIndex instanceHandle = 2*handle; + const EdgeInstanceIndex instanceHandle = 2*handle; PX_ASSERT(instanceHandle < mEdgeInstances.capacity()); /*if(instanceHandle == mEdgeInstances.capacity()) { @@ -293,11 +290,12 @@ void IslandSim::addConnectionToGraph(EdgeIndex handle) Edge& edge = mEdges[handle]; + // PT: TODO: int bools bool activeEdge = false; bool kinematicKinematicEdge = true; - PxNodeIndex nodeIndex1 = mEdgeNodeIndices[instanceHandle]; - PxNodeIndex nodeIndex2 = mEdgeNodeIndices[instanceHandle+1]; + const PxNodeIndex nodeIndex1 = mEdgeNodeIndices[instanceHandle]; + const PxNodeIndex nodeIndex2 = mEdgeNodeIndices[instanceHandle+1]; if(nodeIndex1.index() != PX_INVALID_NODE) { @@ -307,7 +305,7 @@ void IslandSim::addConnectionToGraph(EdgeIndex handle) kinematicKinematicEdge = node.isKinematic(); } - if (nodeIndex1.index() != nodeIndex2.index() && nodeIndex2.index() != PX_INVALID_NODE) + if(nodeIndex1.index() != nodeIndex2.index() && nodeIndex2.index() != PX_INVALID_NODE) { Node& node = mNodes[nodeIndex2.index()]; connectEdge(mEdgeInstances[instanceHandle + 1], instanceHandle + 1, node, nodeIndex1); @@ -324,8 +322,8 @@ void IslandSim::addConnectionToGraph(EdgeIndex handle) void IslandSim::removeConnectionFromGraph(EdgeIndex edgeIndex) { - PxNodeIndex nodeIndex1 = mEdgeNodeIndices[2 * edgeIndex]; - PxNodeIndex nodeIndex2 = mEdgeNodeIndices[2 * edgeIndex+1]; + const PxNodeIndex nodeIndex1 = mEdgeNodeIndices[2 * edgeIndex]; + const PxNodeIndex nodeIndex2 = mEdgeNodeIndices[2 * edgeIndex+1]; if (nodeIndex1.index() != PX_INVALID_NODE) { Node& node = mNodes[nodeIndex1.index()]; @@ -354,7 +352,6 @@ void IslandSim::removeConnectionFromGraph(EdgeIndex edgeIndex) void IslandSim::disconnectEdge(EdgeInstance& instance, EdgeInstanceIndex edgeIndex, Node& node) { - PX_ASSERT(instance.mNextEdge == IG_INVALID_EDGE || mEdgeInstances[instance.mNextEdge].mPrevEdge == edgeIndex); PX_ASSERT(instance.mPrevEdge == IG_INVALID_EDGE || mEdgeInstances[instance.mPrevEdge].mNextEdge == edgeIndex); @@ -399,31 +396,21 @@ void IslandSim::removeConnection(EdgeIndex edgeIndex) void IslandSim::removeConnectionInternal(EdgeIndex edgeIndex) { PX_ASSERT(edgeIndex != IG_INVALID_EDGE); - EdgeInstanceIndex edgeInstanceBase = edgeIndex*2; - - - PxNodeIndex nodeIndex1 = mEdgeNodeIndices[edgeIndex * 2]; + const EdgeInstanceIndex edgeInstanceBase = edgeIndex*2; + const PxNodeIndex nodeIndex1 = mEdgeNodeIndices[edgeIndex * 2]; + const PxNodeIndex nodeIndex2 = mEdgeNodeIndices[edgeIndex * 2 + 1]; if (nodeIndex1.index() != PX_INVALID_NODE) - { - Node& node = mNodes[nodeIndex1.index()]; - disconnectEdge(mEdgeInstances[edgeInstanceBase], edgeInstanceBase, node); - } - - PxNodeIndex nodeIndex2 = mEdgeNodeIndices[edgeIndex * 2 + 1]; + disconnectEdge(mEdgeInstances[edgeInstanceBase], edgeInstanceBase, mNodes[nodeIndex1.index()]); if (nodeIndex2.index() != PX_INVALID_NODE && nodeIndex1.index() != nodeIndex2.index()) - { - Node& node = mNodes[nodeIndex2.index()]; - disconnectEdge(mEdgeInstances[edgeInstanceBase+1], edgeInstanceBase+1, node); - } + disconnectEdge(mEdgeInstances[edgeInstanceBase+1], edgeInstanceBase+1, mNodes[nodeIndex2.index()]); } - -void IslandSim::addContactManager(PxsContactManager* /*manager*/, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, EdgeIndex handle) +/*void IslandSim::addContactManager(PxsContactManager*, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, EdgeIndex handle) { addConnection(nodeHandle1, nodeHandle2, Edge::eCONTACT_MANAGER, handle); -} +}*/ void IslandSim::addConstraint(Dy::Constraint* /*constraint*/, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, EdgeIndex handle) { @@ -436,10 +423,8 @@ void IslandSim::activateNode(PxNodeIndex nodeIndex) { Node& node = mNodes[nodeIndex.index()]; - if(!(node.isActive() || - node.isActivating())) + if(!(node.isActive() || node.isActivating())) { - //If the node is kinematic and already in the active node list, then we need to remove it //from the active kinematic node list, then re-add it after the wake-up. It's a bit stupid //but it means that we don't need another index @@ -450,7 +435,7 @@ void IslandSim::activateNode(PxNodeIndex nodeIndex) //node.clearIsReadyForSleeping(); //Clear the "isReadyForSleeping" flag. Just in case it was set //return; - PxU32 activeRefCount = node.mActiveRefCount; + const PxU32 activeRefCount = node.mActiveRefCount; node.mActiveRefCount = 0; node.clearActive(); markKinematicInactive(nodeIndex); @@ -477,14 +462,14 @@ void IslandSim::deactivateNode(PxNodeIndex nodeIndex) //If the node is activating, clear its activating state and remove it from the activating list. //If it wasn't already activating, then it's probably already in the active list - bool wasActivating = node.isActivating(); + const bool wasActivating = node.isActivating(); if(wasActivating) { //Already activating, so remove it from the activating list node.clearActivating(); PX_ASSERT(mActivatingNodes[mActiveNodeIndex[nodeIndex.index()]].index() == nodeIndex.index()); - PxNodeIndex replaceIndex = mActivatingNodes[mActivatingNodes.size()-1]; + const PxNodeIndex replaceIndex = mActivatingNodes[mActivatingNodes.size()-1]; mActiveNodeIndex[replaceIndex.index()] = mActiveNodeIndex[nodeIndex.index()]; mActivatingNodes[mActiveNodeIndex[nodeIndex.index()]] = replaceIndex; mActivatingNodes.forceSize_Unsafe(mActivatingNodes.size()-1); @@ -509,12 +494,9 @@ void IslandSim::deactivateNode(PxNodeIndex nodeIndex) void IslandSim::putNodeToSleep(PxNodeIndex nodeIndex) { if(nodeIndex.index() != PX_INVALID_NODE) - { deactivateNode(nodeIndex); - } } - void IslandSim::activateNodeInternal(PxNodeIndex nodeIndex) { //This method should activate the node, then activate all the connections involving this node @@ -530,7 +512,7 @@ void IslandSim::activateNodeInternal(PxNodeIndex nodeIndex) while(index != IG_INVALID_EDGE) { - EdgeIndex idx = index/2; + const EdgeIndex idx = index/2; Edge& edge = mEdges[idx]; //InstanceIndex/2 = edgeIndex if(!edge.isActive()) { @@ -540,22 +522,17 @@ void IslandSim::activateNodeInternal(PxNodeIndex nodeIndex) markEdgeActive(idx); edge.activateEdge(); - } index = mEdgeInstances[index].mNextEdge; } if(node.isKinematic()) - { markKinematicActive(nodeIndex); - } else - { markActive(nodeIndex); - } + node.setActive(); } - } void IslandSim::deactivateNodeInternal(PxNodeIndex nodeIndex) @@ -567,13 +544,9 @@ void IslandSim::deactivateNodeInternal(PxNodeIndex nodeIndex) if(node.isActive()) { if(node.isKinematic()) - { markKinematicInactive(nodeIndex); - } else - { markInactive(nodeIndex); - } //Clear the active status flag node.clearActive(); @@ -583,14 +556,13 @@ void IslandSim::deactivateNodeInternal(PxNodeIndex nodeIndex) while(index != IG_INVALID_EDGE) { - EdgeInstance& instance = mEdgeInstances[index]; - + const EdgeInstance& instance = mEdgeInstances[index]; - PxNodeIndex outboundNode = mEdgeNodeIndices[index ^ 1]; + const PxNodeIndex outboundNode = mEdgeNodeIndices[index ^ 1]; if(outboundNode.index() == PX_INVALID_NODE || !mNodes[outboundNode.index()].isActive()) { - EdgeIndex idx = index/2; + const EdgeIndex idx = index/2; Edge& edge = mEdges[idx]; //InstanceIndex/2 = edgeIndex //PX_ASSERT(edge.isActive()); //The edge must currently be inactive because the node was active //Deactivate the edge if both nodes connected are inactive OR if one node is static/kinematic and the other is inactive... @@ -607,7 +579,6 @@ void IslandSim::deactivateNodeInternal(PxNodeIndex nodeIndex) index = instance.mNextEdge; } } - } bool IslandSim::canFindRoot(PxNodeIndex startNode, PxNodeIndex targetNode, PxArray* visitedNodes) @@ -627,21 +598,19 @@ bool IslandSim::canFindRoot(PxNodeIndex startNode, PxNodeIndex targetNode, PxArr do { - PxNodeIndex currentIndex = stack.popBack(); - Node& currentNode = mNodes[currentIndex.index()]; + const PxNodeIndex currentIndex = stack.popBack(); + const Node& currentNode = mNodes[currentIndex.index()]; EdgeInstanceIndex currentEdge = currentNode.mFirstEdgeIndex; while(currentEdge != IG_INVALID_EDGE) { - EdgeInstance& edge = mEdgeInstances[currentEdge]; - PxNodeIndex outboundNode = mEdgeNodeIndices[currentEdge ^ 1]; + const EdgeInstance& edge = mEdgeInstances[currentEdge]; + const PxNodeIndex outboundNode = mEdgeNodeIndices[currentEdge ^ 1]; if(outboundNode.index() != PX_INVALID_NODE && !mNodes[outboundNode.index()].isKinematic() && !visitedState.test(outboundNode.index())) { if(outboundNode.index() == targetNode.index()) - { return true; - } visitedState.set(outboundNode.index()); stack.pushBack(outboundNode); @@ -651,16 +620,12 @@ bool IslandSim::canFindRoot(PxNodeIndex startNode, PxNodeIndex targetNode, PxArr currentEdge = edge.mNextEdge; } - } while(stack.size()); return false; - } - - void IslandSim::unwindRoute(PxU32 traversalIndex, PxNodeIndex lastNode, PxU32 hopCount, IslandId id) { //We have found either a witness *or* the root node with this traversal. In the event of finding the root node, hopCount will be 0. In the event of finding @@ -703,7 +668,7 @@ void IslandSim::deactivateIsland(IslandId islandId) PxNodeIndex currentNode = island.mRootNode; while(currentNode.index() != PX_INVALID_NODE) { - Node& node = mNodes[currentNode.index()]; + const Node& node = mNodes[currentNode.index()]; //if(mActiveNodeIndex[currentNode.index()] < mInitialActiveNodeCount[node.mType]) mNodesToPutToSleep[node.mType].pushBack(currentNode); //If this node was previously active, then push it to the list of nodes to deactivate @@ -713,15 +678,13 @@ void IslandSim::deactivateIsland(IslandId islandId) markIslandInactive(islandId); } - void IslandSim::wakeIslands() { PX_PROFILE_ZONE("Basic.wakeIslands", getContextId()); //(1) Iterate over activating nodes and activate them - - PxU32 originalActiveIslands = mActiveIslands.size(); + const PxU32 originalActiveIslands = mActiveIslands.size(); for (PxU32 a = 0; a < Edge::eEDGE_TYPE_COUNT; ++a) { @@ -744,18 +707,17 @@ void IslandSim::wakeIslands() for(PxU32 a = 0; a < mActivatingNodes.size(); ++a) { - PxNodeIndex wakeNode = mActivatingNodes[a]; + const PxNodeIndex wakeNode = mActivatingNodes[a]; - IslandId islandId = mIslandIds[wakeNode.index()]; + const IslandId islandId = mIslandIds[wakeNode.index()]; Node& node = mNodes[wakeNode.index()]; node.clearActivating(); if(islandId != IG_INVALID_ISLAND) { if(!mIslandAwake.test(islandId)) - { markIslandActive(islandId); - } + mActiveNodeIndex[wakeNode.index()] = PX_INVALID_NODE; //Mark active node as invalid. activateNodeInternal(wakeNode); } @@ -771,17 +733,17 @@ void IslandSim::wakeIslands() EdgeInstanceIndex index = node.mFirstEdgeIndex; while(index != IG_INVALID_EDGE) { - EdgeInstance& edgeInstance = mEdgeInstances[index]; + const EdgeInstance& edgeInstance = mEdgeInstances[index]; - PxNodeIndex outboundNode = mEdgeNodeIndices[index ^ 1]; + const PxNodeIndex outboundNode = mEdgeNodeIndices[index ^ 1]; //Edge& edge = mEdges[index/2]; //if(edge.isConnected()) //Only wake up if the edge is not connected... - PxNodeIndex nodeIndex = outboundNode; + const PxNodeIndex nodeIndex = outboundNode; if (nodeIndex.isStaticBody() || mIslandIds[nodeIndex.index()] == IG_INVALID_ISLAND) { //If the edge connects to a static body *or* it connects to a node which is not part of an island (i.e. a kinematic), then activate the edge - EdgeIndex idx = index / 2; + const EdgeIndex idx = index / 2; Edge& edge = mEdges[idx]; if (!edge.isActive() && edge.getEdgeType() != IG::Edge::eCONSTRAINT) { @@ -791,12 +753,11 @@ void IslandSim::wakeIslands() markEdgeActive(idx); edge.activateEdge(); - } } else { - IslandId connectedIslandId = mIslandIds[nodeIndex.index()]; + const IslandId connectedIslandId = mIslandIds[nodeIndex.index()]; if(!mIslandAwake.test(connectedIslandId)) { //Wake up that island @@ -808,14 +769,12 @@ void IslandSim::wakeIslands() } } } - - mActivatingNodes.forceSize_Unsafe(0); for(PxU32 a = originalActiveIslands; a < mActiveIslands.size(); ++a) { - Island& island = mIslands[mActiveIslands[a]]; + const Island& island = mIslands[mActiveIslands[a]]; PxNodeIndex currentNode = island.mRootNode; while(currentNode.index() != PX_INVALID_NODE) @@ -828,22 +787,21 @@ void IslandSim::wakeIslands() void IslandSim::wakeIslands2() { - PxU32 originalActiveIslands = mActiveIslands.size(); + const PxU32 originalActiveIslands = mActiveIslands.size(); for (PxU32 a = 0; a < mActivatingNodes.size(); ++a) { - PxNodeIndex wakeNode = mActivatingNodes[a]; + const PxNodeIndex wakeNode = mActivatingNodes[a]; - IslandId islandId = mIslandIds[wakeNode.index()]; + const IslandId islandId = mIslandIds[wakeNode.index()]; Node& node = mNodes[wakeNode.index()]; node.clearActivating(); if (islandId != IG_INVALID_ISLAND) { if (!mIslandAwake.test(islandId)) - { markIslandActive(islandId); - } + mActiveNodeIndex[wakeNode.index()] = PX_INVALID_NODE; //Mark active node as invalid. activateNodeInternal(wakeNode); } @@ -859,17 +817,17 @@ void IslandSim::wakeIslands2() EdgeInstanceIndex index = node.mFirstEdgeIndex; while (index != IG_INVALID_EDGE) { - EdgeInstance& edgeInstance = mEdgeInstances[index]; + const EdgeInstance& edgeInstance = mEdgeInstances[index]; - PxNodeIndex outboundNode = mEdgeNodeIndices[index ^ 1]; + const PxNodeIndex outboundNode = mEdgeNodeIndices[index ^ 1]; //Edge& edge = mEdges[index/2]; //if(edge.isConnected()) //Only wake up if the edge is not connected... - PxNodeIndex nodeIndex = outboundNode; + const PxNodeIndex nodeIndex = outboundNode; if (nodeIndex.isStaticBody() || mIslandIds[nodeIndex.index()] == IG_INVALID_ISLAND) { //If the edge connects to a static body *or* it connects to a node which is not part of an island (i.e. a kinematic), then activate the edge - EdgeIndex idx = index / 2; + const EdgeIndex idx = index / 2; Edge& edge = mEdges[idx]; if (!edge.isActive() && edge.getEdgeType() != IG::Edge::eCONSTRAINT) { @@ -879,7 +837,6 @@ void IslandSim::wakeIslands2() markEdgeActive(idx); edge.activateEdge(); - } } else @@ -901,7 +858,7 @@ void IslandSim::wakeIslands2() for (PxU32 a = originalActiveIslands; a < mActiveIslands.size(); ++a) { - Island& island = mIslands[mActiveIslands[a]]; + const Island& island = mIslands[mActiveIslands[a]]; PxNodeIndex currentNode = island.mRootNode; while (currentNode.index() != PX_INVALID_NODE) @@ -922,7 +879,7 @@ void IslandSim::insertNewEdges() { for(PxU32 a = 0; a < mDirtyEdges[i].size(); ++a) { - EdgeIndex edgeIndex = mDirtyEdges[i][a]; + const EdgeIndex edgeIndex = mDirtyEdges[i][a]; Edge& edge = mEdges[edgeIndex]; @@ -945,9 +902,9 @@ void IslandSim::removeDestroyedEdges() for(PxU32 a = 0; a < mDestroyedEdges.size(); ++a) { - EdgeIndex edgeIndex = mDestroyedEdges[a]; + const EdgeIndex edgeIndex = mDestroyedEdges[a]; - Edge& edge = mEdges[edgeIndex]; + const Edge& edge = mEdges[edgeIndex]; if(edge.isPendingDestroyed()) { @@ -973,20 +930,18 @@ void IslandSim::processNewEdges() mHopCounts.resize(mNodes.size()); //Make sure we have enough space for hop counts for all nodes mFastRoute.resize(mNodes.size()); - for(PxU32 i = 0; i < Edge::eEDGE_TYPE_COUNT; ++i) { for(PxU32 a = 0; a < mDirtyEdges[i].size(); ++a) { - EdgeIndex edgeIndex = mDirtyEdges[i][a]; - Edge& edge = mEdges[edgeIndex]; + const EdgeIndex edgeIndex = mDirtyEdges[i][a]; + const Edge& edge = mEdges[edgeIndex]; /*PX_ASSERT(edge.mState != Edge::eDESTROYED || ((edge.mNode1.index() == PX_INVALID_NODE || mNodes[edge.mNode1.index()].isKinematic() || mNodes[edge.mNode1.index()].isActive() == false) && (edge.mNode2.index() == PX_INVALID_NODE || mNodes[edge.mNode2.index()].isKinematic() || mNodes[edge.mNode2.index()].isActive() == false)));*/ //edge.clearInDirtyList(); - //We do not process either destroyed or disconnected edges if(/*edge.isConnected() && */!edge.isPendingDestroyed()) { @@ -998,19 +953,19 @@ void IslandSim::processNewEdges() //(3) One body is already in an island and the other isn't, so we just add the new body to the existing island. //(4) Both bodies are in different islands. In that case, we merge the islands - PxNodeIndex nodeIndex1 = mEdgeNodeIndices[2 * edgeIndex]; - PxNodeIndex nodeIndex2 = mEdgeNodeIndices[2 * edgeIndex+1]; + const PxNodeIndex nodeIndex1 = mEdgeNodeIndices[2 * edgeIndex]; + const PxNodeIndex nodeIndex2 = mEdgeNodeIndices[2 * edgeIndex+1]; - IslandId islandId1 = nodeIndex1.index() == PX_INVALID_NODE ? IG_INVALID_ISLAND : mIslandIds[nodeIndex1.index()]; - IslandId islandId2 = nodeIndex2.index() == PX_INVALID_NODE ? IG_INVALID_ISLAND : mIslandIds[nodeIndex2.index()]; + const IslandId islandId1 = nodeIndex1.index() == PX_INVALID_NODE ? IG_INVALID_ISLAND : mIslandIds[nodeIndex1.index()]; + const IslandId islandId2 = nodeIndex2.index() == PX_INVALID_NODE ? IG_INVALID_ISLAND : mIslandIds[nodeIndex2.index()]; //TODO - wake ups!!!! //If one of the nodes is awake and the other is asleep, we need to wake 'em up //When a node is activated, the island must also be activated... - bool active1 = nodeIndex1.index() != PX_INVALID_NODE && mNodes[nodeIndex1.index()].isActive(); - bool active2 = nodeIndex2.index() != PX_INVALID_NODE && mNodes[nodeIndex2.index()].isActive(); + const bool active1 = nodeIndex1.index() != PX_INVALID_NODE && mNodes[nodeIndex1.index()].isActive(); + const bool active2 = nodeIndex2.index() != PX_INVALID_NODE && mNodes[nodeIndex2.index()].isActive(); IslandId islandId = IG_INVALID_ISLAND; @@ -1028,8 +983,8 @@ void IslandSim::processNewEdges() PX_ASSERT(mIslandAwake.test(islandId1)); //If we got here, where the 2 were already in an island, if 1 node is awake, the whole island must be awake } //Both bodies in the same island. Nothing major to do already but we should see if this creates a shorter path to root for either node - PxU32 hopCount1 = mHopCounts[nodeIndex1.index()]; - PxU32 hopCount2 = mHopCounts[nodeIndex2.index()]; + const PxU32 hopCount1 = mHopCounts[nodeIndex1.index()]; + const PxU32 hopCount2 = mHopCounts[nodeIndex2.index()]; if((hopCount1+1) < hopCount2) { //It would be faster for node 2 to go through node 1 @@ -1044,7 +999,6 @@ void IslandSim::processNewEdges() } //No need to activate/deactivate the island. Its state won't have changed - } else if(islandId1 == IG_INVALID_ISLAND) { @@ -1101,7 +1055,6 @@ void IslandSim::processNewEdges() //Island& island = mIslands[islandId2]; //island.mStaticTouchCount++; //Increment static touch counter on the island mIslandStaticTouchCount[islandId2]++; - } } else if (islandId2 == IG_INVALID_ISLAND) @@ -1159,7 +1112,6 @@ void IslandSim::processNewEdges() mIslandStaticTouchCount[islandId1]++; //island.mStaticTouchCount++; //Increment static touch counter on the island } - } else { @@ -1194,19 +1146,17 @@ void IslandSim::processNewEdges() } } } - } - } -bool IslandSim::isPathTo(PxNodeIndex startNode, PxNodeIndex targetNode) +bool IslandSim::isPathTo(PxNodeIndex startNode, PxNodeIndex targetNode) const { - Node& node = mNodes[startNode.index()]; + const Node& node = mNodes[startNode.index()]; EdgeInstanceIndex index = node.mFirstEdgeIndex; while(index != IG_INVALID_EDGE) { - EdgeInstance& instance = mEdgeInstances[index]; + const EdgeInstance& instance = mEdgeInstances[index]; if(/*mEdges[index/2].isConnected() &&*/ mEdgeNodeIndices[index^1].index() == targetNode.index()) return true; index = instance.mNextEdge; @@ -1221,7 +1171,7 @@ bool IslandSim::tryFastPath(PxNodeIndex startNode, PxNodeIndex targetNode, Islan PxNodeIndex currentNode = startNode; - PxU32 currentVisitedNodes = mVisitedNodes.size(); + const PxU32 currentVisitedNodes = mVisitedNodes.size(); PxU32 depth = 0; @@ -1254,7 +1204,7 @@ bool IslandSim::tryFastPath(PxNodeIndex startNode, PxNodeIndex targetNode, Islan for(PxU32 a = currentVisitedNodes; a < mVisitedNodes.size(); ++a) { - TraversalState& state = mVisitedNodes[a]; + const TraversalState& state = mVisitedNodes[a]; mIslandIds[state.mNodeIndex.index()] = islandId; } @@ -1262,19 +1212,17 @@ bool IslandSim::tryFastPath(PxNodeIndex startNode, PxNodeIndex targetNode, Islan { for(PxU32 a = currentVisitedNodes; a < mVisitedNodes.size(); ++a) { - TraversalState& state = mVisitedNodes[a]; + const TraversalState& state = mVisitedNodes[a]; mVisitedState.reset(state.mNodeIndex.index()); } mVisitedNodes.forceSize_Unsafe(currentVisitedNodes); } return found; - } bool IslandSim::findRoute(PxNodeIndex startNode, PxNodeIndex targetNode, IslandId islandId) { - //Firstly, traverse the fast path and tag up witnesses. TryFastPath can fail. In that case, no witnesses are left but this node is permitted to report //that it is still part of the island. Whichever node lost its fast path will be tagged as dirty and will be responsible for recovering the fast path //and tagging up the visited nodes @@ -1305,19 +1253,19 @@ bool IslandSim::findRoute(PxNodeIndex startNode, PxNodeIndex targetNode, IslandI do { - QueueElement currentQE = mPriorityQueue.pop(); + const QueueElement currentQE = mPriorityQueue.pop(); - TraversalState& currentState = *currentQE.mState; + const TraversalState& currentState = *currentQE.mState; - Node& currentNode = mNodes[currentState.mNodeIndex.index()]; + const Node& currentNode = mNodes[currentState.mNodeIndex.index()]; EdgeInstanceIndex edge = currentNode.mFirstEdgeIndex; while(edge != IG_INVALID_EDGE) { - EdgeInstance& instance = mEdgeInstances[edge]; + const EdgeInstance& instance = mEdgeInstances[edge]; { - PxNodeIndex nextIndex = mEdgeNodeIndices[edge ^ 1]; + const PxNodeIndex nextIndex = mEdgeNodeIndices[edge ^ 1]; //Static or kinematic nodes don't connect islands. if(nextIndex.index() != PX_INVALID_NODE && !mNodes[nextIndex.index()].isKinematic()) @@ -1335,7 +1283,7 @@ bool IslandSim::findRoute(PxNodeIndex startNode, PxNodeIndex targetNode, IslandI //We now need to test the island id to find out if this node knows the root. //If it has a valid root id, that id *is* our new root. We can guesstimate our hop count based on the node's properties - IslandId visitedIslandId = mIslandIds[nextIndex.index()]; + const IslandId visitedIslandId = mIslandIds[nextIndex.index()]; if(visitedIslandId != IG_INVALID_ISLAND) { //If we get here, we must have found a node that knows a route to our root node. It must not be a different island @@ -1370,9 +1318,7 @@ bool IslandSim::findRoute(PxNodeIndex startNode, PxNodeIndex targetNode, IslandI #define IG_LIMIT_DIRTY_NODES 0 - -void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allowDeactivation, bool permitKinematicDeactivation, - PxU32 dirtyNodeLimit) +void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allowDeactivation, bool permitKinematicDeactivation, PxU32 dirtyNodeLimit) { PX_UNUSED(dirtyNodeLimit); PX_PROFILE_ZONE("Basic.processLostEdges", getContextId()); @@ -1385,9 +1331,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo mPriorityQueue.reserve(1024); for (PxU32 i = 0; i < Edge::eEDGE_TYPE_COUNT; ++i) - { mIslandSplitEdges[i].reserve(1024); - } mVisitedNodes.reserve(mNodes.size()); //Make sure we have enough space for all nodes! @@ -1397,7 +1341,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo PX_PROFILE_ZONE("Basic.removeEdgesFromIslands", getContextId()); for (PxU32 a = 0; a < mDestroyedEdges.size(); ++a) { - EdgeIndex lostIndex = mDestroyedEdges[a]; + const EdgeIndex lostIndex = mDestroyedEdges[a]; Edge& lostEdge = mEdges[lostIndex]; if (lostEdge.isPendingDestroyed() && !lostEdge.isInDirtyList()) @@ -1405,8 +1349,8 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo //Process this edge... if (!lostEdge.isReportOnlyDestroy() && lostEdge.isInserted()) { - PxU32 index1 = mEdgeNodeIndices[mDestroyedEdges[a] * 2].index(); - PxU32 index2 = mEdgeNodeIndices[mDestroyedEdges[a] * 2 + 1].index(); + const PxU32 index1 = mEdgeNodeIndices[mDestroyedEdges[a] * 2].index(); + const PxU32 index2 = mEdgeNodeIndices[mDestroyedEdges[a] * 2 + 1].index(); IslandId islandId = IG_INVALID_ISLAND; if (index1 != PX_INVALID_NODE && index2 != PX_INVALID_NODE) @@ -1451,7 +1395,6 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo } lostEdge.clearInserted(); - } } } @@ -1460,7 +1403,6 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo { PX_PROFILE_ZONE("Basic.findPathsAndBreakIslands", getContextId()); - //KS - process only this many dirty nodes, deferring future dirty nodes to subsequent frames. //This means that it may take several frames for broken edges to trigger islands to completely break but this is better //than triggering large performance spikes. @@ -1473,7 +1415,6 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo PxBitMap::Iterator iter(mDirtyMap); #endif - PxU32 dirtyIdx; #if IG_LIMIT_DIRTY_NODES @@ -1491,7 +1432,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo mPriorityQueue.clear(); //Clear the queue used for traversal mVisitedNodes.forceSize_Unsafe(0); //Clear the list of nodes in this island - PxNodeIndex dirtyNodeIndex(dirtyIdx); + const PxNodeIndex dirtyNodeIndex(dirtyIdx); Node& dirtyNode = mNodes[dirtyNodeIndex.index()]; //Check whether this node has already been touched. If it has been touched this frame, then its island state is reliable @@ -1506,10 +1447,10 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo //Indicate that I've been visited - IslandId islandId = mIslandIds[dirtyNodeIndex.index()]; - Island& findIsland = mIslands[islandId]; + const IslandId islandId = mIslandIds[dirtyNodeIndex.index()]; + const Island& findIsland = mIslands[islandId]; - PxNodeIndex searchNode = findIsland.mRootNode;//The node that we're searching for! + const PxNodeIndex searchNode = findIsland.mRootNode;//The node that we're searching for! if (searchNode.index() != dirtyNodeIndex.index()) //If we are the root node, we don't need to do anything! { @@ -1578,7 +1519,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo for (PxU32 a = 0; a < mVisitedNodes.size(); ++a) { - PxNodeIndex index = mVisitedNodes[a].mNodeIndex; + const PxNodeIndex index = mVisitedNodes[a].mNodeIndex; Node& node = mNodes[index.index()]; if (node.mNextNode.index() != PX_INVALID_NODE) @@ -1601,9 +1542,9 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo while (idx != IG_INVALID_EDGE) { - EdgeInstance& instance = mEdgeInstances[idx]; + const EdgeInstance& instance = mEdgeInstances[idx]; const EdgeIndex edgeIndex = idx / 2; - Edge& edge = mEdges[edgeIndex]; + const Edge& edge = mEdges[edgeIndex]; //Only split the island if we're processing the first node or if the first node is infinte-mass if (!(idx & 1) || (mEdgeNodeIndices[idx & (~1)].index() == PX_INVALID_NODE || mNodes[mEdgeNodeIndices[idx & (~1)].index()].isKinematic())) @@ -1612,25 +1553,21 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo mIslandSplitEdges[edge.mEdgeType].pushBack(edgeIndex); removeEdgeFromIsland(oldIsland, edgeIndex); - } idx = instance.mNextEdge; } - } //oldIsland.mStaticTouchCount -= totalStaticTouchCount; mIslandStaticTouchCount[islandId] -= totalStaticTouchCount; for (PxU32 i = 0; i < Edge::eEDGE_TYPE_COUNT; ++i) - { oldIsland.mSize[i] -= size[i]; - } //Now add all these nodes to the new island //(1) Create the new island... - IslandId newIslandHandle = mIslandHandles.getHandle(); + const IslandId newIslandHandle = mIslandHandles.getHandle(); /*if(newIslandHandle == mIslands.capacity()) { mIslands.reserve(2*mIslands.capacity() + 1); @@ -1665,9 +1602,9 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo for (PxU32 a = 1; a < mVisitedNodes.size(); ++a) { - PxNodeIndex index = mVisitedNodes[a].mNodeIndex; + const PxNodeIndex index = mVisitedNodes[a].mNodeIndex; Node& thisNode = mNodes[index.index()]; - PxNodeIndex prevNodeIndex = mVisitedNodes[a - 1].mNodeIndex; + const PxNodeIndex prevNodeIndex = mVisitedNodes[a - 1].mNodeIndex; thisNode.mPrevNode = prevNodeIndex; mNodes[prevNodeIndex.index()].mNextNode = index; size[thisNode.mType]++; @@ -1680,7 +1617,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo newIsland.mSize[i] = size[i]; //Last node in the island - PxNodeIndex lastIndex = mVisitedNodes[mVisitedNodes.size() - 1].mNodeIndex; + const PxNodeIndex lastIndex = mVisitedNodes[mVisitedNodes.size() - 1].mNodeIndex; mNodes[lastIndex.index()].mNextNode.setIndices(PX_INVALID_NODE); newIsland.mLastNode = lastIndex; //newIsland.mStaticTouchCount = totalStaticTouchCount; @@ -1698,7 +1635,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo mEdges[splitEdges[0]].mNextIslandEdge = splitEdges[1]; for (PxU32 a = 1; a < splitEdgeSize; ++a) { - EdgeIndex edgeIndex = splitEdges[a]; + const EdgeIndex edgeIndex = splitEdges[a]; Edge& edge = mEdges[edgeIndex]; edge.mNextIslandEdge = splitEdges[a + 1]; edge.mPrevIslandEdge = splitEdges[a - 1]; @@ -1709,10 +1646,8 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo newIsland.mEdgeCount[j] = splitEdgeSize; } } - } } - } dirtyNode.clearDirty(); #if IG_LIMIT_DIRTY_NODES @@ -1720,8 +1655,6 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo #endif } - - #if IG_LIMIT_DIRTY_NODES mLastMapIndex = lastMapIndex; if (count < MaxCount) @@ -1733,14 +1666,13 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo //mDirtyNodes.forceSize_Unsafe(0); } - { PX_PROFILE_ZONE("Basic.clearDestroyedEdges", getContextId()); //Now process the lost edges... for (PxU32 a = 0; a < mDestroyedEdges.size(); ++a) { //Process these destroyed edges. Recompute island information. Update the islands and hop counters accordingly - EdgeIndex index = mDestroyedEdges[a]; + const EdgeIndex index = mDestroyedEdges[a]; Edge& edge = mEdges[index]; if (edge.isPendingDestroyed()) @@ -1771,8 +1703,8 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo for (PxU32 a = 0; a < destroyedNodes.size(); ++a) { - PxNodeIndex nodeIndex = destroyedNodes[a]; - IslandId islandId = mIslandIds[nodeIndex.index()]; + const PxNodeIndex nodeIndex = destroyedNodes[a]; + const IslandId islandId = mIslandIds[nodeIndex.index()]; Node& node = mNodes[nodeIndex.index()]; if (islandId != IG_INVALID_ISLAND) { @@ -1787,7 +1719,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo mIslandHandles.freeHandle(islandId); if (island.mActiveIndex != IG_INVALID_ISLAND) { - IslandId replaceId = mActiveIslands[mActiveIslands.size() - 1]; + const IslandId replaceId = mActiveIslands[mActiveIslands.size() - 1]; Island& replaceIsland = mIslands[replaceId]; replaceIsland.mActiveIndex = island.mActiveIndex; mActiveIslands[island.mActiveIndex] = replaceId; @@ -1833,7 +1765,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo PX_PROFILE_ZONE("Basic.deactivation", getContextId()); for (PxU32 a = 0; a < mActiveIslands.size(); a++) { - IslandId islandId = mActiveIslands[a]; + const IslandId islandId = mActiveIslands[a]; mIslandAwake.reset(islandId); } @@ -1841,7 +1773,7 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo //Loop over the active kinematic nodes and tag all islands touched by active kinematics as awake for (PxU32 a = mActiveKinematicNodes.size(); a > 0; --a) { - PxNodeIndex kinematicIndex = mActiveKinematicNodes[a - 1]; + const PxNodeIndex kinematicIndex = mActiveKinematicNodes[a - 1]; Node& kinematicNode = mNodes[kinematicIndex.index()]; @@ -1882,9 +1814,9 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo for (PxU32 a = mActiveIslands.size(); a > 0; --a) { - IslandId islandId = mActiveIslands[a - 1]; + const IslandId islandId = mActiveIslands[a - 1]; - Island& island = mIslands[islandId]; + const Island& island = mIslands[islandId]; bool canDeactivate = !mIslandAwake.test(islandId); mIslandAwake.set(islandId); @@ -1926,7 +1858,6 @@ void IslandSim::processLostEdges(PxArray& destroyedNodes, bool allo mDirtyEdges[i].clear(); //All new edges processed } } - } IslandId IslandSim::mergeIslands(IslandId island0, IslandId island1, PxNodeIndex node0, PxNodeIndex node1) @@ -1964,23 +1895,22 @@ IslandId IslandSim::mergeIslands(IslandId island0, IslandId island1, PxNodeIndex } } -bool IslandSim::checkInternalConsistency() +bool IslandSim::checkInternalConsistency() const { //Loop over islands, confirming that the island data is consistent... //Really expensive. Turn off unless investigating some random issue... #if 0 for (PxU32 a = 0; a < mIslands.size(); ++a) { - Island& island = mIslands[a]; + const Island& island = mIslands[a]; PxU32 expectedSize = island.mSize[0] + island.mSize[1]; bool metLastNode = expectedSize == 0; - NodeIndex nodeId = island.mRootNode; + PxNodeIndex nodeId = island.mRootNode; while (nodeId.index() != PX_INVALID_NODE) { - PX_ASSERT(mIslandIds[nodeId.index()] == a); if (nodeId.index() == island.mLastNode.index()) @@ -2000,7 +1930,6 @@ bool IslandSim::checkInternalConsistency() #endif return true; - } void IslandSim::mergeIslandsInternal(Island& island0, Island& island1, IslandId islandId0, IslandId islandId1, PxNodeIndex nodeIndex0, PxNodeIndex nodeIndex1) @@ -2027,8 +1956,7 @@ void IslandSim::mergeIslandsInternal(Island& island0, Island& island1, IslandId //mHopCounts[nodeIndex0] + mHopCounts[nodeIndex1] + 1 + mHopCounts[nodeIndex] to travel from any arbitrary node (nodeIndex) in island1 to the root //of island2. - - PxU32 extraPath = mHopCounts[nodeIndex0.index()] + mHopCounts[nodeIndex1.index()] + 1; + const PxU32 extraPath = mHopCounts[nodeIndex0.index()] + mHopCounts[nodeIndex1.index()] + 1; PxNodeIndex islandNode = island1.mRootNode; while(islandNode.index() != PX_INVALID_NODE) @@ -2055,13 +1983,9 @@ void IslandSim::mergeIslandsInternal(Island& island0, Island& island1, IslandId PX_ASSERT(mIslandIds[island0.mLastNode.index()] == islandId0); - - lastNode.mNextNode = island1.mRootNode; firstNode.mPrevNode = island0.mLastNode; - - island0.mLastNode = island1.mLastNode; //island0.mStaticTouchCount += island1.mStaticTouchCount; mIslandStaticTouchCount[islandId0] += mIslandStaticTouchCount[islandId1]; @@ -2094,7 +2018,6 @@ void IslandSim::mergeIslandsInternal(Island& island0, Island& island1, IslandId island1.mSize[a] = 0; } - island1.mLastNode.setIndices(PX_INVALID_NODE); island1.mRootNode.setIndices(PX_INVALID_NODE); @@ -2103,10 +2026,7 @@ void IslandSim::mergeIslandsInternal(Island& island0, Island& island1, IslandId //Remove from active island list if(island1.mActiveIndex != IG_INVALID_ISLAND) - { markIslandInactive(islandId1); - } - } void IslandSim::removeEdgeFromActivatingList(EdgeIndex index) @@ -2127,9 +2047,8 @@ void IslandSim::removeEdgeFromActivatingList(EdgeIndex index) edge.mEdgeState &= (~Edge::eACTIVATING); } - - PxNodeIndex nodeIndex1 = mEdgeNodeIndices[index * 2]; - PxNodeIndex nodeIndex2 = mEdgeNodeIndices[index * 2 + 1]; + const PxNodeIndex nodeIndex1 = mEdgeNodeIndices[index * 2]; + const PxNodeIndex nodeIndex2 = mEdgeNodeIndices[index * 2 + 1]; if (nodeIndex1.isValid() && nodeIndex2.isValid()) { @@ -2145,17 +2064,14 @@ void IslandSim::removeEdgeFromActivatingList(EdgeIndex index) if(edge.mEdgeType == Edge::eCONTACT_MANAGER) mActiveContactEdges.reset(index); - } void IslandSim::setKinematic(PxNodeIndex nodeIndex) { - Node& node = mNodes[nodeIndex.index()]; if(!node.isKinematic()) { - //Transition from dynamic to kinematic: //(1) Remove this node from the island //(2) Remove this node from the active node list @@ -2163,7 +2079,7 @@ void IslandSim::setKinematic(PxNodeIndex nodeIndex) //(4) Tag the node as kinematic //External code will re-filter interactions and lost touches will be reported - IslandId islandId = mIslandIds[nodeIndex.index()]; + const IslandId islandId = mIslandIds[nodeIndex.index()]; PX_ASSERT(islandId != IG_INVALID_ISLAND); Island& island = mIslands[islandId]; @@ -2172,7 +2088,7 @@ void IslandSim::setKinematic(PxNodeIndex nodeIndex) removeNodeFromIsland(island, nodeIndex); - bool isActive = node.isActive(); + const bool isActive = node.isActive(); if (isActive) { @@ -2185,7 +2101,7 @@ void IslandSim::setKinematic(PxNodeIndex nodeIndex) node.clearActivating(); PX_ASSERT(mActivatingNodes[mActiveNodeIndex[nodeIndex.index()]].index() == nodeIndex.index()); - PxNodeIndex replaceIndex = mActivatingNodes[mActivatingNodes.size() - 1]; + const PxNodeIndex replaceIndex = mActivatingNodes[mActivatingNodes.size() - 1]; mActiveNodeIndex[replaceIndex.index()] = mActiveNodeIndex[nodeIndex.index()]; mActivatingNodes[mActiveNodeIndex[nodeIndex.index()]] = replaceIndex; mActivatingNodes.forceSize_Unsafe(mActivatingNodes.size() - 1); @@ -2214,10 +2130,10 @@ void IslandSim::setKinematic(PxNodeIndex nodeIndex) EdgeInstanceIndex edgeId = node.mFirstEdgeIndex; while(edgeId != IG_INVALID_EDGE) { - EdgeInstance& instance = mEdgeInstances[edgeId]; - EdgeInstanceIndex nextId = instance.mNextEdge; + const EdgeInstance& instance = mEdgeInstances[edgeId]; + const EdgeInstanceIndex nextId = instance.mNextEdge; - PxU32 idx = edgeId/2; + const PxU32 idx = edgeId/2; IG::Edge& edge = mEdges[edgeId/2]; removeEdgeFromIsland(island, idx); @@ -2288,7 +2204,6 @@ void IslandSim::setDynamic(PxNodeIndex nodeIndex) //(4) Add this node to the active dynamic list (if it is active) //(5) Mark node as dynamic - Node& node = mNodes[nodeIndex.index()]; if(node.isKinematic()) @@ -2298,17 +2213,17 @@ void IslandSim::setDynamic(PxNodeIndex nodeIndex) EdgeInstanceIndex edgeId = node.mFirstEdgeIndex; while(edgeId != IG_INVALID_EDGE) { - EdgeInstance& instance = mEdgeInstances[edgeId]; - EdgeInstanceIndex nextId = instance.mNextEdge; + const EdgeInstance& instance = mEdgeInstances[edgeId]; + const EdgeInstanceIndex nextId = instance.mNextEdge; - PxNodeIndex otherNode = mEdgeNodeIndices[edgeId^1]; + const PxNodeIndex otherNode = mEdgeNodeIndices[edgeId^1]; - PxU32 idx = edgeId/2; + const PxU32 idx = edgeId/2; IG::Edge& edge = mEdges[edgeId/2]; if(!otherNode.isStaticBody()) { - IslandId islandId = mIslandIds[otherNode.index()]; + const IslandId islandId = mIslandIds[otherNode.index()]; if(islandId != IG_INVALID_ISLAND) removeEdgeFromIsland(mIslands[islandId], idx); } @@ -2341,7 +2256,6 @@ void IslandSim::setDynamic(PxNodeIndex nodeIndex) edgeId = nextId; } - if(!node.isActivating() && mActiveNodeIndex[nodeIndex.index()] != PX_INVALID_NODE) { //Remove from active kinematic list, add to active dynamic list @@ -2353,8 +2267,6 @@ void IslandSim::setDynamic(PxNodeIndex nodeIndex) node.clearKinematicFlag(); - - //Create an island for this node. If there are any edges affecting this node, they will have been marked as //"new" and will be processed next island update. { @@ -2377,7 +2289,6 @@ void IslandSim::setDynamic(PxNodeIndex nodeIndex) mIslandIds[nodeIndex.index()] = islandHandle; mIslandStaticTouchCount[islandHandle] = 0; - if(node.isActive()) { node.clearActive(); @@ -2387,6 +2298,3 @@ void IslandSim::setDynamic(PxNodeIndex nodeIndex) } } } - -} -} diff --git a/physx/source/lowlevel/software/src/PxsNphaseImplementationContext.cpp b/physx/source/lowlevel/software/src/PxsNphaseImplementationContext.cpp index adfdd58e3..b8b8abb86 100644 --- a/physx/source/lowlevel/software/src/PxsNphaseImplementationContext.cpp +++ b/physx/source/lowlevel/software/src/PxsNphaseImplementationContext.cpp @@ -50,6 +50,7 @@ using namespace physx; #pragma warning(push) #pragma warning(disable : 4324) #endif + class PxsCMUpdateTask : public Cm::Task { public: @@ -607,21 +608,6 @@ void PxsNphaseImplementationContext::secondPassUpdateContactManager(PxReal dt, P processContactManagerSecondPass(dt, continuation); } -PxsNphaseImplementationContext* PxsNphaseImplementationContext::create(PxsContext& context, IG::IslandSim* islandSim, PxVirtualAllocatorCallback* allocator) -{ - PxsNphaseImplementationContext* npImplContext = reinterpret_cast( - PX_ALLOC(sizeof(PxsNphaseImplementationContext), "PxsNphaseImplementationContext")); - - if (npImplContext) - { - //new(npImplContext) PxsNphaseImplementationContext(context, islandSim, allocator); - - npImplContext = PX_PLACEMENT_NEW(npImplContext, PxsNphaseImplementationContext)(context, islandSim, allocator); - } - - return npImplContext; -} - void PxsNphaseImplementationContext::destroy() { this->~PxsNphaseImplementationContext(); @@ -673,9 +659,14 @@ void PxsNphaseImplementationContext::registerContactManager(PxsContactManager* c mNewNarrowPhasePairs.mOutputContactManagers.pushBack(output); mNewNarrowPhasePairs.mCaches.pushBack(cache); mNewNarrowPhasePairs.mContactManagerMapping.pushBack(cm); - mNewNarrowPhasePairs.mShapeInteractions.pushBack(shapeInteraction); - mNewNarrowPhasePairs.mRestDistances.pushBack(cm->getRestDistance()); - mNewNarrowPhasePairs.mTorsionalProperties.pushBack(PxsTorsionalFrictionData(workUnit.mTorsionalPatchRadius, workUnit.mMinTorsionalPatchRadius)); + + if(mGPU) + { + mNewNarrowPhasePairs.mShapeInteractions.pushBack(shapeInteraction); + mNewNarrowPhasePairs.mRestDistances.pushBack(cm->getRestDistance()); + mNewNarrowPhasePairs.mTorsionalProperties.pushBack(PxsTorsionalFrictionData(workUnit.mTorsionalPatchRadius, workUnit.mMinTorsionalPatchRadius)); + } + PxU32 newSz = mNewNarrowPhasePairs.mOutputContactManagers.size(); workUnit.mNpIndex = mNewNarrowPhasePairs.computeId(newSz - 1) | PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK; } @@ -729,13 +720,13 @@ void PxsNphaseImplementationContext::refreshContactManager(PxsContactManager* cm if (!(index & PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK)) { output = mNarrowPhasePairs.mOutputContactManagers[PxsContactManagerBase::computeIndexFromId(index)]; - interaction = mNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index)]; + interaction = mGPU ? mNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index)] : cm->getShapeInteraction(); unregisterAndForceSize(mNarrowPhasePairs, index); } else { output = mNewNarrowPhasePairs.mOutputContactManagers[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))]; - interaction = mNewNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))]; + interaction = mGPU ? mNewNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))] : cm->getShapeInteraction(); //KS - the index in the "new" list will be the index unregisterAndForceSize(mNewNarrowPhasePairs, index); } @@ -775,7 +766,7 @@ void PxsNphaseImplementationContext::refreshContactManagerFallback(PxsContactMan if (!(index & PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK)) { output = cmOutputs[PxsContactManagerBase::computeIndexFromId(index)]; - interaction = mNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))]; + interaction = mGPU ? mNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))] : cm->getShapeInteraction(); //unregisterContactManagerInternal(index, mNarrowPhasePairs, cmOutputs); unregisterContactManagerFallback(cm, cmOutputs); } @@ -783,7 +774,7 @@ void PxsNphaseImplementationContext::refreshContactManagerFallback(PxsContactMan { //KS - the index in the "new" list will be the index output = mNewNarrowPhasePairs.mOutputContactManagers[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))]; - interaction = mNewNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))]; + interaction = mGPU ? mNewNarrowPhasePairs.mShapeInteractions[PxsContactManagerBase::computeIndexFromId(index & (~PxsContactManagerBase::NEW_CONTACT_MANAGER_MASK))] : cm->getShapeInteraction(); unregisterAndForceSize(mNewNarrowPhasePairs, index); } @@ -803,7 +794,7 @@ void PxsNphaseImplementationContext::appendContactManagers() //Copy new pairs to end of old pairs. Clear new flag, update npIndex on CM and clear the new pair buffer const PxU32 existingSize = mNarrowPhasePairs.mContactManagerMapping.size(); const PxU32 nbToAdd = mNewNarrowPhasePairs.mContactManagerMapping.size(); - const PxU32 newSize =existingSize + nbToAdd; + const PxU32 newSize = existingSize + nbToAdd; if(newSize > mNarrowPhasePairs.mContactManagerMapping.capacity()) { @@ -812,24 +803,33 @@ void PxsNphaseImplementationContext::appendContactManagers() mNarrowPhasePairs.mContactManagerMapping.reserve(newSz); mNarrowPhasePairs.mOutputContactManagers.reserve(newSz); mNarrowPhasePairs.mCaches.reserve(newSz); - mNarrowPhasePairs.mShapeInteractions.reserve(newSz); - mNarrowPhasePairs.mRestDistances.reserve(newSz); - mNarrowPhasePairs.mTorsionalProperties.reserve(newSz); + if(mGPU) + { + mNarrowPhasePairs.mShapeInteractions.reserve(newSz); + mNarrowPhasePairs.mRestDistances.reserve(newSz); + mNarrowPhasePairs.mTorsionalProperties.reserve(newSz); + } } mNarrowPhasePairs.mContactManagerMapping.forceSize_Unsafe(newSize); mNarrowPhasePairs.mOutputContactManagers.forceSize_Unsafe(newSize); mNarrowPhasePairs.mCaches.forceSize_Unsafe(newSize); - mNarrowPhasePairs.mShapeInteractions.forceSize_Unsafe(newSize); - mNarrowPhasePairs.mRestDistances.forceSize_Unsafe(newSize); - mNarrowPhasePairs.mTorsionalProperties.forceSize_Unsafe(newSize); + if(mGPU) + { + mNarrowPhasePairs.mShapeInteractions.forceSize_Unsafe(newSize); + mNarrowPhasePairs.mRestDistances.forceSize_Unsafe(newSize); + mNarrowPhasePairs.mTorsionalProperties.forceSize_Unsafe(newSize); + } PxMemCopy(mNarrowPhasePairs.mContactManagerMapping.begin() + existingSize, mNewNarrowPhasePairs.mContactManagerMapping.begin(), sizeof(PxsContactManager*)*nbToAdd); PxMemCopy(mNarrowPhasePairs.mOutputContactManagers.begin() + existingSize, mNewNarrowPhasePairs.mOutputContactManagers.begin(), sizeof(PxsContactManagerOutput)*nbToAdd); PxMemCopy(mNarrowPhasePairs.mCaches.begin() + existingSize, mNewNarrowPhasePairs.mCaches.begin(), sizeof(Gu::Cache)*nbToAdd); - PxMemCopy(mNarrowPhasePairs.mShapeInteractions.begin() + existingSize, mNewNarrowPhasePairs.mShapeInteractions.begin(), sizeof(Sc::ShapeInteraction*)*nbToAdd); - PxMemCopy(mNarrowPhasePairs.mRestDistances.begin() + existingSize, mNewNarrowPhasePairs.mRestDistances.begin(), sizeof(PxReal)*nbToAdd); - PxMemCopy(mNarrowPhasePairs.mTorsionalProperties.begin() + existingSize, mNewNarrowPhasePairs.mTorsionalProperties.begin(), sizeof(PxsTorsionalFrictionData)*nbToAdd); + if(mGPU) + { + PxMemCopy(mNarrowPhasePairs.mShapeInteractions.begin() + existingSize, mNewNarrowPhasePairs.mShapeInteractions.begin(), sizeof(Sc::ShapeInteraction*)*nbToAdd); + PxMemCopy(mNarrowPhasePairs.mRestDistances.begin() + existingSize, mNewNarrowPhasePairs.mRestDistances.begin(), sizeof(PxReal)*nbToAdd); + PxMemCopy(mNarrowPhasePairs.mTorsionalProperties.begin() + existingSize, mNewNarrowPhasePairs.mTorsionalProperties.begin(), sizeof(PxsTorsionalFrictionData)*nbToAdd); + } PxU32* edgeNodeIndices = mIslandSim->getEdgeNodeIndexPtr(); @@ -875,23 +875,32 @@ void PxsNphaseImplementationContext::appendContactManagersFallback(PxsContactMan mNarrowPhasePairs.mContactManagerMapping.reserve(newSz); mNarrowPhasePairs.mCaches.reserve(newSz); - mNarrowPhasePairs.mShapeInteractions.reserve(newSz); - mNarrowPhasePairs.mRestDistances.reserve(newSz); - mNarrowPhasePairs.mTorsionalProperties.reserve(newSz); + if(mGPU) + { + mNarrowPhasePairs.mShapeInteractions.reserve(newSz); + mNarrowPhasePairs.mRestDistances.reserve(newSz); + mNarrowPhasePairs.mTorsionalProperties.reserve(newSz); + } } mNarrowPhasePairs.mContactManagerMapping.forceSize_Unsafe(newSize); mNarrowPhasePairs.mCaches.forceSize_Unsafe(newSize); - mNarrowPhasePairs.mShapeInteractions.forceSize_Unsafe(newSize); - mNarrowPhasePairs.mRestDistances.forceSize_Unsafe(newSize); - mNarrowPhasePairs.mTorsionalProperties.forceSize_Unsafe(newSize); + if(mGPU) + { + mNarrowPhasePairs.mShapeInteractions.forceSize_Unsafe(newSize); + mNarrowPhasePairs.mRestDistances.forceSize_Unsafe(newSize); + mNarrowPhasePairs.mTorsionalProperties.forceSize_Unsafe(newSize); + } PxMemCopy(mNarrowPhasePairs.mContactManagerMapping.begin() + existingSize, mNewNarrowPhasePairs.mContactManagerMapping.begin(), sizeof(PxsContactManager*)*nbToAdd); PxMemCopy(cmOutputs + existingSize, mNewNarrowPhasePairs.mOutputContactManagers.begin(), sizeof(PxsContactManagerOutput)*nbToAdd); PxMemCopy(mNarrowPhasePairs.mCaches.begin() + existingSize, mNewNarrowPhasePairs.mCaches.begin(), sizeof(Gu::Cache)*nbToAdd); - PxMemCopy(mNarrowPhasePairs.mShapeInteractions.begin() + existingSize, mNewNarrowPhasePairs.mShapeInteractions.begin(), sizeof(Sc::ShapeInteraction*)*nbToAdd); - PxMemCopy(mNarrowPhasePairs.mRestDistances.begin() + existingSize, mNewNarrowPhasePairs.mRestDistances.begin(), sizeof(PxReal)*nbToAdd); - PxMemCopy(mNarrowPhasePairs.mTorsionalProperties.begin() + existingSize, mNewNarrowPhasePairs.mTorsionalProperties.begin(), sizeof(PxsTorsionalFrictionData)*nbToAdd); + if(mGPU) + { + PxMemCopy(mNarrowPhasePairs.mShapeInteractions.begin() + existingSize, mNewNarrowPhasePairs.mShapeInteractions.begin(), sizeof(Sc::ShapeInteraction*)*nbToAdd); + PxMemCopy(mNarrowPhasePairs.mRestDistances.begin() + existingSize, mNewNarrowPhasePairs.mRestDistances.begin(), sizeof(PxReal)*nbToAdd); + PxMemCopy(mNarrowPhasePairs.mTorsionalProperties.begin() + existingSize, mNewNarrowPhasePairs.mTorsionalProperties.begin(), sizeof(PxsTorsionalFrictionData)*nbToAdd); + } PxU32* edgeNodeIndices = mIslandSim->getEdgeNodeIndexPtr(); @@ -977,9 +986,12 @@ void PxsNphaseImplementationContext::unregisterContactManagerInternal(PxU32 npIn managers.mContactManagerMapping[index] = replaceManager; managers.mCaches[index] = managers.mCaches[replaceIndex]; cmOutputs[index] = cmOutputs[replaceIndex]; - managers.mShapeInteractions[index] = managers.mShapeInteractions[replaceIndex]; - managers.mRestDistances[index] = managers.mRestDistances[replaceIndex]; - managers.mTorsionalProperties[index] = managers.mTorsionalProperties[replaceIndex]; + if(mGPU) + { + managers.mShapeInteractions[index] = managers.mShapeInteractions[replaceIndex]; + managers.mRestDistances[index] = managers.mRestDistances[replaceIndex]; + managers.mTorsionalProperties[index] = managers.mTorsionalProperties[replaceIndex]; + } managers.mCaches[replaceIndex].reset(); PxcNpWorkUnit& replaceUnit = replaceManager->getWorkUnit(); @@ -1001,9 +1013,12 @@ void PxsNphaseImplementationContext::unregisterContactManagerInternal(PxU32 npIn managers.mContactManagerMapping.forceSize_Unsafe(replaceIndex); managers.mCaches.forceSize_Unsafe(replaceIndex); - managers.mShapeInteractions.forceSize_Unsafe(replaceIndex); - managers.mRestDistances.forceSize_Unsafe(replaceIndex); - managers.mTorsionalProperties.forceSize_Unsafe(replaceIndex); + if(mGPU) + { + managers.mShapeInteractions.forceSize_Unsafe(replaceIndex); + managers.mRestDistances.forceSize_Unsafe(replaceIndex); + managers.mTorsionalProperties.forceSize_Unsafe(replaceIndex); + } } PxsContactManagerOutput& PxsNphaseImplementationContext::getNewContactManagerOutput(PxU32 npId) @@ -1018,8 +1033,16 @@ PxsContactManagerOutputIterator PxsNphaseImplementationContext::getContactManage return PxsContactManagerOutputIterator(offsets, 1, mNarrowPhasePairs.mOutputContactManagers.begin()); } -PxvNphaseImplementationContextUsableAsFallback* physx::createNphaseImplementationContext(PxsContext& context, IG::IslandSim* islandSim, PxVirtualAllocatorCallback* allocator) +PxvNphaseImplementationContextUsableAsFallback* physx::createNphaseImplementationContext(PxsContext& context, IG::IslandSim* islandSim, PxVirtualAllocatorCallback* allocator, bool gpuDynamics) { - return PxsNphaseImplementationContext::create(context, islandSim, allocator); + // PT: TODO: remove useless placement new + + PxsNphaseImplementationContext* npImplContext = reinterpret_cast( + PX_ALLOC(sizeof(PxsNphaseImplementationContext), "PxsNphaseImplementationContext")); + + if(npImplContext) + npImplContext = PX_PLACEMENT_NEW(npImplContext, PxsNphaseImplementationContext)(context, islandSim, allocator, 0, gpuDynamics); + + return npImplContext; } diff --git a/physx/source/lowlevel/software/src/PxsSimpleIslandManager.cpp b/physx/source/lowlevel/software/src/PxsSimpleIslandManager.cpp index 6beaa6050..350d4cfa2 100644 --- a/physx/source/lowlevel/software/src/PxsSimpleIslandManager.cpp +++ b/physx/source/lowlevel/software/src/PxsSimpleIslandManager.cpp @@ -33,32 +33,30 @@ #include "CmTask.h" #include "DyVArticulation.h" - #define IG_SANITY_CHECKS 0 -namespace physx -{ -namespace IG +using namespace physx; +using namespace IG; + +ThirdPassTask::ThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager, IslandSim& islandSim) : Cm::Task(contextID), mIslandManager(islandManager), mIslandSim(islandSim) { - ThirdPassTask::ThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager, IslandSim& islandSim) : Cm::Task(contextID), mIslandManager(islandManager), mIslandSim(islandSim) - { - } +} - PostThirdPassTask::PostThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager) : Cm::Task(contextID), mIslandManager(islandManager) - { - } +PostThirdPassTask::PostThirdPassTask(PxU64 contextID, SimpleIslandManager& islandManager) : Cm::Task(contextID), mIslandManager(islandManager) +{ +} - SimpleIslandManager::SimpleIslandManager(bool useEnhancedDeterminism, PxU64 contextID) : - mDestroyedNodes ("mDestroyedNodes"), - mDestroyedEdges ("mDestroyedEdges"), - mFirstPartitionEdges ("mFirstPartitionEdges"), - mDestroyedPartitionEdges ("IslandSim::mDestroyedPartitionEdges"), - mIslandManager (&mFirstPartitionEdges, mEdgeNodeIndices, &mDestroyedPartitionEdges, contextID), - mSpeculativeIslandManager (NULL, mEdgeNodeIndices, NULL, contextID), - mSpeculativeThirdPassTask (contextID, *this, mSpeculativeIslandManager), - mAccurateThirdPassTask (contextID, *this, mIslandManager), - mPostThirdPassTask (contextID, *this), - mContextID (contextID) +SimpleIslandManager::SimpleIslandManager(bool useEnhancedDeterminism, PxU64 contextID) : + mDestroyedNodes ("mDestroyedNodes"), + mDestroyedEdges ("mDestroyedEdges"), + mFirstPartitionEdges ("mFirstPartitionEdges"), + mDestroyedPartitionEdges ("IslandSim::mDestroyedPartitionEdges"), + mIslandManager (&mFirstPartitionEdges, mEdgeNodeIndices, &mDestroyedPartitionEdges, contextID), + mSpeculativeIslandManager (NULL, mEdgeNodeIndices, NULL, contextID), + mSpeculativeThirdPassTask (contextID, *this, mSpeculativeIslandManager), + mAccurateThirdPassTask (contextID, *this, mIslandManager), + mPostThirdPassTask (contextID, *this), + mContextID (contextID) { mFirstPartitionEdges.resize(1024); mMaxDirtyNodesPerFrame = useEnhancedDeterminism ? 0xFFFFFFFF : 1000u; @@ -70,8 +68,8 @@ SimpleIslandManager::~SimpleIslandManager() PxNodeIndex SimpleIslandManager::addRigidBody(PxsRigidBody* body, bool isKinematic, bool isActive) { - PxU32 handle = mNodeHandles.getHandle(); - PxNodeIndex nodeIndex(handle); + const PxU32 handle = mNodeHandles.getHandle(); + const PxNodeIndex nodeIndex(handle); mIslandManager.addRigidBody(body, isKinematic, isActive, nodeIndex); mSpeculativeIslandManager.addRigidBody(body, isKinematic, isActive, nodeIndex); return nodeIndex; @@ -83,20 +81,20 @@ void SimpleIslandManager::removeNode(const PxNodeIndex index) mDestroyedNodes.pushBack(index); } -PxNodeIndex SimpleIslandManager::addArticulation(Sc::ArticulationSim* articulation, Dy::FeatherstoneArticulation* llArtic, bool isActive) +PxNodeIndex SimpleIslandManager::addArticulation(Dy::FeatherstoneArticulation* llArtic, bool isActive) { - PxU32 handle = mNodeHandles.getHandle(); - PxNodeIndex nodeIndex(handle); - mIslandManager.addArticulation(articulation, llArtic, isActive, nodeIndex); - mSpeculativeIslandManager.addArticulation(articulation, llArtic, isActive, nodeIndex); + const PxU32 handle = mNodeHandles.getHandle(); + const PxNodeIndex nodeIndex(handle); + mIslandManager.addArticulation(llArtic, isActive, nodeIndex); + mSpeculativeIslandManager.addArticulation(llArtic, isActive, nodeIndex); return nodeIndex; } #if PX_SUPPORT_GPU_PHYSX PxNodeIndex SimpleIslandManager::addSoftBody(Dy::SoftBody* llSoftBody, bool isActive) { - PxU32 handle = mNodeHandles.getHandle(); - PxNodeIndex nodeIndex(handle); + const PxU32 handle = mNodeHandles.getHandle(); + const PxNodeIndex nodeIndex(handle); mIslandManager.addSoftBody(llSoftBody, isActive, nodeIndex); mSpeculativeIslandManager.addSoftBody(llSoftBody, isActive, nodeIndex); return nodeIndex; @@ -104,8 +102,8 @@ PxNodeIndex SimpleIslandManager::addSoftBody(Dy::SoftBody* llSoftBody, bool isAc PxNodeIndex SimpleIslandManager::addFEMCloth(Dy::FEMCloth* llFEMCloth, bool isActive) { - PxU32 handle = mNodeHandles.getHandle(); - PxNodeIndex nodeIndex(handle); + const PxU32 handle = mNodeHandles.getHandle(); + const PxNodeIndex nodeIndex(handle); mIslandManager.addFEMCloth(llFEMCloth, isActive, nodeIndex); mSpeculativeIslandManager.addFEMCloth(llFEMCloth, isActive, nodeIndex); return nodeIndex; @@ -113,8 +111,8 @@ PxNodeIndex SimpleIslandManager::addFEMCloth(Dy::FEMCloth* llFEMCloth, bool isAc PxNodeIndex SimpleIslandManager::addParticleSystem(Dy::ParticleSystem* llParticleSystem, bool isActive) { - PxU32 handle = mNodeHandles.getHandle(); - PxNodeIndex nodeIndex(handle); + const PxU32 handle = mNodeHandles.getHandle(); + const PxNodeIndex nodeIndex(handle); mIslandManager.addParticleSystem(llParticleSystem, isActive, nodeIndex); mSpeculativeIslandManager.addParticleSystem(llParticleSystem, isActive, nodeIndex); return nodeIndex; @@ -122,20 +120,19 @@ PxNodeIndex SimpleIslandManager::addParticleSystem(Dy::ParticleSystem* llParticl PxNodeIndex SimpleIslandManager::addHairSystem(Dy::HairSystem* llHairSystem, bool isActive) { - PxU32 handle = mNodeHandles.getHandle(); - PxNodeIndex nodeIndex(handle); + const PxU32 handle = mNodeHandles.getHandle(); + const PxNodeIndex nodeIndex(handle); mIslandManager.addHairSystem(llHairSystem, isActive, nodeIndex); mSpeculativeIslandManager.addHairSystem(llHairSystem, isActive, nodeIndex); return nodeIndex; } #endif //PX_SUPPORT_GPU_PHYSX -EdgeIndex SimpleIslandManager::addContactManager(PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction, - Edge::EdgeType edgeType) +EdgeIndex SimpleIslandManager::addContactManager(PxsContactManager* manager, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction, Edge::EdgeType edgeType) { - EdgeIndex handle = mEdgeHandles.getHandle(); + const EdgeIndex handle = mEdgeHandles.getHandle(); - PxU32 nodeIds = 2 * handle; + const PxU32 nodeIds = 2 * handle; if (mEdgeNodeIndices.size() == nodeIds) { PX_PROFILE_ZONE("ReserveEdges", getContextId()); @@ -156,13 +153,10 @@ EdgeIndex SimpleIslandManager::addContactManager(PxsContactManager* manager, PxN manager->getWorkUnit().mEdgeIndex = handle; if (mConnectedMap.size() == handle) - { mConnectedMap.resize(2 * (handle + 1)); - } + if (mFirstPartitionEdges.capacity() == handle) - { mFirstPartitionEdges.resize(2 * (handle + 1)); - } mConnectedMap.reset(handle); return handle; @@ -170,9 +164,9 @@ EdgeIndex SimpleIslandManager::addContactManager(PxsContactManager* manager, PxN EdgeIndex SimpleIslandManager::addConstraint(Dy::Constraint* constraint, PxNodeIndex nodeHandle1, PxNodeIndex nodeHandle2, Sc::Interaction* interaction) { - EdgeIndex handle = mEdgeHandles.getHandle(); + const EdgeIndex handle = mEdgeHandles.getHandle(); - PxU32 nodeIds = 2 * handle; + const PxU32 nodeIds = 2 * handle; if (mEdgeNodeIndices.size() == nodeIds) { const PxU32 newSize = nodeIds + 2048; @@ -191,14 +185,11 @@ EdgeIndex SimpleIslandManager::addConstraint(Dy::Constraint* constraint, PxNodeI mIslandManager.addConstraint(constraint, nodeHandle1, nodeHandle2, handle); mSpeculativeIslandManager.addConstraint(constraint, nodeHandle1, nodeHandle2, handle); if(mConnectedMap.size() == handle) - { mConnectedMap.resize(2*(mConnectedMap.size()+1)); - } if (mFirstPartitionEdges.capacity() == handle) - { mFirstPartitionEdges.resize(2 * (mFirstPartitionEdges.capacity() + 1)); - } + mConnectedMap.set(handle); return handle; } @@ -263,9 +254,8 @@ void SimpleIslandManager::secondPassIslandGen() mIslandManager.processLostEdges(mDestroyedNodes, false, false, mMaxDirtyNodesPerFrame); for(PxU32 a = 0; a < mDestroyedNodes.size(); ++a) - { mNodeHandles.freeHandle(mDestroyedNodes[a].index()); - } + mDestroyedNodes.clear(); //mDestroyedEdges.clear(); } @@ -301,15 +291,13 @@ void ThirdPassTask::runInternal() void PostThirdPassTask::runInternal() { for (PxU32 a = 0; a < mIslandManager.mDestroyedNodes.size(); ++a) - { mIslandManager.mNodeHandles.freeHandle(mIslandManager.mDestroyedNodes[a].index()); - } + mIslandManager.mDestroyedNodes.clear(); for (PxU32 a = 0; a < mIslandManager.mDestroyedEdges.size(); ++a) - { mIslandManager.mEdgeHandles.freeHandle(mIslandManager.mDestroyedEdges[a]); - } + mIslandManager.mDestroyedEdges.clear(); PX_ASSERT(mIslandManager.validateDeactivations()); @@ -317,7 +305,6 @@ void PostThirdPassTask::runInternal() void SimpleIslandManager::thirdPassIslandGen(PxBaseTask* continuation) { - mIslandManager.clearDeactivations(); mPostThirdPassTask.setContinuation(continuation); @@ -336,8 +323,6 @@ void SimpleIslandManager::thirdPassIslandGen(PxBaseTask* continuation) //mIslandManager.removeDestroyedEdges(); //mIslandManager.processLostEdges(mDestroyedNodes, true, true); - - } bool SimpleIslandManager::checkInternalConsistency() @@ -406,7 +391,3 @@ void SimpleIslandManager::setDynamic(PxNodeIndex nodeIndex) mIslandManager.setDynamic(nodeIndex); mSpeculativeIslandManager.setDynamic(nodeIndex); } - -} -} - diff --git a/physx/source/lowlevelaabb/include/BpAABBManager.h b/physx/source/lowlevelaabb/include/BpAABBManager.h index 18e4a1a92..355cd196f 100644 --- a/physx/source/lowlevelaabb/include/BpAABBManager.h +++ b/physx/source/lowlevelaabb/include/BpAABBManager.h @@ -45,7 +45,6 @@ namespace Bp { struct BroadPhasePair; - // PT: TODO: revisit this..... class Aggregate; class PersistentPairs; class PersistentActorAggregatePair; @@ -141,9 +140,11 @@ namespace Bp virtual bool addBounds(BoundsIndex index, PxReal contactDistance, Bp::FilterGroup::Enum group, void* userdata, AggregateHandle aggregateHandle, ElementType::Enum volumeType) PX_OVERRIDE; virtual bool removeBounds(BoundsIndex index) PX_OVERRIDE; virtual void updateBPFirstPass(PxU32 numCpuTasks, Cm::FlushPool& flushPool, bool hasContactDistanceUpdated, PxBaseTask* continuation) PX_OVERRIDE; - virtual void updateBPSecondPass(PxU32 numCpuTasks, PxcScratchAllocator* scratchAllocator, PxBaseTask* continuation) PX_OVERRIDE; + virtual void updateBPSecondPass(PxcScratchAllocator* scratchAllocator, PxBaseTask* continuation) PX_OVERRIDE; virtual void postBroadPhase(PxBaseTask*, Cm::FlushPool& flushPool) PX_OVERRIDE; virtual void reallocateChangedAABBMgActorHandleMap(const PxU32 size) PX_OVERRIDE; + virtual bool getOutOfBoundsObjects(OutOfBoundsData& data) PX_OVERRIDE; + virtual void clearOutOfBoundsObjects() PX_OVERRIDE; virtual void visualize(PxRenderOutput& out) PX_OVERRIDE; virtual void releaseDeferredAggregateIds() PX_OVERRIDE{} //~AABBManagerBase @@ -177,10 +178,13 @@ namespace Bp PxArray mAggPairTasks; - PxHashSet mCreatedPairs; + PxHashSet mCreatedPairsTmp; // PT: temp hashset for dubious post filtering, persistent to minimize allocs PxSList mBpThreadContextPool; + PxArray mOutOfBoundsObjects; + PxArray mOutOfBoundsAggregates; + PX_FORCE_INLINE Aggregate* getAggregateFromHandle(AggregateHandle handle) { PX_ASSERT(handle mOutOfBoundsObjects; // PT: TODO: only on CPU - PxArray mOutOfBoundsAggregates; // PT: TODO: only on CPU PxArray mCreatedOverlaps[ElementType::eCOUNT]; PxArray mDestroyedOverlaps[ElementType::eCOUNT]; diff --git a/physx/source/lowlevelaabb/include/BpFiltering.h b/physx/source/lowlevelaabb/include/BpFiltering.h index 33dd33ec2..914459e12 100644 --- a/physx/source/lowlevelaabb/include/BpFiltering.h +++ b/physx/source/lowlevelaabb/include/BpFiltering.h @@ -55,8 +55,7 @@ namespace physx enum Enum { eSTATICS = 0, - ePARTICLES = 1, - eDYNAMICS_BASE = 2, + eDYNAMICS_BASE = 1, #ifdef BP_USE_AGGREGATE_GROUP_TAIL eAGGREGATE_BASE = 0xfffffffe, #endif diff --git a/physx/source/lowlevelaabb/include/BpVolumeData.h b/physx/source/lowlevelaabb/include/BpVolumeData.h index 34ada33a9..98e07aa85 100644 --- a/physx/source/lowlevelaabb/include/BpVolumeData.h +++ b/physx/source/lowlevelaabb/include/BpVolumeData.h @@ -108,7 +108,7 @@ namespace physx PX_CUDA_INLINE AggregateHandle getAggregate() const { return mAggregate >> 1; } private: - void* mUserData; + void* mUserData; // PT: in PhysX this is an Sc::ElementSim ptr // PT: TODO: consider moving this to a separate array, which wouldn't be allocated at all for people not using aggregates. // PT: current encoding: // aggregate == PX_INVALID_U32 => single actor diff --git a/physx/source/lowlevelaabb/src/BpAABBManager.cpp b/physx/source/lowlevelaabb/src/BpAABBManager.cpp index 38dc571ed..54cdeb163 100644 --- a/physx/source/lowlevelaabb/src/BpAABBManager.cpp +++ b/physx/source/lowlevelaabb/src/BpAABBManager.cpp @@ -42,7 +42,6 @@ #include "foundation/PxVecMath.h" #include "GuInternal.h" #include "common/PxProfileZone.h" -//#include using namespace physx; using namespace Bp; @@ -1033,12 +1032,14 @@ static void buildFreeBitmap(PxBitMap& bitmap, PxU32 currentFree, const PxArray* overlaps, const VolumeData* volumeData, PxU32 id0, PxU32 id1) +static PX_FORCE_INLINE void outputOverlap(PxArray* overlaps, const VolumeData* volumeData, PxU32 id0, PxU32 id1) { // overlaps.pushBack(AABBOverlap(volumeData[id0].userData, volumeData[id1].userData, handle)); const ElementType::Enum volumeType = PxMax(volumeData[id0].getVolumeType(), volumeData[id1].getVolumeType()); //overlaps[volumeType].pushBack(AABBOverlap(reinterpret_cast(size_t(id0)), reinterpret_cast(size_t(id1)))); - AABBOverlap* newPair = Cm::reserveContainerMemory(overlaps[volumeType], 1); - newPair->mUserData0 = reinterpret_cast(size_t(id0)); - newPair->mUserData1 = reinterpret_cast(size_t(id1)); + AABBOverlap* overlap = Cm::reserveContainerMemory(overlaps[volumeType], 1); + // PT: we don't convert to pointers right away because we need the IDs in postBpStage3 + overlap->mUserData0 = reinterpret_cast(size_t(id0)); + overlap->mUserData1 = reinterpret_cast(size_t(id1)); + // PT: note that overlap->mPairUserData remains uninitialized here +} + +static PX_FORCE_INLINE void createOverlap(PxArray* overlaps, const VolumeData* volumeData, PxU32 id0, PxU32 id1) +{ + outputOverlap(overlaps, volumeData, id0, id1); } static PX_FORCE_INLINE void deleteOverlap(PxArray* overlaps, const VolumeData* volumeData, PxU32 id0, PxU32 id1) { -// PX_ASSERT(volumeData[id0].userData); -// PX_ASSERT(volumeData[id1].userData); +// PX_ASSERT(volumeData[id0].getUserData()); +// PX_ASSERT(volumeData[id1].getUserData()); if (volumeData[id0].getUserData() && volumeData[id1].getUserData()) // PT: TODO: no idea if this is the right thing to do or if it's normal to get null ptrs here - { - const ElementType::Enum volumeType = PxMax(volumeData[id0].getVolumeType(), volumeData[id1].getVolumeType()); -// overlaps.pushBack(AABBOverlap(volumeData[id0].userData, volumeData[id1].userData, handle)); -// overlaps[volumeType].pushBack(AABBOverlap(reinterpret_cast(size_t(id0)), reinterpret_cast(size_t(id1)))); - - AABBOverlap* deletedPair = Cm::reserveContainerMemory(overlaps[volumeType], 1); - deletedPair->mUserData0 = reinterpret_cast(size_t(id0)); - deletedPair->mUserData1 = reinterpret_cast(size_t(id1)); - } + outputOverlap(overlaps, volumeData, id0, id1); } void PersistentPairs::outputDeletedOverlaps(PxArray* overlaps, const VolumeData* volumeData) @@ -1798,15 +1797,13 @@ void AABBManager::processBPDeletedPair(const BroadPhasePair& pair) else pairMap = &mActorAggregatePairs; // PT: actor-aggregate pair - PersistentPairs* p; + const AggPairMap::Entry* e = pairMap->find(AggPair(volA, volB)); + if(e) { - const AggPairMap::Entry* e = pairMap->find(AggPair(volA, volB)); - PX_ASSERT(e); - p = e->second; + PersistentPairs* p = e->second; + p->outputDeletedOverlaps(mDestroyedOverlaps, mVolumeData.begin()); + p->mShouldBeDeleted = true; } - - p->outputDeletedOverlaps(mDestroyedOverlaps, mVolumeData.begin()); - p->mShouldBeDeleted = true; } struct CreatedPairHandler @@ -1823,18 +1820,24 @@ template static void processBPPairs(PxU32 nbPairs, const BroadPhasePair* pairs, AABBManager& manager) { // PT: TODO: figure out this ShapeHandle/BpHandle thing. Is it ok to use "BP_INVALID_BP_HANDLE" for a "ShapeHandle"? +#if PX_DEBUG ShapeHandle previousA = BP_INVALID_BP_HANDLE; ShapeHandle previousB = BP_INVALID_BP_HANDLE; - +#endif while(nbPairs--) { PX_ASSERT(pairs->mVolA!=BP_INVALID_BP_HANDLE); PX_ASSERT(pairs->mVolB!=BP_INVALID_BP_HANDLE); +#if PX_DEBUG // PT: TODO: why is that test needed now? GPU broadphase? - if(pairs->mVolA != previousA || pairs->mVolB != previousB) + PX_ASSERT(pairs->mVolA != previousA || pairs->mVolB != previousB); +#endif + //if(pairs->mVolA != previousA || pairs->mVolB != previousB) { +#if PX_DEBUG previousA = pairs->mVolA; previousB = pairs->mVolB; +#endif FunctionT::processPair(manager, *pairs); } pairs++; @@ -2186,41 +2189,39 @@ void AABBManager::postBpStage2(PxBaseTask* continuation, Cm::FlushPool& flushPoo void AABBManager::postBpStage3(PxBaseTask*) { { + PX_PROFILE_ZONE("SimpleAABBManager::postBroadPhase - aggregate self-collisions", mContextID); + const PxU32 size = mDirtyAggregates.size(); + for (PxU32 i = 0; i < size; i++) { - PX_PROFILE_ZONE("SimpleAABBManager::postBroadPhase - aggregate self-collisions", mContextID); - const PxU32 size = mDirtyAggregates.size(); - for (PxU32 i = 0; i < size; i++) - { - Aggregate* aggregate = mDirtyAggregates[i]; - aggregate->resetDirtyState(); + Aggregate* aggregate = mDirtyAggregates[i]; + aggregate->resetDirtyState(); - } - mDirtyAggregates.resetOrClear(); } + mDirtyAggregates.resetOrClear(); + } - { - PX_PROFILE_ZONE("SimpleAABBManager::postBroadPhase - append pairs", mContextID); + { + PX_PROFILE_ZONE("SimpleAABBManager::postBroadPhase - append pairs", mContextID); - for (PxU32 a = 0; a < mAggPairTasks.size(); ++a) + for (PxU32 a = 0; a < mAggPairTasks.size(); ++a) + { + ProcessAggPairsBase* task = mAggPairTasks[a]; + for (PxU32 t = 0; t < 2; t++) { - ProcessAggPairsBase* task = mAggPairTasks[a]; - for (PxU32 t = 0; t < 2; t++) + for (PxU32 i = 0, startIdx = task->mCreatedPairs[t].mStartIdx; i < task->mCreatedPairs[t].mCount; ++i) { - for (PxU32 i = 0, startIdx = task->mCreatedPairs[t].mStartIdx; i < task->mCreatedPairs[t].mCount; ++i) - { - mCreatedOverlaps[t].pushBack((*task->mCreatedPairs[t].mArray)[i + startIdx]); - } - for (PxU32 i = 0, startIdx = task->mDestroyedPairs[t].mStartIdx; i < task->mDestroyedPairs[t].mCount; ++i) - { - mDestroyedOverlaps[t].pushBack((*task->mDestroyedPairs[t].mArray)[i + startIdx]); - } + mCreatedOverlaps[t].pushBack((*task->mCreatedPairs[t].mArray)[i + startIdx]); + } + for (PxU32 i = 0, startIdx = task->mDestroyedPairs[t].mStartIdx; i < task->mDestroyedPairs[t].mCount; ++i) + { + mDestroyedOverlaps[t].pushBack((*task->mDestroyedPairs[t].mArray)[i + startIdx]); } } + } - mAggPairTasks.forceSize_Unsafe(0); + mAggPairTasks.forceSize_Unsafe(0); - resetBpCacheData(); - } + resetBpCacheData(); } { @@ -2243,37 +2244,51 @@ void AABBManager::postBpStage3(PxBaseTask*) for (PxU32 idx=0; idxmUserData0)); + const PxU32 id1 = PxU32(size_t(overlaps->mUserData1)); + overlaps->mUserData0 = mVolumeData[id0].getUserData(); + overlaps->mUserData1 = mVolumeData[id1].getUserData(); + overlaps++; + if(nbDestroyedOverlaps) + mCreatedPairsTmp.insert(Pair(id0, id1)); } } - PxU32 newSize = 0; - for (PxU32 i = 0; i < nbDestroyedOverlaps; i++) { - const PxU32 id0 = PxU32(size_t(mDestroyedOverlaps[idx][i].mUserData0)); - const PxU32 id1 = PxU32(size_t(mDestroyedOverlaps[idx][i].mUserData1)); - if (!mCreatedPairs.contains(Pair(id0, id1))) + AABBOverlap* overlapsSrc = mDestroyedOverlaps[idx].begin(); + AABBOverlap* overlapsDst = overlapsSrc; + + PxU32 size = mDestroyedOverlaps[idx].size(); + PxU32 newSize = 0; + while(size--) { - mDestroyedOverlaps[idx][newSize].mUserData0 = mVolumeData[id0].getUserData(); - mDestroyedOverlaps[idx][newSize].mUserData1 = mVolumeData[id1].getUserData(); - newSize++; + const PxU32 id0 = PxU32(size_t(overlapsSrc->mUserData0)); + const PxU32 id1 = PxU32(size_t(overlapsSrc->mUserData1)); + overlapsSrc++; + + if(!mCreatedPairsTmp.contains(Pair(id0, id1))) + { + overlapsDst->mUserData0 = mVolumeData[id0].getUserData(); + overlapsDst->mUserData1 = mVolumeData[id1].getUserData(); + overlapsDst++; + newSize++; + } } + mDestroyedOverlaps[idx].forceSize_Unsafe(newSize); } - mDestroyedOverlaps[idx].forceSize_Unsafe(newSize); } } @@ -2338,6 +2353,21 @@ void AABBManager::resetBpCacheData() } } +bool AABBManager::getOutOfBoundsObjects(OutOfBoundsData& data) +{ + data.mNbOutOfBoundsObjects = mOutOfBoundsObjects.size(); + data.mOutOfBoundsObjects = mOutOfBoundsObjects.begin(); + data.mNbOutOfBoundsAggregates = mOutOfBoundsAggregates.size(); + data.mOutOfBoundsAggregates = mOutOfBoundsAggregates.begin(); + return data.mNbOutOfBoundsObjects || data.mNbOutOfBoundsAggregates; +} + +void AABBManager::clearOutOfBoundsObjects() +{ + mOutOfBoundsObjects.clear(); + mOutOfBoundsAggregates.clear(); +} + // PT: disabled this by default, since it bypasses all per-shape/per-actor visualization flags //static const bool gVisualizeAggregateElems = false; void AABBManager::visualize(PxRenderOutput& out) diff --git a/physx/source/lowlevelaabb/src/BpAABBManagerBase.cpp b/physx/source/lowlevelaabb/src/BpAABBManagerBase.cpp index cd899bc53..37b6775af 100644 --- a/physx/source/lowlevelaabb/src/BpAABBManagerBase.cpp +++ b/physx/source/lowlevelaabb/src/BpAABBManagerBase.cpp @@ -47,8 +47,6 @@ AABBManagerBase::AABBManagerBase( BroadPhase& bp, BoundsArray& boundsArray, PxFl mRemovedHandles (allocator), mBroadPhase (bp), mBoundsArray (boundsArray), - mOutOfBoundsObjects ("AABBManager::mOutOfBoundsObjects"), - mOutOfBoundsAggregates ("AABBManager::mOutOfBoundsAggregates"), mUsedSize (0), mNbAggregates (0), #ifdef BP_USE_AGGREGATE_GROUP_TAIL diff --git a/physx/source/lowleveldynamics/include/DyArticulationCore.h b/physx/source/lowleveldynamics/include/DyArticulationCore.h index 6385fc279..97aa3df22 100644 --- a/physx/source/lowleveldynamics/include/DyArticulationCore.h +++ b/physx/source/lowleveldynamics/include/DyArticulationCore.h @@ -37,12 +37,6 @@ namespace physx { struct ArticulationCore { - //= 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_SERIALIZATION ArticulationCore(const PxEMPTY) : flags(PxEmpty) {} ArticulationCore() {} diff --git a/physx/source/lowleveldynamics/include/DyArticulationJointCore.h b/physx/source/lowleveldynamics/include/DyArticulationJointCore.h index bd9224699..3b62ebf5c 100644 --- a/physx/source/lowleveldynamics/include/DyArticulationJointCore.h +++ b/physx/source/lowleveldynamics/include/DyArticulationJointCore.h @@ -42,12 +42,6 @@ namespace physx PX_ALIGN_PREFIX(16) struct ArticulationJointCore { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION diff --git a/physx/source/lowleveldynamics/include/DyConstraint.h b/physx/source/lowleveldynamics/include/DyConstraint.h index 7a8a4eab3..843696430 100644 --- a/physx/source/lowleveldynamics/include/DyConstraint.h +++ b/physx/source/lowleveldynamics/include/DyConstraint.h @@ -53,22 +53,21 @@ struct Constraint { public: - PxReal linBreakForce; //0 - PxReal angBreakForce; //4 - PxU16 constantBlockSize; //6 - PxU16 flags; //8 + PxReal linBreakForce; + PxReal angBreakForce; + PxU16 constantBlockSize; + PxU16 flags; - PxConstraintSolverPrep solverPrep; //12 - PxConstraintProject project; //16 - void* constantBlock; //20 + PxConstraintSolverPrep solverPrep; + void* constantBlock; - PxsRigidBody* body0; //24 - PxsRigidBody* body1; //28 + PxsRigidBody* body0; + PxsRigidBody* body1; - PxsBodyCore* bodyCore0; //32 - PxsBodyCore* bodyCore1; //36 - PxU32 index; //40 //this is also a constraint write back index - PxReal minResponseThreshold; //44 + PxsBodyCore* bodyCore0; + PxsBodyCore* bodyCore1; + PxU32 index; + PxReal minResponseThreshold; } PX_ALIGN_SUFFIX(16); #if PX_VC diff --git a/physx/source/lowleveldynamics/include/DyContext.h b/physx/source/lowleveldynamics/include/DyContext.h index 78c2672e7..8492d169c 100644 --- a/physx/source/lowleveldynamics/include/DyContext.h +++ b/physx/source/lowleveldynamics/include/DyContext.h @@ -35,181 +35,99 @@ #include "PxsSimulationController.h" #include "DyConstraintWriteBack.h" #include "foundation/PxAllocator.h" +#include "foundation/PxUserAllocated.h" #define DY_MAX_VELOCITY_COUNT 4 namespace physx { - -class PxsIslandManager; class PxcNpMemBlockPool; namespace Cm { - class EventProfiler; class FlushPool; } namespace IG { class SimpleIslandManager; - class IslandSim; } -template class PxcThreadCoherentCache; class PxcScratchAllocator; struct PxvSimStats; class PxTaskManager; -class PxsContactManagerOutputIterator; -struct PxsContactManagerOutput; class PxsContactManager; struct PxsContactManagerOutputCounts; class PxvNphaseImplementationContext; - namespace Dy { - -class Context +class Context : public PxUserAllocated { PX_NOCOPY(Context) public: // PT: TODO: consider making all of these public at this point - PX_FORCE_INLINE PxReal getMaxBiasCoefficient() const { return mMaxBiasCoefficient; } - PX_FORCE_INLINE void setMaxBiasCoefficient(PxReal coeff) { mMaxBiasCoefficient = coeff; } - - /** - \brief Returns the bounce threshold - \return The bounce threshold. - */ - PX_FORCE_INLINE PxReal getBounceThreshold() const { return mBounceThreshold; } - /** - \brief Returns the friction offset threshold - \return The friction offset threshold. - */ - PX_FORCE_INLINE PxReal getFrictionOffsetThreshold() const { return mFrictionOffsetThreshold; } - /** - \brief Returns the correlation distance - \return The correlation distance. - */ - PX_FORCE_INLINE PxReal getCorrelationDistance() const { return mCorrelationDistance; } + // PT: please avoid useless comments like "returns Blah" for a function called "getBlah". - /** - \brief Returns the CCD separation threshold - \return The CCD separation threshold. - */ - PX_FORCE_INLINE PxReal getCCDSeparationThreshold() const { return mCCDSeparationThreshold; } + PX_FORCE_INLINE PxReal getMaxBiasCoefficient() const { return mMaxBiasCoefficient; } + PX_FORCE_INLINE void setMaxBiasCoefficient(PxReal coeff) { mMaxBiasCoefficient = coeff; } - /** - \brief Returns the length scale - \return The length scale. - */ - PX_FORCE_INLINE PxReal getLengthScale() const { return mLengthScale; } + PX_FORCE_INLINE PxReal getCorrelationDistance() const { return mCorrelationDistance; } + PX_FORCE_INLINE void setCorrelationDistance(PxReal f) { mCorrelationDistance = f; } - /** - \brief Sets the bounce threshold - \param[in] f The bounce threshold - */ - PX_FORCE_INLINE void setBounceThreshold(PxReal f) { mBounceThreshold = f; } - /** - \brief Sets the correlation distance - \param[in] f The correlation distance - */ - PX_FORCE_INLINE void setCorrelationDistance(PxReal f) { mCorrelationDistance = f; } - /** - \brief Sets the friction offset threshold - \param[in] offset The friction offset threshold - */ - PX_FORCE_INLINE void setFrictionOffsetThreshold(PxReal offset) { mFrictionOffsetThreshold = offset; } + PX_FORCE_INLINE PxReal getBounceThreshold() const { return mBounceThreshold; } + PX_FORCE_INLINE void setBounceThreshold(PxReal f) { mBounceThreshold = f; } - /** - \brief Sets the friction offset threshold - \param[in] offset The friction offset threshold - */ - PX_FORCE_INLINE void setCCDSeparationThreshold(PxReal offset) { mCCDSeparationThreshold = offset; } + PX_FORCE_INLINE PxReal getFrictionOffsetThreshold() const { return mFrictionOffsetThreshold; } + PX_FORCE_INLINE void setFrictionOffsetThreshold(PxReal offset) { mFrictionOffsetThreshold = offset; } - /** - \brief Returns the solver batch size - \return The solver batch size. - */ - PX_FORCE_INLINE PxU32 getSolverBatchSize() const { return mSolverBatchSize; } - /** - \brief Sets the solver batch size - \param[in] f The solver batch size - */ - PX_FORCE_INLINE void setSolverBatchSize(PxU32 f) { mSolverBatchSize = f; } + PX_FORCE_INLINE PxReal getCCDSeparationThreshold() const { return mCCDSeparationThreshold; } + PX_FORCE_INLINE void setCCDSeparationThreshold(PxReal offset) { mCCDSeparationThreshold = offset; } - /** - \brief Returns the solver batch size - \return The solver batch size. - */ - PX_FORCE_INLINE PxU32 getSolverArticBatchSize() const { return mSolverArticBatchSize; } - /** - \brief Sets the solver batch size - \param[in] f The solver batch size - */ - PX_FORCE_INLINE void setSolverArticBatchSize(PxU32 f) { mSolverArticBatchSize = f; } + PX_FORCE_INLINE PxU32 getSolverBatchSize() const { return mSolverBatchSize; } + PX_FORCE_INLINE void setSolverBatchSize(PxU32 f) { mSolverBatchSize = f; } - /** - \brief Returns the maximum solver constraint size - \return The maximum solver constraint size in this island in bytes. - */ - PX_FORCE_INLINE PxU32 getMaxSolverConstraintSize() const { return mMaxSolverConstraintSize; } + PX_FORCE_INLINE PxU32 getSolverArticBatchSize() const { return mSolverArticBatchSize; } + PX_FORCE_INLINE void setSolverArticBatchSize(PxU32 f) { mSolverArticBatchSize = f; } - /** - \brief Returns the friction model being used. - \return The friction model being used. - */ - PX_FORCE_INLINE PxFrictionType::Enum getFrictionType() const { return mFrictionType; } + PX_FORCE_INLINE PxFrictionType::Enum getFrictionType() const { return mFrictionType; } + PX_FORCE_INLINE void setFrictionType(PxFrictionType::Enum f) { mFrictionType = f; } - /** - \brief Returns the threshold stream - \return The threshold stream - */ - PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; } + PX_FORCE_INLINE PxReal getDt() const { return mDt; } + PX_FORCE_INLINE void setDt(const PxReal dt) { mDt = dt; } + // PT: TODO: we have a setDt function but it doesn't set the inverse dt, what's the story here? + PX_FORCE_INLINE PxReal getInvDt() const { return mInvDt; } - PX_FORCE_INLINE ThresholdStream& getForceChangedThresholdStream() { return *mForceChangedThresholdStream; } - - /** - \brief Returns the threshold table - \return The threshold table - */ - PX_FORCE_INLINE ThresholdTable& getThresholdTable() { return mThresholdTable; } - - /** - \brief Sets the friction model to be used. - \param[in] f The friction model to be used. - */ - PX_FORCE_INLINE void setFrictionType(PxFrictionType::Enum f) { mFrictionType = f; } + //Forces any cached body state to be updated! + PX_FORCE_INLINE void setStateDirty(bool dirty) { mBodyStateDirty = dirty; } + PX_FORCE_INLINE bool isStateDirty() const { return mBodyStateDirty; } - /** - \brief Destroys this dynamics context - */ - virtual void destroy() = 0; + // Returns the maximum solver constraint size in this island in bytes. + PX_FORCE_INLINE PxU32 getMaxSolverConstraintSize() const { return mMaxSolverConstraintSize; } - PX_FORCE_INLINE PxcDataStreamPool& getContactStreamPool() { return mContactStreamPool; } + PX_FORCE_INLINE PxReal getLengthScale() const { return mLengthScale; } + PX_FORCE_INLINE const PxVec3& getGravity() const { return mGravity; } + PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; } - PX_FORCE_INLINE PxcDataStreamPool& getPatchStreamPool() { return mPatchStreamPool; } + PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; } + PX_FORCE_INLINE ThresholdStream& getForceChangedThresholdStream() { return *mForceChangedThresholdStream; } + PX_FORCE_INLINE ThresholdTable& getThresholdTable() { return mThresholdTable; } - PX_FORCE_INLINE PxcDataStreamPool& getForceStreamPool() { return mForceStreamPool; } + void createThresholdStream(PxVirtualAllocatorCallback& callback) { PX_ASSERT(!mThresholdStream); mThresholdStream = PX_NEW(ThresholdStream)(callback); } + void createForceChangeThresholdStream(PxVirtualAllocatorCallback& callback) { PX_ASSERT(!mForceChangedThresholdStream); mForceChangedThresholdStream = PX_NEW(ThresholdStream)(callback); } - PX_FORCE_INLINE PxPinnedArray& getConstraintWriteBackPool() { return mConstraintWriteBackPool; } + PX_FORCE_INLINE PxcDataStreamPool& getContactStreamPool() { return mContactStreamPool; } + PX_FORCE_INLINE PxcDataStreamPool& getPatchStreamPool() { return mPatchStreamPool; } + PX_FORCE_INLINE PxcDataStreamPool& getForceStreamPool() { return mForceStreamPool; } + PX_FORCE_INLINE PxPinnedArray& getConstraintWriteBackPool() { return mConstraintWriteBackPool; } /** - \brief Returns the current frame's timestep - \return The current frame's timestep. - */ - PX_FORCE_INLINE PxReal getDt() const { return mDt; } - /** - \brief Returns 1/(current frame's timestep) - \return 1/(current frame's timestep). + \brief Destroys this dynamics context */ - PX_FORCE_INLINE PxReal getInvDt() const { return mInvDt; } - - PX_FORCE_INLINE PxVec3 getGravity() const { return mGravity; } + virtual void destroy() = 0; /** \brief The entry point for the constraint solver. @@ -224,51 +142,35 @@ class Context Each island is solved as an independent solver task chain. In addition, large islands may be solved using multiple parallel tasks. Island solving is asynchronous. Once all islands have been solved, the continuation task will be called. - */ virtual void update(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* processLostTouchTask, - PxvNphaseImplementationContext* nPhaseContext, const PxU32 maxPatchesPerCM, const PxU32 maxArticulationLinks, const PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap) = 0; - - virtual void processLostPatches(IG::SimpleIslandManager& simpleIslandManager, PxsContactManager** lostPatchManagers, PxU32 nbLostPatchManagers, PxsContactManagerOutputCounts* outCounts) = 0; - virtual void processFoundPatches(IG::SimpleIslandManager& simpleIslandManager, PxsContactManager** foundPatchManagers, PxU32 nbFoundPatchManagers, PxsContactManagerOutputCounts* outCounts) = 0; + PxvNphaseImplementationContext* nPhaseContext, PxU32 maxPatchesPerCM, PxU32 maxArticulationLinks, PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap) = 0; + virtual void processLostPatches(IG::SimpleIslandManager& /*simpleIslandManager*/, PxsContactManager** /*lostPatchManagers*/, PxU32 /*nbLostPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/) {} + virtual void processFoundPatches(IG::SimpleIslandManager& /*simpleIslandManager*/, PxsContactManager** /*foundPatchManagers*/, PxU32 /*nbFoundPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/) {} /** \brief This method copy gpu solver body data to cpu body core */ - virtual void updateBodyCore(PxBaseTask* continuation) = 0; + virtual void updateBodyCore(PxBaseTask* /*continuation*/) {} /** - \brief Called after update's task chain has completed. This collects the results of the solver together + \brief Called after update's task chain has completed. This collects the results of the solver together. + This method combines the results of several islands, e.g. constructing scene-level simulation statistics and merging together threshold streams for contact notification. */ virtual void mergeResults() = 0; virtual void setSimulationController(PxsSimulationController* simulationController) = 0; - virtual void getDataStreamBase(void*& contactStreamBase, void*& patchStreamBase, void*& forceAndIndiceStreamBase) = 0; + virtual void getDataStreamBase(void*& /*contactStreamBase*/, void*& /*patchStreamBase*/, void*& /*forceAndIndicesStreamBase*/) {} virtual PxSolverType::Enum getSolverType() const = 0; - void createThresholdStream(PxVirtualAllocatorCallback& callback) { PX_ASSERT(!mThresholdStream); mThresholdStream = PX_NEW(ThresholdStream)(callback); } - - void createForceChangeThresholdStream(PxVirtualAllocatorCallback& callback) { PX_ASSERT(!mForceChangedThresholdStream); mForceChangedThresholdStream = PX_NEW(ThresholdStream)(callback); } - - //Forces any cached body state to be updated! - void setStateDirty(bool dirty) { mBodyStateDirty = dirty; } - - bool isStateDirty() { return mBodyStateDirty;} - - void setSuppressReadback(bool suppressReadback) { mSuppressReadback = suppressReadback; } - - bool getSuppressReadback() { return mSuppressReadback; } - - void setDt(const PxReal dt) { mDt = dt; } - protected: Context(IG::SimpleIslandManager* islandManager, PxVirtualAllocatorCallback* allocatorCallback, - PxvSimStats& simStats, bool enableStabilization, bool useEnhancedDeterminism, - const PxReal maxBiasCoefficient, const PxReal lengthScale) : + PxvSimStats& simStats, bool enableStabilization, bool useEnhancedDeterminism, + PxReal maxBiasCoefficient, PxReal lengthScale, PxU64 contextID) : mThresholdStream (NULL), mForceChangedThresholdStream(NULL), mIslandManager (islandManager), @@ -282,8 +184,8 @@ class Context mSolverBatchSize (32), mConstraintWriteBackPool (PxVirtualAllocator(allocatorCallback)), mSimStats (simStats), - mBodyStateDirty (false), - mSuppressReadback (false) + mContextID (contextID), + mBodyStateDirty (false) { } @@ -293,12 +195,12 @@ class Context PX_DELETE(mForceChangedThresholdStream); } - ThresholdStream* mThresholdStream; - ThresholdStream* mForceChangedThresholdStream; - ThresholdTable mThresholdTable; + ThresholdStream* mThresholdStream; + ThresholdStream* mForceChangedThresholdStream; + ThresholdTable mThresholdTable; - IG::SimpleIslandManager* mIslandManager; - PxsSimulationController* mSimulationController; + IG::SimpleIslandManager* mIslandManager; + PxsSimulationController* mSimulationController; /** \brief Time-step. */ @@ -339,7 +241,6 @@ class Context */ PxReal mCorrelationDistance; - /** \brief The length scale from PxTolerancesScale::length. */ @@ -355,7 +256,6 @@ class Context */ PxU32 mSolverArticBatchSize; - /** \brief The current friction model being used */ @@ -384,26 +284,19 @@ class Context PxvSimStats& mSimStats; + const PxU64 mContextID; + bool mBodyStateDirty; - bool mSuppressReadback; }; -Context* createDynamicsContext( PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, +Context* createDynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, PxU64 contextID, - const bool enableStabilization, const bool useEnhancedDeterminism, const PxReal maxBiasCoefficient, - const bool frictionEveryIteration, const PxReal lengthScale - ); - -Context* createTGSDynamicsContext(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, - PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, PxU64 contextID, - const bool enableStabilization, const bool useEnhancedDeterminism, const PxReal lengthScale -); - + IG::SimpleIslandManager* islandManager, PxU64 contextID, bool enableStabilization, bool useEnhancedDeterminism, + PxReal maxBiasCoefficient, bool frictionEveryIteration, PxReal lengthScale); +Context* createTGSDynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, + PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager, + IG::SimpleIslandManager* islandManager, PxU64 contextID, bool enableStabilization, bool useEnhancedDeterminism, PxReal lengthScale); } } diff --git a/physx/source/lowleveldynamics/include/DyFEMClothCore.h b/physx/source/lowleveldynamics/include/DyFEMClothCore.h index 1caf713a3..e0b2b8ba5 100644 --- a/physx/source/lowleveldynamics/include/DyFEMClothCore.h +++ b/physx/source/lowleveldynamics/include/DyFEMClothCore.h @@ -39,8 +39,6 @@ namespace physx { - class PxBuffer; - namespace Dy { struct FEMClothCore @@ -52,14 +50,14 @@ namespace physx bool dirty; PxReal wakeCounter; PxFEMClothFlags mFlags; - - // Ratio between target volume and rest volume in inflatable simulation. - PxReal mRestVolumeScale; + PxFEMClothDataFlags mDirtyFlags; PxArray mMaterialHandles; - PxBuffer* mClothPositionInvMass; - PxBuffer* mClothVelocity; - PxBuffer* mClothRestPosition; + + // device pointers + PxVec4* mPositionInvMass; + PxVec4* mVelocity; + PxVec4* mRestPosition; // multimaterial bending effects PxArray mBendingScales; @@ -71,6 +69,7 @@ namespace physx PxReal airDensity; PxReal maxVelocity; + PxReal maxDepenetrationVelocity; // negative values mean no activation angle: apply bending force toward rest bending angle PxReal mBendingActivationAngle; @@ -89,11 +88,14 @@ namespace physx wind = PxVec3(0.f); airDensity = 1.225f; // default: 1.225 kg/m^3 maxVelocity = 0.f; + maxDepenetrationVelocity = 0.f; mBendingActivationAngle = -1.f; - mRestVolumeScale = 0.0f; // No inflatable simulation by default. NbCollisionPairUpdatesPerTimestep = 1; nbCollisionSubsteps = 1; + + dirty = 0; + mDirtyFlags = PxFEMClothDataFlags(0); } void setMaterial(const PxU16 materialHandle) diff --git a/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h b/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h index 97f3f8bc7..e34e345e8 100644 --- a/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h +++ b/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h @@ -69,7 +69,6 @@ namespace Dy //#pragma warning(push) //#pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. //#endif - class ArticulationLinkData; struct SpatialSubspaceMatrix; @@ -82,7 +81,6 @@ namespace Dy struct Constraint; class ThreadContext; - struct ArticulationInternalTendonConstraint { Cm::UnAlignedSpatialVector row0; //24 24 @@ -131,7 +129,6 @@ namespace Dy PxReal highImpulse; //4 16 changed }; - struct ArticulationInternalConstraint : public ArticulationInternalConstraintBase { //Joint spring drive info @@ -212,8 +209,10 @@ namespace Dy PX_FORCE_INLINE Cm::SpatialVectorF* getMotionVelocities() { return mMotionVelocities.begin(); } PX_FORCE_INLINE Cm::SpatialVectorF* getMotionAccelerations() { return mMotionAccelerations.begin(); } PX_FORCE_INLINE const Cm::SpatialVectorF* getMotionAccelerations() const { return mMotionAccelerations.begin(); } + PX_FORCE_INLINE Cm::SpatialVectorF* getLinkIncomingJointForces() { return mLinkIncomingJointForces.begin(); } PX_FORCE_INLINE Cm::SpatialVectorF* getCorioliseVectors() { return mCorioliseVectors.begin(); } PX_FORCE_INLINE Cm::SpatialVectorF* getSpatialZAVectors() { return mZAForces.begin(); } + PX_FORCE_INLINE Cm::SpatialVectorF* getSpatialZAInternalVectors() { return mZAInternalForces.begin(); } PX_FORCE_INLINE Cm::SpatialVectorF* getTransmittedForces() { return mJointTransmittedForce.begin(); } PX_FORCE_INLINE Cm::SpatialVectorF* getPosIterMotionVelocities() { return mPosIterMotionVelocities.begin(); } @@ -259,7 +258,6 @@ namespace Dy PX_FORCE_INLINE ArticulationSensor** getSensors() const { return mSensors; } PX_FORCE_INLINE PxU32 getSensorCount() const { return mNbSensors; } - PX_FORCE_INLINE ArticulationLinkData* getLinkData() const { return mLinksData; } ArticulationLinkData& getLinkData(PxU32 index) const; @@ -289,6 +287,7 @@ namespace Dy PX_FORCE_INLINE void setArticulation(FeatherstoneArticulation* articulation) { mArticulation = articulation; } PX_FORCE_INLINE const SpatialMatrix& getBaseInvSpatialArticulatedInertiaW() const { return mBaseInvSpatialArticulatedInertiaW; } + PX_FORCE_INLINE SpatialMatrix& getBaseInvSpatialArticulatedInertiaW() { return mBaseInvSpatialArticulatedInertiaW; } PX_FORCE_INLINE PxTransform* getAccumulatedPoses() { return mAccumulatedPoses.begin(); } PX_FORCE_INLINE const PxTransform* getAccumulatedPoses() const { return mAccumulatedPoses.begin(); } @@ -308,7 +307,35 @@ namespace Dy PX_FORCE_INLINE const Cm::SpatialVectorF& getRootDeferredZ() const { return mRootDeferredZ; } PX_FORCE_INLINE Cm::SpatialVectorF& getRootDeferredZ() { return mRootDeferredZ; } - + PX_FORCE_INLINE const SpatialMatrix* getWorldSpatialArticulatedInertia() const { return mWorldSpatialArticulatedInertia.begin(); } + PX_FORCE_INLINE SpatialMatrix* getWorldSpatialArticulatedInertia() { return mWorldSpatialArticulatedInertia.begin(); } + + PX_FORCE_INLINE const Cm::UnAlignedSpatialVector* getWorldMotionMatrix() const { return mWorldMotionMatrix.begin(); } + PX_FORCE_INLINE Cm::UnAlignedSpatialVector* getWorldMotionMatrix() { return mWorldMotionMatrix.begin(); } + + PX_FORCE_INLINE const Cm::UnAlignedSpatialVector* getMotionMatrix() const { return mMotionMatrix.begin(); } + PX_FORCE_INLINE Cm::UnAlignedSpatialVector* getMotionMatrix() { return mMotionMatrix.begin(); } + + PX_FORCE_INLINE const Cm::SpatialVectorF* getIsW() const { return mIsW.begin(); } + PX_FORCE_INLINE Cm::SpatialVectorF* getIsW() { return mIsW.begin(); } + + PX_FORCE_INLINE const PxVec3* getRw() const { return mRw.begin(); } + PX_FORCE_INLINE PxVec3* getRw() { return mRw.begin(); } + + PX_FORCE_INLINE const PxReal* getMinusStZExt() const { return qstZIc.begin(); } + PX_FORCE_INLINE PxReal* getMinusStZExt() { return qstZIc.begin(); } + + PX_FORCE_INLINE const PxReal* getQstZIc() const { return qstZIc.begin(); } + PX_FORCE_INLINE PxReal* getQstZIc() { return qstZIc.begin(); } + + PX_FORCE_INLINE const PxReal* getQStZIntIc() const { return qstZIntIc.begin();} + PX_FORCE_INLINE PxReal* getQStZIntIc() { return qstZIntIc.begin();} + + PX_FORCE_INLINE const InvStIs* getInvStIS() const { return mInvStIs.begin(); } + PX_FORCE_INLINE InvStIs* getInvStIS() { return mInvStIs.begin(); } + + PX_FORCE_INLINE const Cm::SpatialVectorF* getISInvStIS() const { return mISInvStIS.begin(); } + PX_FORCE_INLINE Cm::SpatialVectorF* getISInvStIS() { return mISInvStIS.begin(); } PX_FORCE_INLINE SpatialImpulseResponseMatrix* getImpulseResponseMatrixWorld() { return mResponseMatrixW.begin(); } @@ -316,7 +343,6 @@ namespace Dy PX_FORCE_INLINE const SpatialMatrix& getWorldSpatialArticulatedInertia(const PxU32 linkID) const { return mWorldSpatialArticulatedInertia[linkID]; } - PX_FORCE_INLINE const InvStIs& getInvStIs(const PxU32 linkID) const { return mInvStIs[linkID]; } PX_FORCE_INLINE const Cm::UnAlignedSpatialVector& getMotionMatrix(const PxU32 dofId) const { return mMotionMatrix[dofId]; } @@ -329,18 +355,21 @@ namespace Dy PX_FORCE_INLINE const Cm::SpatialVectorF& getIsW(const PxU32 dofId) const { return mIsW[dofId]; } - PX_FORCE_INLINE const Cm::SpatialVectorF& getWorldIsInvD(const PxU32 dofId) const { return mIsInvDW[dofId]; } + PX_FORCE_INLINE const Cm::SpatialVectorF& getWorldIsInvD(const PxU32 dofId) const { return mISInvStIS[dofId]; } PX_FORCE_INLINE PxReal* getDeferredQstZ() { return mDeferredQstZ.begin(); } - PX_FORCE_INLINE PxReal* getQstZic() { return qstZIc.begin(); } - - PX_FORCE_INLINE Cm::SpatialVectorF& getSolverSpatialForce(const PxU32 linkID) { return mSolverSpatialForces[linkID]; } + PX_FORCE_INLINE Cm::SpatialVectorF& getSolverSpatialForce(const PxU32 linkID) { return mSolverLinkSpatialForces[linkID]; } PX_FORCE_INLINE PxSpatialForce* getSensorForces() { return mSensorForces; } PX_FORCE_INLINE void setRootPreMotionVelocity(const Cm::UnAlignedSpatialVector& vel) { mRootPreMotionVelocity.top = vel.top; mRootPreMotionVelocity.bottom = vel.bottom; } PX_FORCE_INLINE PxU32* getPathToRootElements() const { return mPathToRootElements; } PX_FORCE_INLINE PxU32 getPathToRootElementCount() const { return mNumPathToRootElements; } + PX_FORCE_INLINE const Cm::SpatialVectorF* getSolverSpatialForces() const {return mSolverLinkSpatialForces.begin();} + PX_FORCE_INLINE Cm::SpatialVectorF* getSolverSpatialForces() {return mSolverLinkSpatialForces.begin();} + + PX_FORCE_INLINE void incrementSolverSpatialDeltaVel(const PxU32 linkID, const Cm::SpatialVectorF& deltaV) {mSolverLinkSpatialDeltaVels[linkID] += deltaV;} + private: Cm::SpatialVectorF mRootPreMotionVelocity; Cm::SpatialVectorF mRootDeferredZ; @@ -354,9 +383,12 @@ namespace Dy PxArray mPosIterJointVelocities; //joint delta velocity after postion iternation before velocity iteration PxArray mPosIterMotionVelocities; //link motion velocites after position iteration before velocity iteration - PxArray mMotionVelocities; //link motion velocites - PxArray mSolverSpatialForces; + PxArray mMotionVelocities; //link motion velocites + PxArray mSolverLinkSpatialDeltaVels; //link DeltaVels arising from solver + PxArray mSolverLinkSpatialImpulses; //link impulses arising from solver. + PxArray mSolverLinkSpatialForces; PxArray mMotionAccelerations; //link motion accelerations + PxArray mLinkIncomingJointForces; PxArray mMotionAccelerationsInternal; //link motion accelerations PxArray mCorioliseVectors; //link coriolise vector PxArray mZAInternalForces; //link internal spatial forces @@ -366,7 +398,6 @@ namespace Dy PxArray mInternalLimits; PxArray mInternalSpatialTendonConstraints; PxArray mInternalFixedTendonConstraints; - PxArray mDeferredQstZ; @@ -390,7 +421,7 @@ namespace Dy PxArray mJointAxis; PxArray mMotionMatrix; PxArray mWorldMotionMatrix; - PxArray mIsInvDW; + PxArray mISInvStIS; PxArray mRw; PxArray mNbStatic1DConstraints; @@ -435,7 +466,6 @@ namespace Dy friend class FeatherstoneArticulation; }; - void ArticulationData::init() { //zero delta motion vector for TGS solver @@ -606,13 +636,17 @@ namespace Dy void assignSensors(const PxU32 nbSensors, Dy::ArticulationSensor** sensors, PxSpatialForce* sensorForces); - PxU32 getDofs(); + PxU32 getDofs() const; PxU32 getDof(const PxU32 linkID); bool applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, bool& shouldWake); - void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag); + void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, const bool isGpuSimEnabled); + + static PxU32 getCacheDataSize(PxU32 totalDofs, PxU32 linkCount, PxU32 sensorCount); + + static PxArticulationCache* createCache(PxU32 totalDofs, PxU32 linkCount, PxU32 sensorCount); void packJointData(const PxReal* maximum, PxReal* reduced); @@ -689,7 +723,7 @@ namespace Dy //this is called by island gen to determine whether the articulation should be awake or sleep Cm::SpatialVector getMotionVelocity(const PxU32 linkID) const; - Cm::SpatialVector getMotionAcceleration(const PxU32 linkID) const; + Cm::SpatialVector getMotionAcceleration(const PxU32 linkID, const bool isGpuSimEnabled) const; void fillIndexType(const PxU32 linkId, PxU8& indexType); @@ -718,9 +752,9 @@ namespace Dy PxU32& acCount, Cm::SpatialVectorF* Z); - static void saveVelocity(const ArticulationSolverDesc& d, Cm::SpatialVectorF* deltaV); + static void saveVelocity(FeatherstoneArticulation* articulation, Cm::SpatialVectorF* deltaV); - static void saveVelocityTGS(const ArticulationSolverDesc& d, PxReal invDtF32); + static void saveVelocityTGS(FeatherstoneArticulation* articulation, PxReal invDtF32); static void updateBodies(const ArticulationSolverDesc& desc, Cm::SpatialVectorF* tempDeltaV, PxReal dt); @@ -781,16 +815,25 @@ namespace Dy const Cm::UnAlignedSpatialVector* motionMatrix, const Cm::SpatialVectorF& Z, const Cm::SpatialVectorF& hDeltaV, const PxU32 dofCount); - - ////This method calculate zero acceration impulse due to test/actual impluse - //static Cm::SpatialVectorF propagateImpulse(const IsInvD& isInvD, const SpatialTransform& childToParent, - // const SpatialSubspaceMatrix& motionMatrix, const Cm::SpatialVectorF& Z); - - static Cm::SpatialVectorF propagateImpulseW(const Cm::SpatialVectorF* isInvD, const PxVec3& childToParent, - const Cm::UnAlignedSpatialVector* motionMatrix, const Cm::SpatialVectorF& Z, const PxU32 dofCount); - - static Cm::SpatialVectorF propagateImpulseW(const Cm::SpatialVectorF* isInvD, const PxVec3& childToParent, - const Cm::UnAlignedSpatialVector* motionMatrix, const Cm::SpatialVectorF& Z, const PxU32 dofCount, PxReal* qstZ); + /** + \brief Propagate a spatial impulse applied to a child link to its parent link. + The Mirtich equivalent is the equation for Y in Figure 5.7, page 141. + Optionally accumulate -s^T*Y for each dof of the child link's incoming joint. + Y = translateChildToParent{[ 1 - [(I * s) / (s^T * I * s)] * s^T] * Y} + \param[in] childToParent is the vector from child link to parent link + \param[in] linkYW is the impulse to apply to the child link. + \param[in] jointDofISInvStISW is (I * s) / (s^T * I * s) with one entry for each dof of the child link's incoming joint. + \param[in] jointDofMotionMatrixW is the motion matrix s with one entry for each dof of the child link's incoming joint. + \param[in] dofCount is the number of dofs of the child link's incoming joint. + \param[in,out] jointDofQStY accumulates -s^T*Y for each dof of the child link's incoming joint. + \note jointDofQStY may be NULL if there is no need to accumulate and record -s^T*Y for each dof of the child link's incoming joint. + \return The propagated spatial impulse. + */ + static Cm::SpatialVectorF propagateImpulseW( + const PxVec3& childToParent, + const Cm::SpatialVectorF& linkYW, + const Cm::SpatialVectorF* jointDofISInvStISW, const Cm::UnAlignedSpatialVector* jointDofMotionMatrixW, const PxU8 dofCount, + PxReal* jointDofQStY = NULL); bool applyCacheToDest(ArticulationData& data, PxArticulationCache& cache, PxReal* jVelocities, PxReal* jAcceleration, PxReal* jPosition, PxReal* jointForce, @@ -840,18 +883,14 @@ namespace Dy Cm::SpatialVectorF* Z, PxSolverConstraintPrepDesc& prepDesc, PxSolverBody& sBody, PxSolverBodyData& sBodyData, PxSolverConstraintDesc* desc, PxConstraintAllocator& allocator); - void updateArticulation(ScratchData& scratchData, - const PxVec3& gravity, - Cm::SpatialVectorF* Z, - Cm::SpatialVectorF* DeltaV, - const PxReal invLengthScale); + void updateArticulation(const PxVec3& gravity, const PxReal invLengthScale); void computeUnconstrainedVelocitiesInternal( const PxVec3& gravity, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV, const PxReal invLengthScale); //copy joint data from fromJointData to toJointData - void copyJointData(ArticulationData& data, PxReal* toJointData, const PxReal* fromJointData); + void copyJointData(const ArticulationData& data, PxReal* toJointData, const PxReal* fromJointData); PxU32 computeDofs(); //this function calculates motion subspace matrix(s) for all tree joint @@ -890,7 +929,23 @@ namespace Dy void computeC(ArticulationData& data, ScratchData& scratchData); //compute relative transform child to parent - void computeRelativeTransformC2P(ArticulationData& data); + /** + \brief a) copy the latest link pose to a handy array + b) update the link separation vectors using the latest link poses. + c) update the motion matrices in the world frame using the latest link poses. + \param[in] links is an array of articulation links that contain the latest link poses. + \param[in] linkCount is the number of links in the articulation + \param[in] jointCoreDatas is an array of joint descriptions + \param[in] jointDofMotionMatrices is an array of motion matrices in the joint frame. + \param[out] linkAccumulatedPoses is an array used to store the latest link poses taken from ArticulationLink::PxsBodyCore. + \param[out] linkRws is an array of link separations. + \param[out] jointDofmotionMatricesW is an array of motion matrices in the world frame. + */ + static void computeRelativeTransformC2P( + const ArticulationLink* links, const PxU32 linkCount, const ArticulationJointCoreData* jointCoreDatas, + const Cm::UnAlignedSpatialVector* jointDofMotionMatrices, + PxTransform* linkAccumulatedPoses, PxVec3* linkRws, Cm::UnAlignedSpatialVector* jointDofmotionMatricesW); + //compute relative transform child to base void computeRelativeTransformC2B(ArticulationData& data); @@ -904,25 +959,25 @@ namespace Dy \param[in] gravity is the gravitational acceleration to apply to all links. \param[in] fixBase determines whether the root link is to be fixed to the world (true) or will move freely (false). \param[in] linkCount is the total number of links in the articulation - \param[in] accumulatedPoses is the pose of each link, specified in the world frame. - \param[in] externalAccels is the external acceleration to apply to each link, specified in the world frame. - \param[in] rws is the vector from each parent link to each child link, specified in the world frame. - \param[in] worldMotionMatrices is the motion matrix of each link, specified in the world frame. + \param[in] linkAccumulatedPosesW is the pose of each link, specified in the world frame. + \param[in] linkExternalAccelsW is the external acceleration to apply to each link, specified in the world frame. + \param[in] linkRsW is the vector from each parent link to each child link, specified in the world frame. + \param[in] jointDofMotionMatricesW is the motion matrix of each dof, specified in the world frame. \param[in] jointCoreData is the ArticulationJointCoreData instance of each link in the articulation. \param[in,out] linkData is the ArticulationLinkData instance of each link in the articulation. \param[in,out] links is the ArticulationLink instance of each link in the articulation. - \param[in,out] motionAccelerations is the acceleration of each link, specified in the world frame. - \param[out] motionVelocities is velocity of each link computed from the parent link velocity and joint velocity of the inbound joint. Specified in the world frame. - \param[out] spatialZAForces is the computed spatial zero acceleration force of each link, accounting for only external forces applied to the links. Specified in the world frame. - \param[out] spatialZAInternal is the computed spatial zero acceleration force of each link, accounting for only internal forces applied to the links. Specified in the world frame. - \param[out] coriolisVectors is the computed coriolis vector of each link. Specified in the world frame. - \param[out] worldIsolatedSpatialArticulatedInertias is the inertia tensor (I) for the trivial sub-chain of each link. Specified in the world frame. + \param[in,out] jointDofMotionAccelerations is the acceleration of each link, specified in the world frame. + \param[out] jointDofMotionVelocities is velocity of each link computed from the parent link velocity and joint velocity of the inbound joint. Specified in the world frame. + \param[out] linkZAForcesExtW is the computed spatial zero acceleration force of each link, accounting for only external forces applied to the links. Specified in the world frame. + \param[out] linkZAForcesIntW is the computed spatial zero acceleration force of each link, accounting for only internal forces applied to the links. Specified in the world frame. + \param[out] linkCoriolisVectorsW is the computed coriolis vector of each link. Specified in the world frame. + \param[out] linkIsolatedArticulatedInertiasW is the inertia tensor (I) for the trivial sub-chain of each link. Specified in the world frame. \param[out] linkMasses is the mass of each link. - \param[out] worldSpatialArticulatedInertias is the spatial matrix containing the inertia tensor I and the mass matrix M for the trivial sub-chain of each link. Specified in the world frame. + \param[out] linkSpatialArticulatedInertiasW is the spatial matrix containing the inertia tensor I and the mass matrix M for the trivial sub-chain of each link. Specified in the world frame. \param[out] jointDofCount is the number of degrees of freedom for the entire articulation. - \param[in,out] jointVelocities is the velocity of each degree of freedom. - \param[out] rootPreMotionVelocity is assigned the spatial velocity of the root link. - \param[out] com is the centre of mass of the assembly of links, specified in the world frame. + \param[in,out] jointDofVelocities is the velocity of each degree of freedom. + \param[out] rootPreMotionVelocityW is assigned the spatial velocity of the root link. + \param[out] comW is the centre of mass of the assembly of links, specified in the world frame. \param[out] invSumMass is the reciprocal of the total mass of all links. \note invLengthScale should have value 1/100 for centimetres scale and 1/1 for metres scale. \note If fixBase is true, the root link is assigned zero velocity. If false, the root link inherits the velocity of the associated body core. @@ -940,31 +995,108 @@ namespace Dy const PxF32 dt, const PxReal invLengthScale, const PxVec3& gravity, const bool fixBase, const PxU32 linkCount, - const PxTransform* accumulatedPoses, const Cm::SpatialVector* externalAccels, const PxVec3* rws, const Cm::UnAlignedSpatialVector* worldMotionMatrices, + const PxTransform* linkAccumulatedPosesW, const Cm::SpatialVector* linkExternalAccelsW, const PxVec3* linkRsW, const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, const Dy::ArticulationJointCoreData* jointCoreData, - Dy::ArticulationLinkData *linkData, Dy::ArticulationLink* links, Cm::SpatialVectorF* motionAccelerations, - Cm::SpatialVectorF* motionVelocities, Cm::SpatialVectorF* spatialZAForces, Cm::SpatialVectorF* spatialZAInternal, Cm::SpatialVectorF* coriolisVectors, - PxMat33* worldIsolatedSpatialArticulatedInertias, PxF32* linkMasses, Dy::SpatialMatrix* worldSpatialArticulatedInertias, + Dy::ArticulationLinkData *linkData, Dy::ArticulationLink* links, + Cm::SpatialVectorF* jointDofMotionAccelerations, Cm::SpatialVectorF* jointDofMotionVelocities, + Cm::SpatialVectorF* linkZAForcesExtW, Cm::SpatialVectorF* linkZAForcesIntW, Cm::SpatialVectorF* linkCoriolisVectorsW, + PxMat33* linkIsolatedArticulatedInertiasW, PxF32* linkMasses, Dy::SpatialMatrix* linkSpatialArticulatedInertiasW, const PxU32 jointDofCount, - PxReal* jointVelocities, - Cm::SpatialVectorF& rootPreMotionVelocity, PxVec3& com, PxF32& invSumMass); - - void initLinks(ArticulationData& data, const PxVec3& gravity, - ScratchData& scratchData, Cm::SpatialVectorF* tZ, Cm::SpatialVectorF* tDeltaV); + PxReal* jointDofVelocities, + Cm::SpatialVectorF& rootPreMotionVelocityW, PxVec3& comW, PxF32& invSumMass); - void computeIs(ArticulationJointCoreData& jointDatum, ArticulationJointTargetData& jointTarget, const PxU32 linkID); - static SpatialMatrix computePropagateSpatialInertia_ZA_ZIc(const PxU8 jointType, const ArticulationJointTargetData& jointTarget, const ArticulationJointCoreData& jointDatum, - const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, Cm::SpatialVectorF* isInvD, const Cm::UnAlignedSpatialVector* motionMatrix, - const PxReal* jF, const Cm::SpatialVectorF& Z, const Cm::SpatialVectorF& ZIntIc, Cm::SpatialVectorF& ZA, Cm::SpatialVectorF& ZInt, PxReal* qstZ, - PxReal* qstZIntIc); - - static SpatialMatrix computePropagateSpatialInertia_ZA_ZIc_NonSeparated(const PxU8 jointType, const ArticulationJointTargetData& jointTarget, const ArticulationJointCoreData& jointDatum, - const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, Cm::SpatialVectorF* isInvD, const Cm::UnAlignedSpatialVector* motionMatrix, - const PxReal* jF, const Cm::SpatialVectorF& Z, Cm::SpatialVectorF& ZA, PxReal* qstZIc); + /** + \brief Propagate articulated z.a. spatial force and articulated spatial inertia from parent link to child link. + Repeated calls to computePropagateSpatialInertia_ZA_ZIc allow z.a. spatial force and articulated spatial inertia + to be propagated from tip to root. + The computation proceeds by considering a link/joint pair composed of a child link and its + incoming joint. + The articulated z.a. spatial force is split into an internal and external part. Gravity is added to the external + part, while user-applied external joint forces are added to the internal part. + \note Reference maths can be found in Eq 4.29 in Mirtich thesis. + \note Mirtich works in the joint frame while every quantity here is in the world frame. + \note linkArticulatedInertia has equivalent I_i^A in Mirtich + \note jointMotionMatrix has equivalent s_i and its transpose is s_i^T. + \param[in] jointType is the type of joint + \param[in] nbJointDofs is the number of dofs supported by the joint. + \param[in] jointMotionMatricesW is an array of motion matrices with one entry per dof. + \param[in] jointISW is a cached term linkArticulatedInertia*jointDofMotionMatrix with one entry per dof. + \param[in] jointTargetArmatures is an array of armature values with one entry per dof. + \param[in] jointExternalForces is an array of user-applied external forces applied to the joint wtih one entry per dof. + \param[in] linkArticulatedInertiaW is the articulated inertia of the link. + \param[in] linkZExtW is the external articulated z.a. force of the link. + \param[in] linkZIntIcW is the sum of the internal z.a force of the link and linkArticulatedInertia*coriolisForce + \param[out] linkInvStISW will be computed as 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[out] jointDofISInvStISW will be computed as linkArticulatedInertia*jointMotionMatrix^T/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[out] jointDofMinusStZExtW will be computed as [-jointMotionMatrix^T * ZExt] + \param[out] jointDofQStZIntIcW will be computed as [jointForce - jointMotionMatrix^T *ZIntIc] + \param[out] deltaZAExtParent is a term that is to be translated to parent link and added to the ZExt value of the parent link. + \param[out] deltaZAIntIcParent is a term that is to be translated to parent link and added to the ZInt value of the parent link. + \return A term to be translated to parent link and added to the articulated inertia of the parent. + */ + static SpatialMatrix computePropagateSpatialInertia_ZA_ZIc + (const PxArticulationJointType::Enum jointType, const PxU8 nbJointDofs, + const Cm::UnAlignedSpatialVector* jointMotionMatricesW, const Cm::SpatialVectorF* jointISW, + const PxReal* jointTargetArmatures, const PxReal* jointExternalForces, + const SpatialMatrix& linkArticulatedInertiaW, + const Cm::SpatialVectorF& linkZExtW, const Cm::SpatialVectorF& linkZIntIcW, + InvStIs& linkInvStISW, Cm::SpatialVectorF* jointDofISInvStISW, + PxReal* jointDofMinusStZExtW, PxReal* jointDofQStZIntIcW, + Cm::SpatialVectorF& deltaZAExtParent, Cm::SpatialVectorF& deltaZAIntIcParent); - static SpatialMatrix computePropagateSpatialInertia(const PxU8 jointType, ArticulationJointCoreData& jointDatum, - const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, Cm::SpatialVectorF* isInvD, - const Cm::UnAlignedSpatialVector* motionMatrix); + /** + \brief Propagate articulated z.a. spatial force and articulated spatial inertia from child link to parent link. + Repeated calls to computePropagateSpatialInertia_ZA_ZIc allow z.a. spatial force and articulated spatial inertia + to be propagated from tip to root. + The computation proceeds by considering a link/joint pair composed of a child link and its incoming joint. + \note Reference maths can be found in Eq 4.29 in Mirtich thesis. + \note Mirtich works in the joint frame while every quantity here is in the world frame. + \note linkArticulatedInertia has equivalent I_i^A in Mirtich + \note jointMotionMatrix has equivalent s_i + \param[in] jointType is the type of joint + \param[in] nbJointDofs is the number of dofs supported by the joint. + \param[in] jointMotionMatrices is an array of motion matrices with one entry per dof. + \param[in] jointIs is a cached term linkArticulatedInertia*jointDofMotionMatrix with one entry per dof. + \param[in] jointTargetArmatures is an array of armature values with one entry per dof. + \param[in] jointExternalForces is an array of user-applied external forces applied to the joint with one entry per dof. + \param[in] linkArticulatedInertia is the articulated inertia of the link. + \param[in] ZIc is the sum of the z.a force of the link and linkArticulatedInertia*coriolisForce. + \param[out] invStIs will be computed as 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[out] isInvD will be computed as linkArticulatedInertia*jointMotionMatrix^T/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[out] qstZIc will be computed as [jointForce - jointMotionMatrix^T *ZIc]/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[out] deltaZParent is a term that is to be translated to parent link and added to the articulated z.a force of the parent link. + \return A term to be translated to parent link and added to the articulated inertia of the parent. + */ + static SpatialMatrix computePropagateSpatialInertia_ZA_ZIc_NonSeparated + (const PxArticulationJointType::Enum jointType, const PxU8 nbJointDofs, + const Cm::UnAlignedSpatialVector* jointMotionMatrices, const Cm::SpatialVectorF* jointIs, + const PxReal* jointTargetArmatures, const PxReal* jointExternalForces, + const SpatialMatrix& linkArticulatedInertia, + const Cm::SpatialVectorF& ZIc, + InvStIs& invStIs, Cm::SpatialVectorF* isInvD, + PxReal* qstZIc, + Cm::SpatialVectorF& deltaZParent); + + /* + \brief Propagate articulated spatial inertia (but not the articulated z.a. spatial force) from child link to parent link. + Repeated calls to computePropagateSpatialInertia allow the articulated spatial inertia + to be propagated from tip to root. + The computation proceeds by considering a link/joint pair composed of a child link and its + incoming joint. + \param[in] jointType is the type of joint + \param[in] nbJointDofs is the number of dofs supported by the joint. + \param[in] linkArticulatedInertia is the articulated inertia of the link. + \param[in] jointMotionMatrices is an array of motion matrices with one entry per dof. + \param[in] jointIs is a cached term linkArticulatedInertia*jointDofMotionMatrix with one entry per dof. + \param[out] invStIs will be computed as 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[out] isInvD will be computed as linkArticulatedInertia*jointMotionMatrix^T/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \return A term to be translated to parent link and added to the articulated inertia of the parent. + */ + static SpatialMatrix computePropagateSpatialInertia( + const PxArticulationJointType::Enum jointType, const PxU8 nbDofs, + const SpatialMatrix& linkArticulatedInertia, const Cm::UnAlignedSpatialVector* jointMotionMatrices, + const Cm::SpatialVectorF* jointIs, + InvStIs& invStIs, Cm::SpatialVectorF* isInvD); static void transformInertia(const SpatialTransform& sTod, SpatialMatrix& inertia); @@ -972,12 +1104,60 @@ namespace Dy static PxMat33 translateInertia(const PxMat33& inertia, const PxReal mass, const PxVec3& t); - void computeArticulatedSpatialInertiaAndZ(ArticulationData& data, ScratchData& scratchData); + /* + \brief Propagate articulated spatial inertia and articulated z.a. spatial force from tip to root. + \param[in] links is an array of articulation links with size denoted by linkCount. + \param[in] linkCount is the number of articulation links. + \param[in] linkRsW is an array of link separations in the world frame with one entry per link. + \param[in] jointData is an array of joint descriptions with one entry per joint. + \param[in] jointTargetData is an array of joint armatures with one entry per joint. + \param[in] jointDofMotionMatricesW ins an array of motion matrices in the world frame with one entry per dof. + \param[in] linkCoriolisVectorsW is an array fo coriolis terms with one entry per link. + \param[in] jointForces is an array forces to be applied to joints with one entry per dof. + \param[out] jointDofIsW is a cached term linkArticulatedInertia*jointDofMotionMatrix to be computed with one entry per dof. + \param[out] linkInvStIsW will be computed as 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] with one entry per link. + \param[out] jointDofISInvStIS will be computed as linkArticulatedInertia*jointMotionMatrix^T/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] with one entry per dof. + \param[out] joIntDofMinusStZExtW will be computed as [-jointMotionMatrix^T * ZExt] with one entry per dof. + \param[out] jointDofQStZIntIcW will be computed as [jointForce - jointMotionMatrix^T *ZIntIc] with one entry per dof. + \param[in,out] linkZAExtForcsW is the articulated z.a spatial force of each link arising from external forces. + \param[in,out] linkZAIntForcesW is the articulated z.a spatial force of each link arising from internal forces. + \param[in,out] linkSpatialArticulatedInertiaW is the articulated spatial inertia of each link. + \param[out] baseInvSpatialArticulatedInertiaW is the inverse of the articulated spatial inertia of the root link. + */ + static void computeArticulatedSpatialInertiaAndZ + (const ArticulationLink* links, const PxU32 linkCount, const PxVec3* linkRsW, + const ArticulationJointCoreData* jointData, const ArticulationJointTargetData* jointTargetData, + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const Cm::SpatialVectorF* linkCoriolisVectorsW, const PxReal* jointDofForces, + Cm::SpatialVectorF* jointDofIsW, InvStIs* linkInvStIsW, Cm::SpatialVectorF* jointDofISInvStIS, PxReal* joIntDofMinusStZExtW, PxReal* jointDofQStZIntIcW, + Cm::SpatialVectorF* linkZAExtForcesW, Cm::SpatialVectorF* linkZAIntForcesW, SpatialMatrix* linkSpatialArticulatedInertiaW, + SpatialMatrix& baseInvSpatialArticulatedInertiaW); + void computeArticulatedSpatialInertiaAndZ_NonSeparated(ArticulationData& data, ScratchData& scratchData); void computeArticulatedSpatialInertia(ArticulationData& data); - void computeArticulatedResponseMatrix(ArticulationData& data); + /* + \brief Compute the response matrix of each link of an articulation. + \param[in] articulationFlags describes whether the articulation has a fixed base. + \param[in] linkCount is the number of links in the articulation. + \param[in] jointData is an array of joint descriptions with one entry per joint. + \param[in] baseInvSpatialArticulatedInertiaW is the inverse of the articulated spatial inertia of the root link. + \param[in] linkRsW is an array of link separations in the world frame with one entry per link. + \param[in] jointDofMotionMatricesW is an array of motion matrices with one entry per dof. + \param[in] jointDofISW is a cached term linkArticulatedInertia*jointDofMotionMatrix to be computed with one entry per dof. + \param[in] linkInvStISW will be computed as 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] with one entry per link. + \param[in] jointDofIsInvDW will be computed as linkArticulatedInertia*jointMotionMatrix^T/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] with one entry per dof. + \param[out] links is an array of articulation links with one entry per link. The cfm value of each link will be updated. + \param[out] linkResponsesW if an array of link responses with one entry per link. + */ + static void computeArticulatedResponseMatrix + (const PxArticulationFlags& articulationFlags, const PxU32 linkCount, + const ArticulationJointCoreData* jointData, + const SpatialMatrix& baseInvArticulatedInertiaW, + const PxVec3* linkRsW, const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const Cm::SpatialVectorF* jointDofISW, const InvStIs* linkInvStISW, const Cm::SpatialVectorF* jointDofIsInvDW, + ArticulationLink* links, SpatialImpulseResponseMatrix* linkResponsesW); void computeJointSpaceJacobians(ArticulationData& data); @@ -986,15 +1166,133 @@ namespace Dy /*void computeJointAcceleration(ArticulationLinkData& linkDatum, ArticulationJointCoreData& jointDatum, const Cm::SpatialVectorF& pMotionAcceleration, PxReal* jointAcceleration, const PxU32 linkID);*/ - void computeJointAccelerationW(ArticulationJointCoreData& jointDatum, - const Cm::SpatialVectorF& pMotionAcceleration, PxReal* jointAcceleration, const Cm::SpatialVectorF* IsW, const PxU32 linkID, - const PxReal* qstZIc); + /** + \brief Compute the joint acceleration + \note Reference maths found in Eq 4.27 of Mirtich thesis. + \param[in] pMotionAcceleration is the acceleration of the parent link already transformed into the (child) link frame. + \param[in] jointDofISW is an array of cached terms linkArticulatedInertia*jointDofMotionMatrix with one entry per dof. + \param[in] linkInvStISW is a cached term equivalent to 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] + \param[in] jointDofQStZIcW is an array of cached terms equivlaent to + [jointExternalForce - jointDofMotionMatrix^T * (zeroAccelSpatialForce + spatialInertia*coriolisForce] with one entry per dof. + \param[out] jointAcceleration is an array of output joint dof accelerations equivalent to Eq 4.27 in Mirtich thesis. + */ + static void computeJointAccelerationW(const PxU8 nbJointDofs, + const Cm::SpatialVectorF& pMotionAcceleration, const Cm::SpatialVectorF* jointDofISW, const InvStIs& linkInvStISW, + const PxReal* jointDofQStZIcW, PxReal* jointAcceleration); //compute joint acceleration, joint velocity and link acceleration, velocity based //on spatial force and spatial articulated inertia tensor - void computeLinkAcceleration(ArticulationData& data, ScratchData& scratchData, bool doIC); - void computeLinkInternalAcceleration(ArticulationData& data, ScratchData& scratchData); + /** + \brief Compute joint and link accelerations. + Accelerations are computed by iterating from root to tip using the formulae in Mirtich Figure 4.8 to compute first + the joint dof acceleration and then the link acceleration. + The accelerations are used to forward integrate the link and joint velocities. + This function may be used to determine either the effect of external forces only or the effect of the external and internal forces combined. + The function may not be used to determine the effect of internal forces. For internal forces only use computeLinkInternalAcceleration(). + If external forces only are to be considered then set doIC to false to avoid adding the Coriolis vector to the link acceleration. This is important + because Coriolis forces are accounted as part of the update arising from internal forces. + \param[in] doIC determines whether the link Coriolis force is added to the link acceleration. + Set to false if considering external forces only and true if considering the combination of internal and external forces. + \param[in] dt is the timestep used to accumulate joint/link velocities from joint/link accelerations. + \param[in] fixBase describes whether the root of the articulation is fixed or free to rotate and translate. + \param[in] links is an array of articulation links with one entry for each link. + \param[in] linkCount is the number of links in the articulation. + \param[in] jointDatas is an array of joint descriptions with one entry per joint. + \param[in] linkSpatialZAForcesW is an array of spatial z.a. forces arising from the forces acting on each link with one entry for each link. + linkSpatialZAForces will either be internal z.a forces or the sum of internal and external forces. + \param[in] linkCoriolisForcesW is an array of coriolis forces with one entry for each link. + \param[in] linkRsW is an array of link separations with one entry for each link. + \param[in] jointDofMotionMatricesW is an array of motion matrices with one entry per joint dof. + \param[in] baseInvSpatialArticulatedInertiaW is the inverse of the articulated spatial inertia of the root link. + \param[in] linkInvStISW is 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] with one entry per link. + \param[in] jointDofISW linkArticulatedInertia*jointMotionMatrix^T/ with one entry per joint dof. + \param[in] jointDofQStZIcW has one of two forms: + a) [-jointDofMotionMatrix^T * linkSpatialZAForceExternal] + b) [jointDofForce - jointDofMotionMatrix^T*(linkSpatialZAForceTotal + linkSpatialInertia*linkCoriolisForce)] + with one entry for each joint dof. + \param[out] linkMotionAccelerationsW is an array of link accelerations with one entry per link. The link accelerations are computed + using the formula in Figure 4.8 of the Mirtich thesis. + \param[in,out] linkMotionVelocitiesW is an array of link velocities that are forward integrated by dt using the link accelerations. + \param[out] jointDofAccelerations is an array of joint dof accelerations with one entry per link. The joint dof accelerations are computed + using the formula in Figure 4.8 of the Mirtich thesis. + \param[in,out] jointDofVelocities is an array of joint dof velocities that are forward integrated by dt using the joint dof accelerations. + \param[out] jointDofNewVelocities is another array of joint dof velocities that are forward integrated by dt using the joint dof accelerations. + \note If doIC is false then linkSpatialZAForces must be the external z.a. forces and jointDofQstZics must be [-jointDofMotionMatrix^T * linkSpatialZAForceExternal] + \note If doIC is true then linkSpatialZAForces must be the internal z.a. forces and jointDofQstZics must be [jointDofForce - jointDofMotionMatrix^T*(linkSpatialZAForceTotal + linkSpatialInertia*linkCoriolisForce)] + */ + static void computeLinkAcceleration + (const bool doIC, const PxReal dt, + const bool fixBase, + const ArticulationLink* links, const PxU32 linkCount, const ArticulationJointCoreData* jointDatas, + const Cm::SpatialVectorF* linkSpatialZAForcesW, const Cm::SpatialVectorF* linkCoriolisForcesW, const PxVec3* linkRsW, + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const SpatialMatrix& baseInvSpatialArticulatedInertiaW, + const InvStIs* linkInvStISW, + const Cm::SpatialVectorF* jointDofISW, const PxReal* jointDofQStZIcW, + Cm::SpatialVectorF* linkMotionAccelerationsW, Cm::SpatialVectorF* linkMotionVelocitiesW, + PxReal* jointDofAccelerations, PxReal* jointDofVelocities, PxReal* jointDofNewVelocities); + + /** + \brief Compute joint and link accelerations arising from internal z.a. forces. + Accelerations are computed by iterating from root to tip using the formulae in Mirtich Figure 4.8 to compute first + the joint dof acceleration and then the link acceleration. + The accelerations are used to forward integrate the link and joint velocities. + The resulting link velocities are rescaled if any link violates the maximum allowed linear or angular velocity. + \param[in] dt is the timestep used to accumulate joint/link velocities from joint/link accelerations. + \param[in] fixBase describes whether the root of the articulation is fixed or free to rotate and translate. + \param[in] comW is the centre of mass of the ensemble of links in the articulation. com is used only to enforce the max linear and angular velocity. + \param[in] invSumMass is the inverse of the mass sum of the ensemble of links in the articulation. invSumMass is used only to enforce the max linear and angular velocity. + \param[in] linkMaxLinearVelocity is the maximum allowed linear velocity of any link. The link linear velocities are rescaled to ensure none breaches the limit. + \param[in] linkMaxAngularVelocity is the maximum allowed angular velocity of any link. The link angular velocities are rescaled to ensure none breaches the limit. + \param[in] linkIsolatedSpatialArticulatedInertiasW is an array of link inertias. The link inertias are used only to enforce the max linear and angular velocity. + \param[in] baseInvSpatialArticulatedInertiaW is the inverse of the articulated spatial inertia of the root link. + \param[in] links is an array of articulation links with one entry for each link. + \param[in] linkCount is the number of links in the articulation. + \param[in] linkMasses is an array of link masses with one entry per link. + \param[in] linkRsW is an array of link separations with one entry per link. + \param[in] linkAccumulatedPosesW is an array of link poses with one entry per link. + \param[in] linkSpatialZAIntForcesW is an array of spatial z.a. forces arising from internal forces only with one netry per link. + \param[in] linkCoriolisVectorsW is an array of link Coriolis forces with one entry per link. + \param[in] jointDatas is an array of joint descriptions with one entry per joint. + \param[in] jointDofMotionMatricesW is an array of motion matrices with one entry per dof. + \param[in] linkInvStISW is 1/[jointMotionMatrix^T * linkArticulatedInertia * jointMotionMatrix] with one entry per link. + \param[in] jointDofISW linkArticulatedInertia*jointMotionMatrix^T with one entry per joint dof. + \param[in] jointDoQStZIntIcW has form: [jointDofForce - jointDofMotionMatrix^T*(linkSpatialZAForceInternal + linkSpatialInertia*linkCoriolisForce)] + with one entry for each joint dof. + \param[in,out] linkMotionAccelerationsW accumulates with the computed acceleration arising from internal forces. + \param[out] linkMotionAccelerationIntsW is the computed acceleration arising from internal forces. + \param[in,out] jointDofVelocities is an array of joint dof velocities that are forward integrated by dt using the joint dof accelerations arising from internal forces. + \param[out] jointDofNewVelocities is another array of joint dof velocities that are forward integrated by dt using the joint dof accelerations arising from internal forces. + \note computeLinkInternalAcceleration must be called after computeLinkAcceleration to allow the effect of internal forces to be accumulated on top of external forces. + */ + static void computeLinkInternalAcceleration + (const PxReal dt, + const bool fixBase, + const PxVec3& comW, const PxReal invSumMass, const PxReal linkMaxLinearVelocity, const PxReal linkMaxAngularVelocity, const PxMat33* linkIsolatedSpatialArticulatedInertiasW, + const SpatialMatrix& baseInvSpatialArticulatedInertiaW, + const ArticulationLink* links, const PxU32 linkCount, + const PxReal* linkMasses, const PxVec3* linkRsW, const PxTransform* linkAccumulatedPosesW, + const Cm::SpatialVectorF* linkSpatialZAIntForcesW, const Cm::SpatialVectorF* linkCoriolisVectorsW, + const ArticulationJointCoreData* jointDatas, const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const InvStIs* linkInvStISW, const Cm::SpatialVectorF* jointDofISW, const PxReal* jointDoQStZIntIcW, + Cm::SpatialVectorF* linkMotionAccelerationsW, Cm::SpatialVectorF* linkMotionAccelerationIntsW, Cm::SpatialVectorF* linkMotionVelocitiesW, + PxReal* jointDofAccelerations, PxReal* jointDofInternalAccelerations, PxReal* jointDofVelocities, PxReal* jointDofNewVelocities); + + /** + \brief For each link compute the incoming joint force in the joint frame. + \param[in] linkCount is the number of links in the articulation + \param[in] linkZAForcesExtW are the external spatial zero acceleration forces in the world frame with one entry per link. + \param[in] linkZAForcesIntW are the internal spatial zero acceleration forces in the world frame with one entry per link. + \param[in] linkMotionAccelerationsW are the spatial accelerations ion the world framewith one entry per link. + \param[in] linkSpatialInertiasW are the spatial articulated inertias in the world frame with one entry per link. + \param[out] linkIncomingJointForces are the incoming joint forces specified in the joint frame that are applied to each link. + */ + static void computeLinkIncomingJointForce( + const PxU32 linkCount, + const Cm::SpatialVectorF* linkZAForcesExtW, const Cm::SpatialVectorF* linkZAForcesIntW, + const Cm::SpatialVectorF* linkMotionAccelerationsW, const SpatialMatrix* linkSpatialInertiasW, + Cm::SpatialVectorF* linkIncomingJointForces); //void computeTempLinkAcceleration(ArticulationData& data, ScratchData& scratchData); void computeJointTransmittedFrictionForce(ArticulationData& data, ScratchData& scratchData, @@ -1004,9 +1302,6 @@ namespace Dy const ArticulationData& data, Cm::SpatialVectorF* Z, PxReal* jointVelocities); - static Cm::SpatialVectorF getDeltaV(const bool fixBase, const PxU32 linkID, - const ArticulationData& data, Cm::SpatialVectorF* Z); - //impulse need to be in the linkID space static void getZ(const PxU32 linkID, const ArticulationData& data, Cm::SpatialVectorF* Z, const Cm::SpatialVectorF& impulse); @@ -1237,9 +1532,6 @@ namespace Dy PxReal* jointVelocities, PxReal* jointAccelerations); - void recomputeAccelerations(const PxReal dt); - Cm::SpatialVector recomputeAcceleration(const PxU32 linkID, const PxReal dt) const; - void computeAndEnforceJointPositions(ArticulationData& data); //update link position based on joint position provided by the cache @@ -1280,7 +1572,6 @@ namespace Dy PxArray mStaticContactConstraints; PxArray mStatic1DConstraints; PxU32 mGPUDirtyFlags; - } PX_ALIGN_SUFFIX(64); @@ -1288,9 +1579,6 @@ namespace Dy #pragma warning(pop) #endif - void PxvRegisterArticulationsReducedCoordinate(); - - } //namespace Dy } diff --git a/physx/source/lowleveldynamics/include/DyHairSystem.h b/physx/source/lowleveldynamics/include/DyHairSystem.h index 601c6afba..57f2d5319 100644 --- a/physx/source/lowleveldynamics/include/DyHairSystem.h +++ b/physx/source/lowleveldynamics/include/DyHairSystem.h @@ -53,7 +53,7 @@ namespace physx eNONE = 0, //!> default, everything up-to-date ePARAMETERS = 1 << 0, //!> Parameters were changed eGRID_SIZE = 1 << 1 | ePARAMETERS, //!> Grid size was changed. sets ePARAMETERS because settings are stored there - eATTACHMENT = 1 << 2, //!> Attachment was changed + eRIGID_ATTACHMENTS = 1 << 2, //!> Rigid attachment was changed ePOSITIONS_VELOCITIES_MASS = 1 << 3, //!> Positions, velocities or masses changed eREST_POSITION_TRANSFORM = 1 << 4, //!> Transform of the rest positions changed eLOD_SWITCH = 1 << 5, //!> Level of detail was changed, update lodX pos/vel from lod0 @@ -66,8 +66,9 @@ namespace physx eNUM_STRANDS_OR_VERTS = 1 << 12 | eSHAPE_MATCHING_SIZES | ePOSITIONS_VELOCITIES_MASS | eBENDING_REST_ANGLES | eTWISTING_REST_POSITIONS | eREST_POSITIONS | eLOD_DATA | eSTRAND_LENGTHS, //!> Number of strands or vertices changed + eSOFTBODY_ATTACHMENTS = 1 << 13, //!> Softbody attachments added or removed - eALL = (1 << 13) - 1 //!> everything needs updating + eALL = (1 << 14) - 1 //!> everything needs updating }; }; diff --git a/physx/source/lowleveldynamics/include/DyHairSystemCore.h b/physx/source/lowleveldynamics/include/DyHairSystemCore.h index a2cea2d8f..65ce29c0e 100644 --- a/physx/source/lowleveldynamics/include/DyHairSystemCore.h +++ b/physx/source/lowleveldynamics/include/DyHairSystemCore.h @@ -27,101 +27,166 @@ #ifndef DY_HAIR_SYSTEM_CORE_H #define DY_HAIR_SYSTEM_CORE_H -#include "foundation/PxSimpleTypes.h" +#include "PxAttachment.h" +#include "PxHairSystemFlag.h" +#include "PxNodeIndex.h" #include "foundation/PxArray.h" -#include "foundation/PxVec4.h" +#include "foundation/PxSimpleTypes.h" #include "foundation/PxVec2.h" -#include "PxHairSystemFlag.h" -#include "PxAttachment.h" +#include "foundation/PxVec4.h" namespace physx { - struct PxsBodyCore; - namespace Dy +namespace Dy +{ +// These parameters are needed on GPU for simulation and are grouped in a struct +// to reduce the number of assignments in update user data. +struct HairSystemSimParameters +{ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getCellSize() const { return mSegmentLength + 2.0f * mSegmentRadius; } + PX_CUDA_CALLABLE PX_FORCE_INLINE int getGridSize() const { return mGridSize[0] * mGridSize[1] * mGridSize[2]; } + PxHairSystemFlags::InternalType mFlags; + PxReal mSegmentLength; + PxReal mSegmentRadius; + PxReal mInterHairRepulsion; // strength of the repulsion field + PxReal mInterHairVelocityDamping; // friction based on interpolated vel field + PxReal mFrictionCoeff; // coulomb friction coefficient for collisions (internal and external) + PxReal mBendingCompliance; + PxReal mTwistingCompliance; + int mGridSize[3]; // number of cells in x,y,z directions + PxVec2 mShapeCompliance; // compliance for shape matching + PxReal mSelfCollisionContactDist; // contact distance for self collisions expressed as a multiple of the segment + // radius + PxReal mSelfCollisionRelaxation; + PxReal mLraRelaxation; + PxReal mShapeMatchingCompliance; + PxReal mShapeMatchingBeta; // balance between rigid rotation and linear stretching + PxU16 mShapeMatchingNumVertsPerGroup; + PxU16 mShapeMatchingNumVertsOverlap; + + HairSystemSimParameters() + : mFlags(0) + , mSegmentLength(0.1f) + , mSegmentRadius(0.02f) + , mInterHairRepulsion(0.0f) + , mInterHairVelocityDamping(0.03f) + , mFrictionCoeff(0.0f) + , mBendingCompliance(-1.0f) + , mTwistingCompliance(-1.0f) + , mShapeCompliance(-1.0f) + , mSelfCollisionContactDist(1.5f) + , mSelfCollisionRelaxation(0.7f) + , mLraRelaxation(1.0f) + , mShapeMatchingCompliance(-1.0f) + , mShapeMatchingBeta(0.0f) + , mShapeMatchingNumVertsPerGroup(10) + , mShapeMatchingNumVertsOverlap(5) + { + // grid size must be powers of two + mGridSize[0] = 32; + mGridSize[1] = 64; + mGridSize[0] = 32; + } +}; + +PX_ALIGN_PREFIX(16) +struct SoftbodyHairAttachment +{ + PxVec4 tetBarycentric; // 16 16 // must be aligned, is being loaded as float4 + PxU32 tetId; // 4 20 + PxU32 softbodyNodeIdx; // 4 24 + PxU32 hairVtxIdx; // 4 28 + PxU32 padding; // 4 32 +} PX_ALIGN_SUFFIX(16); + +struct HairSystemCore +{ + public: + PxU32 mDirtyFlags; + PxHairSystemDataFlags mReadRequests; + + PxU32 mNumVertices; + PxU32 mNumStrands; + + // Parameters + HairSystemSimParameters mParams; + PxU16 mSolverIterationCounts; + PxVec4 mWind; + + // Topology data + const PxU32* mStrandPastEndIndices; + const PxReal* mBendingRestAngles; + + PxArray mMaterialhandles; + + // Buffers for simulation (device or pinned host mirrors) + PxVec4* mPositionInvMass; + PxVec4* mVelocity; + + // pointers to PxgHairSystemCore buffers that are exposed to the user + PxU32* mStrandPastEndIndicesGpuSim; + PxVec4* mPositionInvMassGpuSim; + PxReal* mTwistingRestPositionsGpuSim; + + // rest positions + PxVec4* mRestPositions; // Gpu buffer + PxTransform* mRestPositionsTransform; + PxU64 mRestPositionBodyNodeIdx; + + // Attachments to rigids + PxParticleRigidAttachment* mRigidAttachments; // Gpu buffer + PxU32 mNumRigidAttachments; + + // Attachments to softbodies + SoftbodyHairAttachment* mSoftbodyAttachments; + PxU32 mNumSoftbodyAttachments; + + // LOD data + PxU32 mLodLevel; // the selected level, zero by default meaning full detail + PxU32 mLodNumLevels; // number of levels excluding level zero + const PxReal* mLodProportionOfStrands; + const PxReal* mLodProportionOfVertices; + + // sleeping + PxReal mSleepThreshold; + PxReal mWakeCounter; + + void setMaterial(PxU16 materialhandle) { mMaterialhandles.pushBack(materialhandle); } + + void clearMaterials() { mMaterialhandles.clear(); } + + HairSystemCore() + : mDirtyFlags(PX_MAX_U32) + , mNumVertices(0) + , mNumStrands(0) + , mSolverIterationCounts(8) + , mWind(0.0f) + , mStrandPastEndIndices(NULL) + , mBendingRestAngles(NULL) + , mPositionInvMass(NULL) + , mVelocity(NULL) + , mStrandPastEndIndicesGpuSim(NULL) + , mPositionInvMassGpuSim(NULL) + , mTwistingRestPositionsGpuSim(NULL) + , mRestPositions(NULL) + , mRestPositionsTransform(NULL) + , mRestPositionBodyNodeIdx(PxNodeIndex().getInd()) + , mRigidAttachments(NULL) + , mNumRigidAttachments(0) + , mSoftbodyAttachments(NULL) + , mNumSoftbodyAttachments(0) + , mLodLevel(0) + , mLodNumLevels(0) + , mLodProportionOfStrands(NULL) + , mLodProportionOfVertices(NULL) + , mSleepThreshold(0.1f) + , mWakeCounter(1.0f) { - // These parameters are needed on GPU for simulation and are grouped in a struct - // to reduce the number of assignments in update user data. - struct HairSystemSimParameters - { - PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getCellSize() const { return mSegmentLength + 2.0f * mSegmentRadius; } - PX_CUDA_CALLABLE PX_FORCE_INLINE int getGridSize() const { return mGridSize[0] * mGridSize[1] * mGridSize[2]; } - PxHairSystemFlags::InternalType mFlags; - PxReal mSegmentLength; - PxReal mSegmentRadius; - PxReal mInterHairRepulsion; // strength of the repulsion field - PxReal mInterHairVelocityDamping; // friction based on interpolated vel field - PxReal mFrictionCoeff; // coulomb friction coefficient for collisions (internal and external) - PxReal mBendingCompliance; - PxReal mTwistingCompliance; - int mGridSize[3]; // number of cells in x,y,z directions - PxVec2 mShapeCompliance; // compliance for shape matching - PxReal mSelfCollisionContactDist; // contact distance for self collisions expressed as a multiple of the segment radius - PxReal mSelfCollisionRelaxation; - PxReal mLraRelaxation; - PxReal mShapeMatchingCompliance; - PxReal mShapeMatchingBeta; // balance between rigid rotation and linear stretching - PxU16 mShapeMatchingNumVertsPerGroup; - PxU16 mShapeMatchingNumVertsOverlap; - }; - - // The struct's defaults are defined in the Sc::HairSystemShapeCore constructor - struct HairSystemCore - { - public: - PxU32 mDirtyFlags; - PxHairSystemDataFlags mReadRequests; - - PxU32 mNumVertices; - PxU32 mNumStrands; - - // Parameters - HairSystemSimParameters mParams; - PxReal mSleepThreshold; - PxReal mWakeCounter; - PxU16 mSolverIterationCounts; - PxVec4 mWind; - - // Topology data - const PxU32* mStrandPastEndIndices; - const PxReal* mBendingRestAngles; - - PxArray mMaterialhandles; - - // Buffers for simulation (device or pinned host mirrors) - PxVec4* mPositionInvMass; - PxVec4* mVelocity; - - // pointers to PxgHairSystemCore buffers that are exposed to the user - PxU32* mStrandPastEndIndicesGpuSim; - PxVec4* mPositionInvMassGpuSim; - PxReal* mTwistingRestPositionsGpuSim; - - // rest positions - PxVec4* mRestPositions; // Gpu buffer - PxTransform* mRestPositionsTransform; - PxU64 mRestPositionBodyNodeIdx; - - // Attachments - PxParticleRigidAttachment* mRigidAttachments; // Gpu buffer - PxU32 mNumRigidAttachments; - - // LOD data - PxU32 mLodLevel; // the selected level, zero by default meaning full detail - PxU32 mLodNumLevels; // number of levels excluding level zero - const PxReal* mLodProportionOfStrands; - const PxReal* mLodProportionOfVertices; - - - void setMaterial(PxU16 materialhandle) - { - mMaterialhandles.pushBack(materialhandle); - } - - void clearMaterials() { mMaterialhandles.clear(); } - }; } -} +}; +} // namespace Dy +} // namespace physx #endif diff --git a/physx/source/lowleveldynamics/include/DyParticleSystemCore.h b/physx/source/lowleveldynamics/include/DyParticleSystemCore.h index c9a00b3be..2f32dab92 100644 --- a/physx/source/lowleveldynamics/include/DyParticleSystemCore.h +++ b/physx/source/lowleveldynamics/include/DyParticleSystemCore.h @@ -39,7 +39,6 @@ #include "PxMPMParticleSystem.h" #endif #include "PxParticleSolverType.h" -#include "PxCustomParticleSystemSolverCallback.h" #include "PxSparseGridParams.h" namespace physx @@ -66,11 +65,6 @@ class ParticleSystemCore PxU16 solverIterationCounts; PxSparseGridParams sparseGridParams; - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxFLIPParams flipParams; - PxMPMParams mpmParams; -#endif PxReal restOffset; PxReal particleContactOffset; @@ -84,8 +78,6 @@ class ParticleSystemCore PxReal maxDepenetrationVelocity; PxReal maxVelocity; - PxVec3 periodicBoundary; - PxParticleFlags mFlags; PxVec3 mWind; @@ -236,7 +228,6 @@ class ParticleSystemCore bool mParticleAndDiffuseBufferUpdate; PxParticleSystemCallback* mCallback; - PxCustomParticleSystemSolverCallback* mSolverCallback; ParticleSystemCore() { @@ -269,6 +260,13 @@ class ParticleSystemCore mParticleAndDiffuseBuffers[i]->onParticleSystemDestroy(); } } + +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + //Leave these members at the end to remain binary compatible with public builds + PxFLIPParams flipParams; + PxMPMParams mpmParams; +#endif + }; } // namespace Dy diff --git a/physx/source/lowleveldynamics/include/DySoftBody.h b/physx/source/lowleveldynamics/include/DySoftBody.h index 63ed917d9..d2d1b5886 100644 --- a/physx/source/lowleveldynamics/include/DySoftBody.h +++ b/physx/source/lowleveldynamics/include/DySoftBody.h @@ -120,9 +120,9 @@ namespace physx PX_FORCE_INLINE const SoftBodyCore& getCore() const { return mCore; } PX_FORCE_INLINE SoftBodyCore& getCore() { return mCore; } - PX_FORCE_INLINE PxU16 getIterationCounts() { return mCore.solverIterationCounts; } + PX_FORCE_INLINE PxU16 getIterationCounts() const { return mCore.solverIterationCounts; } - PX_FORCE_INLINE PxU32 getGpuSoftBodyIndex() { return mGpuRemapId; } + PX_FORCE_INLINE PxU32 getGpuSoftBodyIndex() const { return mGpuRemapId; } //These variables are used in the constraint partition PxU16 maxSolverFrictionProgress; diff --git a/physx/source/lowleveldynamics/include/DySoftBodyCore.h b/physx/source/lowleveldynamics/include/DySoftBodyCore.h index be4dbe0ba..74c59be1c 100644 --- a/physx/source/lowleveldynamics/include/DySoftBodyCore.h +++ b/physx/source/lowleveldynamics/include/DySoftBodyCore.h @@ -30,6 +30,7 @@ #include "foundation/PxSimpleTypes.h" #include "foundation/PxTransform.h" #include "PxSoftBody.h" +#include "PxSoftBodyFlag.h" #include "PxsFEMSoftBodyMaterialCore.h" #include "foundation/PxArray.h" @@ -50,6 +51,7 @@ namespace physx PxU16 solverIterationCounts; //vel iters are in low word and pos iters in high word. bool dirty; PxSoftBodyFlags mFlags; + PxSoftBodyDataFlags mDirtyFlags; void setMaterial(const PxU16 materialHandle) @@ -61,22 +63,14 @@ namespace physx PxArray mMaterialHandles; - //device - PxBuffer* mPositionInvMass; + //device - managed by PhysX + PxVec4* mPositionInvMass; // collision mesh positions, alloc on attachShape(), dealloc detachShape() + PxVec4* mRestPosition; // collision mesh rest positions, alloc on attachShape(), dealloc detachShape() + PxVec4* mSimPositionInvMass; // simulation mesh positions, alloc on attachSimulationMesh(), dealloc detachSimulationMesh() + PxVec4* mSimVelocity; // simulation mesh velocities, alloc on attachSimulationMesh(), dealloc detachSimulationMesh() - //host - PxBuffer* mPositionInvMassCPU; - PxBuffer* mRestPositionInvMassCPU; - - //device - PxBuffer* mSimPositionInvMass; - PxBuffer* mSimVelocityInvMass; - PxBuffer* mKinematicTarget; - - //host - PxBuffer* mSimPositionInvMassCPU; - PxBuffer* mSimVelocityInvMassCPU; - PxBuffer* mKinematicTargetCPU; + // device - just the pointer, user responsible. + const PxVec4* mKinematicTarget; }; } diff --git a/physx/source/lowleveldynamics/src/DyArticulationPImpl.h b/physx/source/lowleveldynamics/src/DyArticulationPImpl.h index 4213f5662..2b5d59156 100644 --- a/physx/source/lowleveldynamics/src/DyArticulationPImpl.h +++ b/physx/source/lowleveldynamics/src/DyArticulationPImpl.h @@ -30,6 +30,7 @@ #define DY_ARTICULATION_INTERFACE_H #include "DyArticulationUtils.h" +#include "DyFeatherstoneArticulation.h" namespace physx { @@ -41,47 +42,6 @@ class ArticulationPImpl { public: - typedef PxU32 (*ComputeUnconstrainedVelocitiesFn)(const ArticulationSolverDesc& desc, - PxReal dt, - PxU32& acCount, - const PxVec3& gravity, - Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV, - const PxReal invLengthScale); - - typedef void (*UpdateBodiesFn)(const ArticulationSolverDesc& desc, Cm::SpatialVectorF* deltaV, PxReal dt); - - typedef void (*SaveVelocityFn)(const ArticulationSolverDesc &m, Cm::SpatialVectorF* deltaV); - - typedef void(*SaveVelocityTGSFn)(const ArticulationSolverDesc& m, PxReal invDtF32); - - typedef PxU32(*SetupInternalConstraintsTGSFn)(const ArticulationSolverDesc& desc, - PxReal dt, - PxReal invDt, - PxReal totalDt, - const PxReal biasCoefficient, - PxU32& acCount, - Cm::SpatialVectorF* Z); - - typedef void(*ComputeUnconstrainedVelocitiesTGSFn)(const ArticulationSolverDesc& desc, - PxReal dt, - const PxVec3& gravity, PxU64 contextID, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV, - const PxReal invLengthScale); - - typedef void(*UpdateDeltaMotionFn)(const ArticulationSolverDesc &m, const PxReal dt, Cm::SpatialVectorF* DeltaV, const PxReal totalInvDt); - - typedef void(*DeltaMotionToMotionVelFn)(const ArticulationSolverDesc &m, const PxReal dt); - - static ComputeUnconstrainedVelocitiesFn sComputeUnconstrainedVelocities; - static UpdateBodiesFn sUpdateBodies; - static UpdateBodiesFn sUpdateBodiesTGS; - static SaveVelocityFn sSaveVelocity; - static SaveVelocityTGSFn sSaveVelocityTGS; - - static UpdateDeltaMotionFn sUpdateDeltaMotion; - static DeltaMotionToMotionVelFn sDeltaMotionToMotionVel; - static ComputeUnconstrainedVelocitiesTGSFn sComputeUnconstrainedVelocitiesTGS; - static SetupInternalConstraintsTGSFn sSetupInternalConstraintsTGS; - static PxU32 computeUnconstrainedVelocities(const ArticulationSolverDesc& desc, PxReal dt, PxU32& acCount, @@ -90,45 +50,29 @@ class ArticulationPImpl Cm::SpatialVectorF* deltaV, const PxReal invLengthScale) { - PX_ASSERT(sComputeUnconstrainedVelocities); - if (sComputeUnconstrainedVelocities) - return (sComputeUnconstrainedVelocities)(desc, dt, acCount, - gravity, Z, deltaV, invLengthScale); - else - return 0; + return FeatherstoneArticulation::computeUnconstrainedVelocities(desc, dt, acCount, gravity, Z, deltaV, invLengthScale); } static void updateBodies(const ArticulationSolverDesc& desc, Cm::SpatialVectorF* tempDeltaV, PxReal dt) { - PX_ASSERT(sUpdateBodies); - if (sUpdateBodies) - (*sUpdateBodies)(desc, tempDeltaV, dt); + FeatherstoneArticulation::updateBodies(desc, tempDeltaV, dt); } static void updateBodiesTGS(const ArticulationSolverDesc& desc, Cm::SpatialVectorF* tempDeltaV, PxReal dt) { - PX_ASSERT(sUpdateBodiesTGS); - if (sUpdateBodiesTGS) - (*sUpdateBodiesTGS)(desc, tempDeltaV, dt); + FeatherstoneArticulation::updateBodiesTGS(desc, tempDeltaV, dt); } - static void saveVelocity(const ArticulationSolverDesc& desc, Cm::SpatialVectorF* tempDeltaV) + static void saveVelocity(FeatherstoneArticulation* articulation, Cm::SpatialVectorF* tempDeltaV) { - PX_ASSERT(sSaveVelocity); - if (sSaveVelocity) - (*sSaveVelocity)(desc, tempDeltaV); + FeatherstoneArticulation::saveVelocity(articulation, tempDeltaV); } - - static void saveVelocityTGS(const ArticulationSolverDesc& desc, PxReal invDtF32) + static void saveVelocityTGS(FeatherstoneArticulation* articulation, PxReal invDtF32) { - PX_UNUSED(desc); - PX_UNUSED(invDtF32); - PX_ASSERT(sSaveVelocityTGS); - if (sSaveVelocityTGS) - (*sSaveVelocityTGS)(desc, invDtF32); + FeatherstoneArticulation::saveVelocityTGS(articulation, invDtF32); } static void computeUnconstrainedVelocitiesTGS(const ArticulationSolverDesc& desc, @@ -136,23 +80,17 @@ class ArticulationPImpl const PxVec3& gravity, PxU64 contextID, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV, const PxReal invLengthScale) { - PX_ASSERT(sComputeUnconstrainedVelocitiesTGS); - if (sComputeUnconstrainedVelocitiesTGS) - (sComputeUnconstrainedVelocitiesTGS)(desc, dt, gravity, contextID, Z, DeltaV, invLengthScale); + FeatherstoneArticulation::computeUnconstrainedVelocitiesTGS(desc, dt, gravity, contextID, Z, DeltaV, invLengthScale); } static void updateDeltaMotion(const ArticulationSolverDesc& desc, const PxReal dt, Cm::SpatialVectorF* DeltaV, const PxReal totalInvDt) { - PX_ASSERT(sUpdateDeltaMotion); - if (sUpdateDeltaMotion) - (*sUpdateDeltaMotion)(desc, dt, DeltaV, totalInvDt); + FeatherstoneArticulation::recordDeltaMotion(desc, dt, DeltaV, totalInvDt); } static void deltaMotionToMotionVel(const ArticulationSolverDesc& desc, const PxReal invDt) { - PX_ASSERT(sDeltaMotionToMotionVel); - if (sDeltaMotionToMotionVel) - (*sDeltaMotionToMotionVel)(desc, invDt); + FeatherstoneArticulation::deltaMotionToMotionVelocity(desc, invDt); } static PxU32 setupSolverInternalConstraintsTGS(const ArticulationSolverDesc& desc, @@ -163,12 +101,7 @@ class ArticulationPImpl PxU32& acCount, Cm::SpatialVectorF* Z) { - PX_ASSERT(sSetupInternalConstraintsTGS); - if (sSetupInternalConstraintsTGS) - return sSetupInternalConstraintsTGS(desc, dt, invDt, - totalDt, biasCoefficient, acCount, Z); - return 0; - + return FeatherstoneArticulation::setupSolverConstraintsTGS(desc, dt, invDt, totalDt, biasCoefficient, acCount, Z); } }; diff --git a/physx/source/lowleveldynamics/src/DyArticulationUtils.h b/physx/source/lowleveldynamics/src/DyArticulationUtils.h index 66db78f24..9720a7b8d 100644 --- a/physx/source/lowleveldynamics/src/DyArticulationUtils.h +++ b/physx/source/lowleveldynamics/src/DyArticulationUtils.h @@ -32,7 +32,6 @@ #include "foundation/PxBitUtils.h" #include "foundation/PxVecMath.h" #include "CmSpatialVector.h" -#include "DySpatial.h" #include "DyVArticulation.h" namespace physx diff --git a/physx/source/lowleveldynamics/src/DyBodyCoreIntegrator.h b/physx/source/lowleveldynamics/src/DyBodyCoreIntegrator.h index a128a79bd..feb3f5174 100644 --- a/physx/source/lowleveldynamics/src/DyBodyCoreIntegrator.h +++ b/physx/source/lowleveldynamics/src/DyBodyCoreIntegrator.h @@ -30,23 +30,17 @@ #define DY_BODYCORE_INTEGRATOR_H #include "PxvDynamics.h" -#include "PxsRigidBody.h" #include "DySolverBody.h" -#include "DySleepingConfigulation.h" -#include "PxsIslandSim.h" namespace physx { - namespace Dy { - PX_FORCE_INLINE void bodyCoreComputeUnconstrainedVelocity -(const PxVec3& gravity, const PxReal dt, const PxReal linearDamping, const PxReal angularDamping, const PxReal accelScale, -const PxReal maxLinearVelocitySq, const PxReal maxAngularVelocitySq, PxVec3& inOutLinearVelocity, PxVec3& inOutAngularVelocity, -bool disableGravity) + (const PxVec3& gravity, PxReal dt, PxReal linearDamping, PxReal angularDamping, PxReal accelScale, + PxReal maxLinearVelocitySq, PxReal maxAngularVelocitySq, PxVec3& inOutLinearVelocity, PxVec3& inOutAngularVelocity, + bool disableGravity) { - //Multiply everything that needs multiplied by dt to improve code generation. PxVec3 linearVelocity = inOutLinearVelocity; @@ -58,7 +52,7 @@ bool disableGravity) const PxReal oneMinusAngularDampingTimesDT=1.0f-angularDampingTimesDT; //TODO context-global gravity - if (!disableGravity) + if(!disableGravity) { const PxVec3 linearAccelTimesDT = gravity*dt *accelScale; linearVelocity += linearAccelTimesDT; @@ -86,9 +80,8 @@ bool disableGravity) inOutAngularVelocity = angularVelocity; } - PX_FORCE_INLINE void integrateCore(PxVec3& motionLinearVelocity, PxVec3& motionAngularVelocity, - PxSolverBody& solverBody, PxSolverBodyData& solverBodyData, const PxF32 dt, const PxU32 lockFlags) + PxSolverBody& solverBody, PxSolverBodyData& solverBodyData, PxF32 dt, PxU32 lockFlags) { if (lockFlags) { @@ -96,16 +89,19 @@ PX_FORCE_INLINE void integrateCore(PxVec3& motionLinearVelocity, PxVec3& motionA { motionLinearVelocity.x = 0.f; solverBody.linearVelocity.x = 0.f; + solverBodyData.linearVelocity.x = 0.f; } if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_Y) { motionLinearVelocity.y = 0.f; solverBody.linearVelocity.y = 0.f; + solverBodyData.linearVelocity.y = 0.f; } if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_Z) { motionLinearVelocity.z = 0.f; solverBody.linearVelocity.z = 0.f; + solverBodyData.linearVelocity.z = 0.f; } //The angular velocity should be 0 because it is now impossible to make it rotate around that axis! @@ -127,8 +123,8 @@ PX_FORCE_INLINE void integrateCore(PxVec3& motionLinearVelocity, PxVec3& motionA } // Integrate linear part - PxVec3 linearMotionVel = solverBodyData.linearVelocity + motionLinearVelocity; - PxVec3 delta = linearMotionVel * dt; + const PxVec3 linearMotionVel = solverBodyData.linearVelocity + motionLinearVelocity; + const PxVec3 delta = linearMotionVel * dt; PxVec3 angularMotionVel = solverBodyData.angularVelocity + solverBodyData.sqrtInvInertia * motionAngularVelocity; PxReal w = angularMotionVel.magnitudeSquared(); solverBodyData.body2World.p += delta; @@ -171,220 +167,7 @@ PX_FORCE_INLINE void integrateCore(PxVec3& motionLinearVelocity, PxVec3& motionA motionLinearVelocity = linearMotionVel; motionAngularVelocity = angularMotionVel; } - - -// PT: TODO: why do we force-inline this? -PX_FORCE_INLINE PxReal _updateWakeCounter(PxsRigidBody* originalBody, PxReal dt, PxReal /*invDt*/, const bool enableStabilization, const Cm::SpatialVector& motionVelocity, - bool hasStaticTouch) -{ - PxsBodyCore& bodyCore = originalBody->getCore(); - - // update the body's sleep state and - PxReal wakeCounterResetTime = 20.0f*0.02f; - - PxReal wc = bodyCore.wakeCounter; - - { - if (enableStabilization) - { - bool freeze = false; - const PxTransform& body2World = bodyCore.body2World; - - // calculate normalized energy: kinetic energy divided by mass - - const PxVec3& t = bodyCore.inverseInertia; - const PxVec3 inertia(t.x > 0.f ? 1.0f / t.x : 1.f, t.y > 0.f ? 1.0f / t.y : 1.f, t.z > 0.f ? 1.0f / t.z : 1.f); - - const PxVec3& sleepLinVelAcc = motionVelocity.linear; - const PxVec3 sleepAngVelAcc = body2World.q.rotateInv(motionVelocity.angular); - - // scale threshold by cluster factor (more contacts => higher sleep threshold) - //const PxReal clusterFactor = PxReal(1u + getNumUniqueInteractions()); - - PxReal invMass = bodyCore.inverseMass; - if (invMass == 0.f) - invMass = 1.f; - - const PxReal angular = sleepAngVelAcc.multiply(sleepAngVelAcc).dot(inertia) * invMass; - const PxReal linear = sleepLinVelAcc.magnitudeSquared(); - const PxReal frameNormalizedEnergy = 0.5f * (angular + linear); - - const PxReal cf = hasStaticTouch ? PxReal(PxMin(10u, bodyCore.numCountedInteractions)) : 0.f; - const PxReal freezeThresh = cf*bodyCore.freezeThreshold; - - originalBody->freezeCount = PxMax(originalBody->freezeCount - dt, 0.0f); - bool settled = true; - - PxReal accelScale = PxMin(1.f, originalBody->accelScale + dt); - - if (frameNormalizedEnergy >= freezeThresh) - { - settled = false; - originalBody->freezeCount = PXD_FREEZE_INTERVAL; - } - - if (!hasStaticTouch) - { - accelScale = 1.f; - settled = false; - } - - - if (settled) - { - //Dampen bodies that are just about to go to sleep - if (cf > 1.f) - { - const PxReal sleepDamping = PXD_SLEEP_DAMPING; - const PxReal sleepDampingTimesDT = sleepDamping*dt; - const PxReal d = 1.0f - sleepDampingTimesDT; - bodyCore.linearVelocity = bodyCore.linearVelocity * d; - bodyCore.angularVelocity = bodyCore.angularVelocity * d; - accelScale = accelScale * 0.75f + 0.25f*PXD_FREEZE_SCALE; - } - freeze = originalBody->freezeCount == 0.f && frameNormalizedEnergy < (bodyCore.freezeThreshold * PXD_FREEZE_TOLERANCE); - } - - originalBody->accelScale = accelScale; - - const PxU32 wasFrozen = originalBody->mInternalFlags & PxsRigidBody::eFROZEN; - PxU16 flags; - if(freeze) - { - //current flag isn't frozen but freeze flag raise so we need to raise the frozen flag in this frame - flags = PxU16(PxsRigidBody::eFROZEN); - if(!wasFrozen) - flags |= PxsRigidBody::eFREEZE_THIS_FRAME; - bodyCore.body2World = originalBody->getLastCCDTransform(); - } - else - { - flags = 0; - if(wasFrozen) - flags |= PxsRigidBody::eUNFREEZE_THIS_FRAME; - } - originalBody->mInternalFlags = flags; - - /*KS: New algorithm for sleeping when using stabilization: - * Energy *this frame* must be higher than sleep threshold and accumulated energy over previous frames - * must be higher than clusterFactor*energyThreshold. - */ - if (wc < wakeCounterResetTime * 0.5f || wc < dt) - { - //Accumulate energy - originalBody->sleepLinVelAcc += sleepLinVelAcc; - originalBody->sleepAngVelAcc += sleepAngVelAcc; - - //If energy this frame is high - if (frameNormalizedEnergy >= bodyCore.sleepThreshold) - { - //Compute energy over sleep preparation time - const PxReal sleepAngular = originalBody->sleepAngVelAcc.multiply(originalBody->sleepAngVelAcc).dot(inertia) * invMass; - const PxReal sleepLinear = originalBody->sleepLinVelAcc.magnitudeSquared(); - const PxReal normalizedEnergy = 0.5f * (sleepAngular + sleepLinear); - const PxReal sleepClusterFactor = PxReal(1u + bodyCore.numCountedInteractions); - // scale threshold by cluster factor (more contacts => higher sleep threshold) - const PxReal threshold = sleepClusterFactor*bodyCore.sleepThreshold; - - //If energy over sleep preparation time is high - if (normalizedEnergy >= threshold) - { - //Wake up - //PX_ASSERT(isActive()); - originalBody->sleepAngVelAcc = PxVec3(0); - originalBody->sleepLinVelAcc = PxVec3(0); - - const float factor = bodyCore.sleepThreshold == 0.f ? 2.0f : PxMin(normalizedEnergy / threshold, 2.0f); - PxReal oldWc = wc; - wc = factor * 0.5f * wakeCounterResetTime + dt * (sleepClusterFactor - 1.0f); - bodyCore.solverWakeCounter = wc; - //if (oldWc == 0.0f) // for the case where a sleeping body got activated by the system (not the user) AND got processed by the solver as well - // notifyNotReadyForSleeping(bodyCore.nodeIndex); - - if (oldWc == 0.0f) - originalBody->mInternalFlags |= PxsRigidBody::eACTIVATE_THIS_FRAME; - - return wc; - } - } - } - - } - else - { - if (wc < wakeCounterResetTime * 0.5f || wc < dt) - { - const PxTransform& body2World = bodyCore.body2World; - - // calculate normalized energy: kinetic energy divided by mass - const PxVec3& t = bodyCore.inverseInertia; - const PxVec3 inertia(t.x > 0.f ? 1.0f / t.x : 1.f, t.y > 0.f ? 1.0f / t.y : 1.f, t.z > 0.f ? 1.0f / t.z : 1.f); - - const PxVec3& sleepLinVelAcc = motionVelocity.linear; - const PxVec3 sleepAngVelAcc = body2World.q.rotateInv(motionVelocity.angular); - - originalBody->sleepLinVelAcc += sleepLinVelAcc; - originalBody->sleepAngVelAcc += sleepAngVelAcc; - - PxReal invMass = bodyCore.inverseMass; - if (invMass == 0.f) - invMass = 1.f; - - const PxReal angular = originalBody->sleepAngVelAcc.multiply(originalBody->sleepAngVelAcc).dot(inertia) * invMass; - const PxReal linear = originalBody->sleepLinVelAcc.magnitudeSquared(); - const PxReal normalizedEnergy = 0.5f * (angular + linear); - - // scale threshold by cluster factor (more contacts => higher sleep threshold) - const PxReal clusterFactor = PxReal(1 + bodyCore.numCountedInteractions); - const PxReal threshold = clusterFactor*bodyCore.sleepThreshold; - - if (normalizedEnergy >= threshold) - { - //PX_ASSERT(isActive()); - originalBody->sleepLinVelAcc = PxVec3(0); - originalBody->sleepAngVelAcc = PxVec3(0); - const float factor = threshold == 0.f ? 2.0f : PxMin(normalizedEnergy / threshold, 2.0f); - PxReal oldWc = wc; - wc = factor * 0.5f * wakeCounterResetTime + dt * (clusterFactor - 1.0f); - bodyCore.solverWakeCounter = wc; - PxU16 flags = 0; - if (oldWc == 0.0f) // for the case where a sleeping body got activated by the system (not the user) AND got processed by the solver as well - { - flags |= PxsRigidBody::eACTIVATE_THIS_FRAME; - //notifyNotReadyForSleeping(bodyCore.nodeIndex); - } - - originalBody->mInternalFlags = flags; - - return wc; - } - } - } - } - - wc = PxMax(wc - dt, 0.0f); - bodyCore.solverWakeCounter = wc; - return wc; -} - -PX_FORCE_INLINE void sleepCheck(PxsRigidBody* originalBody, const PxReal dt, const PxReal intDt, const bool enableStabilization, const Cm::SpatialVector& motionVelocity, - bool hasStaticTouch) -{ - const PxReal wc = _updateWakeCounter(originalBody, dt, intDt, enableStabilization, motionVelocity, hasStaticTouch); - const bool wakeCounterZero = (wc == 0.0f); - - if (wakeCounterZero) - { - //PxsBodyCore& bodyCore = originalBody->getCore(); - originalBody->mInternalFlags |= PxsRigidBody::eDEACTIVATE_THIS_FRAME; - // notifyReadyForSleeping(bodyCore.nodeIndex); - originalBody->sleepLinVelAcc = PxVec3(0); - originalBody->sleepAngVelAcc = PxVec3(0); - } } - -} - } #endif diff --git a/physx/source/lowleveldynamics/src/DyConstraintPartition.cpp b/physx/source/lowleveldynamics/src/DyConstraintPartition.cpp index ed77fdc5a..7251cb1dc 100644 --- a/physx/source/lowleveldynamics/src/DyConstraintPartition.cpp +++ b/physx/source/lowleveldynamics/src/DyConstraintPartition.cpp @@ -36,92 +36,27 @@ namespace physx { namespace Dy { - namespace { - -#define MAX_NUM_PARTITIONS 32 - - -class RigidBodyClassification +class RigidBodyClassification : public RigidBodyClassificationBase { - PxU8* PX_RESTRICT mBodies; - PxU32 mBodySize; - PxU32 mBodyStride; - PxU32 mBodyCount; - public: - RigidBodyClassification(PxU8* PX_RESTRICT bodies, PxU32 bodyCount, PxU32 bodyStride) : mBodies(bodies), mBodySize(bodyCount*bodyStride), mBodyStride(bodyStride), - mBodyCount(bodyCount) - { - } - - //Returns true if it is a dynamic-dynamic constraint; false if it is a dynamic-static or dynamic-kinematic constraint - PX_FORCE_INLINE bool classifyConstraint(const PxSolverConstraintDesc& desc, uintptr_t& indexA, uintptr_t& indexB, - bool& activeA, bool& activeB, PxU32& bodyAProgress, PxU32& bodyBProgress) const + RigidBodyClassification(PxU8* bodies, PxU32 bodyCount, PxU32 bodyStride) : RigidBodyClassificationBase(bodies, bodyCount, bodyStride) { - indexA=uintptr_t(reinterpret_cast(desc.bodyA) - mBodies)/mBodyStride; - indexB=uintptr_t(reinterpret_cast(desc.bodyB) - mBodies)/mBodyStride; - activeA = indexA < mBodyCount; - activeB = indexB < mBodyCount; - bodyAProgress = desc.bodyA->solverProgress; - bodyBProgress = desc.bodyB->solverProgress; - return activeA && activeB; } - PX_FORCE_INLINE void getProgress(const PxSolverConstraintDesc& desc, - PxU32& bodyAProgress, PxU32& bodyBProgress) +/* PX_FORCE_INLINE void getProgress(const PxSolverConstraintDesc& desc, PxU32& bodyAProgress, PxU32& bodyBProgress) const { bodyAProgress = desc.bodyA->solverProgress; bodyBProgress = desc.bodyB->solverProgress; - } - - PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, const PxU32 bodyAProgress, const PxU32 bodyBProgress, - const PxU16 availablePartition) - { - desc.bodyA->solverProgress = bodyAProgress; - desc.bodyA->maxSolverNormalProgress = PxMax(desc.bodyA->maxSolverNormalProgress, availablePartition); - desc.bodyB->solverProgress = bodyBProgress; - desc.bodyB->maxSolverNormalProgress = PxMax(desc.bodyB->maxSolverNormalProgress, availablePartition); - } - - PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, const PxU32 bodyAProgress, const PxU32 bodyBProgress) - { - desc.bodyA->solverProgress = bodyAProgress; - desc.bodyB->solverProgress = bodyBProgress; - } - - PX_FORCE_INLINE PxU32 getStaticContactWriteIndex(const PxSolverConstraintDesc& desc, - bool activeA, bool activeB) - { - if (activeA) - return PxU32(desc.bodyA->maxSolverNormalProgress + desc.bodyA->maxSolverFrictionProgress++); - else if (activeB) - return PxU32(desc.bodyB->maxSolverNormalProgress + desc.bodyB->maxSolverFrictionProgress++); - - return 0xffffffff; - - } - - PX_FORCE_INLINE void recordStaticConstraint(const PxSolverConstraintDesc& desc, bool activeA, bool activeB) const - { - if (activeA) - { - desc.bodyA->maxSolverFrictionProgress++; - } - - if (activeB) - { - desc.bodyB->maxSolverFrictionProgress++; - } - } + }*/ PX_FORCE_INLINE void getProgressRequirements(const PxSolverConstraintDesc& desc, PxU32& progressA, PxU32& progressB) const { - uintptr_t indexA = uintptr_t(reinterpret_cast(desc.bodyA) - mBodies) / mBodyStride; - uintptr_t indexB = uintptr_t(reinterpret_cast(desc.bodyB) - mBodies) / mBodyStride; - bool activeA = indexA < mBodyCount; - bool activeB = indexB < mBodyCount; + const uintptr_t indexA = uintptr_t(reinterpret_cast(desc.bodyA) - mBodies) / mBodyStride; + const uintptr_t indexB = uintptr_t(reinterpret_cast(desc.bodyB) - mBodies) / mBodyStride; + const bool activeA = indexA < mBodyCount; + const bool activeB = indexB < mBodyCount; if (activeA) progressA = desc.bodyA->maxSolverFrictionProgress++; @@ -160,29 +95,22 @@ class RigidBodyClassification } }; -class ExtendedRigidBodyClassification +class ExtendedRigidBodyClassification : public ExtendedRigidBodyClassificationBase { - PxU8* PX_RESTRICT mBodies; - PxU32 mBodyCount; - PxU32 mBodySize; - PxU32 mStride; - Dy::FeatherstoneArticulation** PX_RESTRICT mArticulations; - PxU32 mNumArticulations; - bool mForceStaticCollisionsToSolver; + const bool mForceStaticCollisionsToSolver; // PT: why is this one not present in the immediate mode version? public: - ExtendedRigidBodyClassification(PxU8* PX_RESTRICT bodies, PxU32 numBodies, PxU32 stride, Dy::FeatherstoneArticulation** articulations, PxU32 numArticulations, - bool forceStaticCollisionsToSolver) - : mBodies(bodies), mBodyCount(numBodies), mBodySize(numBodies*stride), mStride(stride), mArticulations(articulations), mNumArticulations(numArticulations), - mForceStaticCollisionsToSolver(forceStaticCollisionsToSolver) + ExtendedRigidBodyClassification(PxU8* bodies, PxU32 numBodies, PxU32 stride, Dy::FeatherstoneArticulation** articulations, PxU32 numArticulations, bool forceStaticCollisionsToSolver) : + ExtendedRigidBodyClassificationBase (bodies, numBodies, stride, articulations, numArticulations), + mForceStaticCollisionsToSolver (forceStaticCollisionsToSolver) { + // PT: why is this loop not present in the immediate mode version? for (PxU32 i = 0; i < mNumArticulations; ++i) - { mArticulations[i]->mArticulationIndex = PxTo16(i); - } } + // PT: this version is slightly different from the immediate mode version, see mArticulationIndex! //Returns true if it is a dynamic-dynamic constraint; false if it is a dynamic-static or dynamic-kinematic constraint PX_FORCE_INLINE bool classifyConstraint(const PxSolverConstraintDesc& desc, uintptr_t& indexA, uintptr_t& indexB, bool& activeA, bool& activeB, PxU32& bodyAProgress, PxU32& bodyBProgress) const @@ -197,7 +125,6 @@ class ExtendedRigidBodyClassification } else { - FeatherstoneArticulation* articulationA = getArticulationA(desc); indexA=mBodyCount+ articulationA->mArticulationIndex; //bodyAProgress = articulationA->getFsDataPtr()->solverProgress; @@ -222,7 +149,7 @@ class ExtendedRigidBodyClassification return !hasStatic; } - PX_FORCE_INLINE void getProgress(const PxSolverConstraintDesc& desc, +/* PX_FORCE_INLINE void getProgress(const PxSolverConstraintDesc& desc, PxU32& bodyAProgress, PxU32& bodyBProgress) const { if (desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY) @@ -244,11 +171,9 @@ class ExtendedRigidBodyClassification FeatherstoneArticulation* articulationB = getArticulationB(desc); bodyBProgress = articulationB->solverProgress; } - } - + }*/ - PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, const PxU32 bodyAProgress, const PxU32 bodyBProgress, - const PxU16 availablePartition) + PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, PxU32 bodyAProgress, PxU32 bodyBProgress, PxU16 availablePartition) { if (desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY) { @@ -275,8 +200,7 @@ class ExtendedRigidBodyClassification } } - PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, const PxU32 bodyAProgress, - const PxU32 bodyBProgress) + PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, PxU32 bodyAProgress, PxU32 bodyBProgress) { if (desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY) { @@ -362,8 +286,7 @@ class ExtendedRigidBodyClassification } } - PX_FORCE_INLINE PxU32 getStaticContactWriteIndex(const PxSolverConstraintDesc& desc, - bool activeA, bool activeB) + PX_FORCE_INLINE PxU32 getStaticContactWriteIndex(const PxSolverConstraintDesc& desc, bool activeA, bool activeB) const { if (activeA) { @@ -450,9 +373,9 @@ class ExtendedRigidBodyClassification }; template -PxU32 classifyConstraintDesc(const PxSolverConstraintDesc* PX_RESTRICT descs, const PxU32 numConstraints, Classification& classification, +static PxU32 classifyConstraintDesc(const PxSolverConstraintDesc* PX_RESTRICT descs, PxU32 numConstraints, Classification& classification, PxArray& numConstraintsPerPartition, PxSolverConstraintDesc* PX_RESTRICT eaTempConstraintDescriptors, - const PxU32 maxPartitions) + PxU32 maxPartitions) { const PxSolverConstraintDesc* _desc = descs; const PxU32 numConstraintsMin1 = numConstraints - 1; @@ -574,9 +497,9 @@ PxU32 classifyConstraintDesc(const PxSolverConstraintDesc* PX_RESTRICT descs, co } template -PxU32 writeConstraintDesc(const PxSolverConstraintDesc* PX_RESTRICT descs, const PxU32 numConstraints, Classification& classification, - PxArray& accumulatedConstraintsPerPartition, PxSolverConstraintDesc* eaTempConstraintDescriptors, - PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDesc, PxU32 maxPartitions, const PxU32 numOverflows) +static PxU32 writeConstraintDesc( const PxSolverConstraintDesc* PX_RESTRICT descs, PxU32 numConstraints, Classification& classification, + PxArray& accumulatedConstraintsPerPartition, PxSolverConstraintDesc* eaTempConstraintDescriptors, + PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDesc, PxU32 maxPartitions, PxU32 numOverflows) { PX_UNUSED(eaTempConstraintDescriptors); const PxSolverConstraintDesc* _desc = descs; @@ -693,14 +616,12 @@ PxU32 writeConstraintDesc(const PxSolverConstraintDesc* PX_RESTRICT descs, const return numStaticConstraints; } - -void outputOverflowConstraints( - PxArray& accumulatedConstraintsPerPartition, PxSolverConstraintDesc* overflowConstraints, const PxU32 nbOverflowConstraints, +static void outputOverflowConstraints( + PxArray& accumulatedConstraintsPerPartition, PxSolverConstraintDesc* overflowConstraints, PxU32 nbOverflowConstraints, PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDesc) { //Firstly, we resize and shuffle accumulatedConstraintsPerPartition - accumulatedConstraintsPerPartition.resize(accumulatedConstraintsPerPartition.size()+1); PxU32 partitionCount = accumulatedConstraintsPerPartition.size(); @@ -724,9 +645,10 @@ void outputOverflowConstraints( #if PX_NORMALIZE_PARTITIONS +#ifdef REMOVED_UNUSED template PxU32 normalizePartitions(PxArray& accumulatedConstraintsPerPartition, PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDescriptors, - const PxU32 numConstraintDescriptors, PxArray& bitField, const Classification& classification, const PxU32 numBodies, const PxU32 numArticulations) + PxU32 numConstraintDescriptors, PxArray& bitField, const Classification& classification, PxU32 numBodies, PxU32 numArticulations) { PxU32 numPartitions = 0; @@ -845,6 +767,7 @@ PxU32 normalizePartitions(PxArray& accumulatedConstraintsPerPartition, Px return partitionCount; } +#endif #endif @@ -852,14 +775,14 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) { PxU32 maxPartition = 0; //Unpack the input data. - const PxU32 numBodies=args.mNumBodies; - const PxU32 numArticulations=args.mNumArticulationPtrs; + const PxU32 numBodies = args.mNumBodies; + const PxU32 numArticulations = args.mNumArticulationPtrs; - const PxU32 numConstraintDescriptors=args.mNumContactConstraintDescriptors; + const PxU32 numConstraintDescriptors = args.mNumContactConstraintDescriptors; - PxSolverConstraintDesc* PX_RESTRICT eaConstraintDescriptors=args.mContactConstraintDescriptors; - PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDescriptors=args.mOrderedContactConstraintDescriptors; - PxSolverConstraintDesc* PX_RESTRICT eaOverflowConstraintDescriptors=args.mOverflowConstraintDescriptors; + const PxSolverConstraintDesc* PX_RESTRICT eaConstraintDescriptors = args.mContactConstraintDescriptors; + PxSolverConstraintDesc* PX_RESTRICT eaOrderedConstraintDescriptors = args.mOrderedContactConstraintDescriptors; + PxSolverConstraintDesc* PX_RESTRICT eaOverflowConstraintDescriptors = args.mOverflowConstraintDescriptors; PxArray& constraintsPerPartition = *args.mConstraintsPerPartition; constraintsPerPartition.forceSize_Unsafe(0); @@ -885,7 +808,7 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) { RigidBodyClassification classification(args.mBodies, numBodies, stride); numOverflows = classifyConstraintDesc(eaConstraintDescriptors, numConstraintDescriptors, classification, constraintsPerPartition, - eaOverflowConstraintDescriptors, args.maxPartitions); + eaOverflowConstraintDescriptors, args.mMaxPartitions); PxU32 accumulation = 0; for(PxU32 a = 0; a < constraintsPerPartition.size(); ++a) @@ -907,7 +830,7 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) } writeConstraintDesc(eaConstraintDescriptors, numConstraintDescriptors, classification, constraintsPerPartition, - eaOverflowConstraintDescriptors, eaOrderedConstraintDescriptors, args.maxPartitions, numOverflows); + eaOverflowConstraintDescriptors, eaOrderedConstraintDescriptors, args.mMaxPartitions, numOverflows); numOrderedConstraints = numConstraintDescriptors; @@ -917,11 +840,9 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) outputOverflowConstraints(constraintsPerPartition, eaOverflowConstraintDescriptors, numOverflows, eaOrderedConstraintDescriptors); } - } else { - const ArticulationSolverDesc* articulationDescs=args.mArticulationPtrs; PX_ALLOCA(_eaArticulations, Dy::FeatherstoneArticulation*, numArticulations); Dy::FeatherstoneArticulation** eaArticulations = _eaArticulations; @@ -934,10 +855,10 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) articulation->maxSolverNormalProgress = 0; } ExtendedRigidBodyClassification classification(args.mBodies, numBodies, stride, eaArticulations, numArticulations, - args.forceStaticConstraintsToSolver); + args.mForceStaticConstraintsToSolver); numOverflows = classifyConstraintDesc(eaConstraintDescriptors, numConstraintDescriptors, classification, - constraintsPerPartition, eaOverflowConstraintDescriptors, args.maxPartitions); + constraintsPerPartition, eaOverflowConstraintDescriptors, args.mMaxPartitions); PxU32 accumulation = 0; for(PxU32 a = 0; a < constraintsPerPartition.size(); ++a) @@ -965,7 +886,7 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) } numStaticConstraints = writeConstraintDesc(eaConstraintDescriptors, numConstraintDescriptors, classification, constraintsPerPartition, - eaOverflowConstraintDescriptors, eaOrderedConstraintDescriptors, args.maxPartitions, numOverflows); + eaOverflowConstraintDescriptors, eaOrderedConstraintDescriptors, args.mMaxPartitions, numOverflows); numOrderedConstraints = numConstraintDescriptors - numStaticConstraints; @@ -974,7 +895,6 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) outputOverflowConstraints(constraintsPerPartition, eaOverflowConstraintDescriptors, numOverflows, eaOrderedConstraintDescriptors); } - } const PxU32 numConstraintsDifferentBodies=numOrderedConstraints; @@ -1006,7 +926,7 @@ PxU32 partitionContactConstraints(ConstraintPartitionArgs& args) } void processOverflowConstraints(PxU8* bodies, PxU32 bodyStride, PxU32 numBodies, Dy::ArticulationSolverDesc* articulationDescs, PxU32 numArticulations, - PxSolverConstraintDesc* constraints, const PxU32 numConstraints) + PxSolverConstraintDesc* constraints, PxU32 numConstraints) { for (PxU32 a = 0, offset = 0; a < numBodies; ++a, offset += bodyStride) { @@ -1045,8 +965,7 @@ void processOverflowConstraints(PxU8* bodies, PxU32 bodyStride, PxU32 numBodies, //articulation->maxSolverNormalProgress = 0; } - ExtendedRigidBodyClassification classification(bodies, numBodies, bodyStride, eaArticulations, numArticulations, - false); + ExtendedRigidBodyClassification classification(bodies, numBodies, bodyStride, eaArticulations, numArticulations, false); for (PxU32 i = 0; i < numConstraints; ++i) { diff --git a/physx/source/lowleveldynamics/src/DyConstraintPartition.h b/physx/source/lowleveldynamics/src/DyConstraintPartition.h index 12f21889e..c0dfcd61a 100644 --- a/physx/source/lowleveldynamics/src/DyConstraintPartition.h +++ b/physx/source/lowleveldynamics/src/DyConstraintPartition.h @@ -31,44 +31,133 @@ #include "DyDynamics.h" - namespace physx { - namespace Dy { -struct ConstraintPartitionArgs +#define MAX_NUM_PARTITIONS 32u + +// PT: introduced base classes to start sharing code between the SDK's and the immediate mode's versions. + +class RigidBodyClassificationBase +{ + PX_NOCOPY(RigidBodyClassificationBase) + + PxU8* const mBodies; + const PxU32 mBodySize; + const PxU32 mBodyStride; + const PxU32 mBodyCount; + +public: + RigidBodyClassificationBase(PxU8* bodies, PxU32 bodyCount, PxU32 bodyStride) : + mBodies (bodies), + mBodySize (bodyCount*bodyStride), + mBodyStride (bodyStride), + mBodyCount (bodyCount) + { + } + + //Returns true if it is a dynamic-dynamic constraint; false if it is a dynamic-static or dynamic-kinematic constraint + PX_FORCE_INLINE bool classifyConstraint(const PxSolverConstraintDesc& desc, uintptr_t& indexA, uintptr_t& indexB, + bool& activeA, bool& activeB, PxU32& bodyAProgress, PxU32& bodyBProgress) const + { + indexA = uintptr_t(reinterpret_cast(desc.bodyA) - mBodies) / mBodyStride; + indexB = uintptr_t(reinterpret_cast(desc.bodyB) - mBodies) / mBodyStride; + activeA = indexA < mBodyCount; + activeB = indexB < mBodyCount; + bodyAProgress = desc.bodyA->solverProgress; + bodyBProgress = desc.bodyB->solverProgress; + return activeA && activeB; + } + + PX_FORCE_INLINE PxU32 getStaticContactWriteIndex(const PxSolverConstraintDesc& desc, bool activeA, bool activeB) const + { + if(activeA) + return PxU32(desc.bodyA->maxSolverNormalProgress + desc.bodyA->maxSolverFrictionProgress++); + else if(activeB) + return PxU32(desc.bodyB->maxSolverNormalProgress + desc.bodyB->maxSolverFrictionProgress++); + + return 0xffffffff; + } + + PX_FORCE_INLINE void recordStaticConstraint(const PxSolverConstraintDesc& desc, bool activeA, bool activeB) const + { + if(activeA) + desc.bodyA->maxSolverFrictionProgress++; + + if(activeB) + desc.bodyB->maxSolverFrictionProgress++; + } + + PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, PxU32 bodyAProgress, PxU32 bodyBProgress) + { + desc.bodyA->solverProgress = bodyAProgress; + desc.bodyB->solverProgress = bodyBProgress; + } + + PX_FORCE_INLINE void storeProgress(const PxSolverConstraintDesc& desc, PxU32 bodyAProgress, PxU32 bodyBProgress, PxU16 availablePartition) + { + desc.bodyA->solverProgress = bodyAProgress; + desc.bodyA->maxSolverNormalProgress = PxMax(desc.bodyA->maxSolverNormalProgress, availablePartition); + desc.bodyB->solverProgress = bodyBProgress; + desc.bodyB->maxSolverNormalProgress = PxMax(desc.bodyB->maxSolverNormalProgress, availablePartition); + } +}; + +class ExtendedRigidBodyClassificationBase { + PX_NOCOPY(ExtendedRigidBodyClassificationBase) + PxU8* const mBodies; + const PxU32 mBodyCount; + const PxU32 mBodySize; + const PxU32 mStride; + Dy::FeatherstoneArticulation** mArticulations; + const PxU32 mNumArticulations; + +public: + + ExtendedRigidBodyClassificationBase(PxU8* bodies, PxU32 numBodies, PxU32 stride, Dy::FeatherstoneArticulation** articulations, PxU32 numArticulations) : + mBodies (bodies), + mBodyCount (numBodies), + mBodySize (numBodies*stride), + mStride (stride), + mArticulations (articulations), + mNumArticulations (numArticulations) + { + } +}; + +struct ConstraintPartitionArgs +{ //Input - PxU8* mBodies; - PxU32 mNumBodies; - PxU32 mStride; - ArticulationSolverDesc* mArticulationPtrs; - PxU32 mNumArticulationPtrs; - PxSolverConstraintDesc* mContactConstraintDescriptors; - PxU32 mNumContactConstraintDescriptors; + PxU8* mBodies; + PxU32 mNumBodies; + PxU32 mStride; + const ArticulationSolverDesc* mArticulationPtrs; + PxU32 mNumArticulationPtrs; + const PxSolverConstraintDesc* mContactConstraintDescriptors; + PxU32 mNumContactConstraintDescriptors; //output - PxSolverConstraintDesc* mOrderedContactConstraintDescriptors; - PxSolverConstraintDesc* mOverflowConstraintDescriptors; - PxU32 mNumDifferentBodyConstraints; - PxU32 mNumSelfConstraints; - PxU32 mNumStaticConstraints; - PxU32 mNumOverflowConstraints; - PxArray* mConstraintsPerPartition; - PxArray* mBitField; - - PxU32 maxPartitions; - - bool enhancedDeterminism; - bool forceStaticConstraintsToSolver; - + PxSolverConstraintDesc* mOrderedContactConstraintDescriptors; + PxSolverConstraintDesc* mOverflowConstraintDescriptors; + PxU32 mNumDifferentBodyConstraints; + PxU32 mNumSelfConstraints; + PxU32 mNumStaticConstraints; + PxU32 mNumOverflowConstraints; + PxArray* mConstraintsPerPartition; + //PxArray* mBitField; // PT: removed, unused + + PxU32 mMaxPartitions; + + bool mEnhancedDeterminism; + bool mForceStaticConstraintsToSolver; }; PxU32 partitionContactConstraints(ConstraintPartitionArgs& args); void processOverflowConstraints(PxU8* bodies, PxU32 bodyStride, PxU32 numBodies, ArticulationSolverDesc* articulations, PxU32 numArticulations, - PxSolverConstraintDesc* constraints, const PxU32 numConstraints); + PxSolverConstraintDesc* constraints, PxU32 numConstraints); } // namespace physx diff --git a/physx/source/lowleveldynamics/src/DyConstraintSetup.cpp b/physx/source/lowleveldynamics/src/DyConstraintSetup.cpp index 395f2d5e1..da81f9844 100644 --- a/physx/source/lowleveldynamics/src/DyConstraintSetup.cpp +++ b/physx/source/lowleveldynamics/src/DyConstraintSetup.cpp @@ -35,6 +35,7 @@ #include "DySolverConstraintDesc.h" #include "PxcConstraintBlockStream.h" #include "DyArticulationContactPrep.h" +#include "foundation/PxSIMDHelpers.h" namespace physx { @@ -117,7 +118,7 @@ PxQuat diagonalize(const PxMat33& m) // jacobi rotation using quaternions PxMat33 d; for(PxU32 i=0; i < MAX_ITERS;i++) { - const PxMat33 axes(q); + const PxMat33Padded axes(q); d = axes.getTranspose() * m * axes; const PxReal d0 = PxAbs(d[1][2]), d1 = PxAbs(d[0][2]), d2 = PxAbs(d[0][1]); diff --git a/physx/source/lowleveldynamics/src/DyConstraintSetupBlock.cpp b/physx/source/lowleveldynamics/src/DyConstraintSetupBlock.cpp index b01d9bcf6..544b8c6d0 100644 --- a/physx/source/lowleveldynamics/src/DyConstraintSetupBlock.cpp +++ b/physx/source/lowleveldynamics/src/DyConstraintSetupBlock.cpp @@ -36,7 +36,6 @@ #include "DyArticulationContactPrep.h" namespace physx { - namespace Dy { @@ -220,7 +219,6 @@ PxConstraintAllocator& allocator, PxU32 maxRows) const Vec4V invMassScale1 = V4LoadXYZW(constraintDescs[0].invMassScales.linear1, constraintDescs[1].invMassScales.linear1, constraintDescs[2].invMassScales.linear1, constraintDescs[3].invMassScales.linear1); - const Vec4V iMass0 = V4LoadXYZW(bd00.invMass, bd01.invMass, bd02.invMass, bd03.invMass); const Vec4V iMass1 = V4LoadXYZW(bd10.invMass, bd11.invMass, bd12.invMass, bd13.invMass); @@ -228,7 +226,6 @@ PxConstraintAllocator& allocator, PxU32 maxRows) const Vec4V invMass0 = V4Mul(iMass0, invMassScale0); const Vec4V invMass1 = V4Mul(iMass1, invMassScale1); - const Vec4V invInertiaScale0 = V4LoadXYZW(constraintDescs[0].invMassScales.angular0, constraintDescs[1].invMassScales.angular0, constraintDescs[2].invMassScales.angular0, constraintDescs[3].invMassScales.angular0); const Vec4V invInertiaScale1 = V4LoadXYZW(constraintDescs[0].invMassScales.angular1, constraintDescs[1].invMassScales.angular1, @@ -255,20 +252,16 @@ PxConstraintAllocator& allocator, PxU32 maxRows) Vec4V angVel30 = V4LoadA(&bd03.angularVelocity.x); Vec4V angVel31 = V4LoadA(&bd13.angularVelocity.x); - Vec4V linVel0T0, linVel0T1, linVel0T2; Vec4V linVel1T0, linVel1T1, linVel1T2; Vec4V angVel0T0, angVel0T1, angVel0T2; Vec4V angVel1T0, angVel1T1, angVel1T2; - PX_TRANSPOSE_44_34(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2); PX_TRANSPOSE_44_34(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2); PX_TRANSPOSE_44_34(angVel00, angVel10, angVel20, angVel30, angVel0T0, angVel0T1, angVel0T2); PX_TRANSPOSE_44_34(angVel01, angVel11, angVel21, angVel31, angVel1T0, angVel1T1, angVel1T2); - - //body world offsets Vec4V workOffset0 = Vec4V_From_Vec3V(V3LoadU(constraintDescs[0].body0WorldOffset)); Vec4V workOffset1 = Vec4V_From_Vec3V(V3LoadU(constraintDescs[1].body0WorldOffset)); @@ -280,18 +273,16 @@ PxConstraintAllocator& allocator, PxU32 maxRows) PX_TRANSPOSE_44_34(workOffset0, workOffset1, workOffset2, workOffset3, workOffsetX, workOffsetY, workOffsetZ); const FloatV dtV = FLoad(dt); - Vec4V linBreakForce = V4LoadXYZW(constraintDescs[0].linBreakForce, constraintDescs[1].linBreakForce, + const Vec4V linBreakForce = V4LoadXYZW(constraintDescs[0].linBreakForce, constraintDescs[1].linBreakForce, constraintDescs[2].linBreakForce, constraintDescs[3].linBreakForce); - Vec4V angBreakForce = V4LoadXYZW(constraintDescs[0].angBreakForce, constraintDescs[1].angBreakForce, + const Vec4V angBreakForce = V4LoadXYZW(constraintDescs[0].angBreakForce, constraintDescs[1].angBreakForce, constraintDescs[2].angBreakForce, constraintDescs[3].angBreakForce); - header->break0 = PxU8((constraintDescs[0].linBreakForce != PX_MAX_F32) || (constraintDescs[0].angBreakForce != PX_MAX_F32)); header->break1 = PxU8((constraintDescs[1].linBreakForce != PX_MAX_F32) || (constraintDescs[1].angBreakForce != PX_MAX_F32)); header->break2 = PxU8((constraintDescs[2].linBreakForce != PX_MAX_F32) || (constraintDescs[2].angBreakForce != PX_MAX_F32)); header->break3 = PxU8((constraintDescs[3].linBreakForce != PX_MAX_F32) || (constraintDescs[3].angBreakForce != PX_MAX_F32)); - //OK, I think that's everything loaded in header->invMass0D0 = invMass0; @@ -359,7 +350,6 @@ PxConstraintAllocator& allocator, PxU32 maxRows) if (con3->flags&Px1DConstraintFlag::eHAS_DRIVE_LIMIT && constraintDescs[3].driveLimitsAreForces) driveScale = V4SetW(driveScale, FMin(one, dtV)); - Vec4V clin00 = V4LoadA(&con0->linear0.x); Vec4V clin01 = V4LoadA(&con1->linear0.x); Vec4V clin02 = V4LoadA(&con2->linear0.x); @@ -463,7 +453,6 @@ PxConstraintAllocator& allocator, PxU32 maxRows) const Vec4V normalVel = V4Sub(projectVel0, projectVel1); - { const PxVec4& ur = reinterpret_cast(unitResponse); PxVec4& cConstant = reinterpret_cast(c->constant); diff --git a/physx/source/lowleveldynamics/src/DyContactPrep.cpp b/physx/source/lowleveldynamics/src/DyContactPrep.cpp index eff20bdb0..558ebb252 100644 --- a/physx/source/lowleveldynamics/src/DyContactPrep.cpp +++ b/physx/source/lowleveldynamics/src/DyContactPrep.cpp @@ -53,8 +53,6 @@ PxcCreateFinalizeSolverContactMethod createFinalizeMethods[3] = createFinalizeSolverContactsCoulomb2D }; - - static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteraction, const PxContactPoint* buffer, const CorrelationBuffer& c, @@ -104,7 +102,6 @@ static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteractio const FloatV invMass0_dom0fV = FMul(d0, invMass0); const FloatV invMass1_dom1fV = FMul(nDom1fV, invMass1); - Vec4V staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W = V4Zero(); staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W=V4SetZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, invMass0_dom0fV); staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W=V4SetW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, invMass1_dom1fV); @@ -150,7 +147,6 @@ static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteractio const FloatV invDtp8 = FMul(invDt, p8); const FloatV dt = FLoad(dtF32); - for(PxU32 i=0;i(ptr); ptr += sizeof(SolverContactHeader); - PxPrefetchLine(ptr, 128); PxPrefetchLine(ptr, 256); @@ -268,8 +262,7 @@ static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteractio const Vec3V t1 = V3Cross(norCross, t0Cross); const VecCrossV t1Cross = V3PrepareCross(t1); - - + // since we don't even have the body velocities we can't compute the tangent dirs, so // the only thing we can do right now is to write the geometric information (which is the // same for both axis constraints of an anchor) We put ra in the raXn field, rb in the rbXn @@ -322,7 +315,6 @@ static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteractio const Vec3V raXnSqrtInertia = M33MulV3(invSqrtInertia0, raXn); const Vec3V rbXnSqrtInertia = M33MulV3(invSqrtInertia1, rbXn); - const FloatV resp0 = FAdd(invMass0_dom0fV, FMul(angD0, V3Dot(raXnSqrtInertia, raXnSqrtInertia))); const FloatV resp1 = FSub(FMul(angD1, V3Dot(rbXnSqrtInertia, rbXnSqrtInertia)), invMass1_dom1fV); const FloatV resp = FAdd(resp0, resp1); @@ -344,7 +336,6 @@ static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteractio } { - Vec3V raXn = V3Cross(ra, t1Cross); Vec3V rbXn = V3Cross(rb, t1Cross); @@ -380,7 +371,6 @@ static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteractio } } - PX_FORCE_INLINE void computeBlockStreamByteSizes(const bool useExtContacts, const CorrelationBuffer& c, PxU32& _solverConstraintByteSize, PxU32& _frictionPatchByteSize, PxU32& _numFrictionPatches, PxU32& _axisConstraintCount) @@ -395,7 +385,6 @@ PX_FORCE_INLINE void computeBlockStreamByteSizes(const bool useExtContacts, cons PxU32 numFrictionPatches = 0; PxU32 axisConstraintCount = 0; - for(PxU32 i = 0; i < c.frictionPatchCount; i++) { //Friction patches. @@ -421,7 +410,6 @@ PX_FORCE_INLINE void computeBlockStreamByteSizes(const bool useExtContacts, cons solverConstraintByteSize += useExtContacts ? c.frictionPatches[i].anchorCount * 2 * sizeof(SolverContactFrictionExt) : c.frictionPatches[i].anchorCount * 2 * sizeof(SolverContactFriction); axisConstraintCount += c.frictionPatches[i].anchorCount * 2; - } } } @@ -432,7 +420,7 @@ PX_FORCE_INLINE void computeBlockStreamByteSizes(const bool useExtContacts, cons //16-byte alignment. _frictionPatchByteSize = ((frictionPatchByteSize + 0x0f) & ~0x0f); - _solverConstraintByteSize = ((solverConstraintByteSize + 0x0f) & ~0x0f); + _solverConstraintByteSize = ((solverConstraintByteSize + 0x0f) & ~0x0f); PX_ASSERT(0 == (_solverConstraintByteSize & 0x0f)); PX_ASSERT(0 == (_frictionPatchByteSize & 0x0f)); } @@ -525,7 +513,6 @@ static bool reserveBlockStreams(const bool useExtContacts, Dy::CorrelationBuffer return ((0==constraintBlockByteSize || constraintBlock) && (0==frictionPatchByteSize || frictionPatches)); } - bool createFinalizeSolverContacts( PxSolverContactDesc& contactDesc, CorrelationBuffer& c, @@ -556,7 +543,6 @@ bool createFinalizeSolverContacts( desc.constraintLengthOver16 = 0; - if (contactDesc.numContacts == 0) { contactDesc.frictionPtr = NULL; @@ -576,10 +562,7 @@ bool createFinalizeSolverContacts( #if PX_CHECKED if (overflow) - { - PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, - "Dropping contacts in solver because we exceeded limit of 32 friction patches."); - } + PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL, "Dropping contacts in solver because we exceeded limit of 32 friction patches."); #endif growPatches(c, contactDesc.contacts, contactDesc.bodyFrame0, contactDesc.bodyFrame1, 0, frictionOffsetThreshold + contactDesc.restDistance); @@ -718,9 +701,7 @@ FloatV setupExtSolverContact(const SolverExtBody& b0, const SolverExtBody& b1, const BoolV isGreater2 = BAnd(BAnd(FIsGrtr(restitution, zero), FIsGrtr(bounceThreshold, vrel)), FIsGrtr(FNeg(vrel), penetrationInvDt)); - - - FloatV velMultiplier, scaledBias, impulseMultiplier; + FloatV velMultiplier, impulseMultiplier; FloatV biasedErr, unbiasedErr; const FloatV tVel = FSel(isGreater2, FMul(FNeg(vrel), restitution), zero); @@ -743,8 +724,8 @@ FloatV setupExtSolverContact(const SolverExtBody& b0, const SolverExtBody& b1, const FloatV x = FRecip(FScaleAdd(a, unitResponse, FOne())); velMultiplier = FMul(x, a); - //scaledBias = FSel(isSeparated, FNeg(invStepDt), FDiv(FMul(nrdt, FMul(x, unitResponse)), velMultiplier)); - scaledBias = FMul(x, b); + //FloatV scaledBias = FSel(isSeparated, FNeg(invStepDt), FDiv(FMul(nrdt, FMul(x, unitResponse)), velMultiplier)); + const FloatV scaledBias = FMul(x, b); impulseMultiplier = FSub(FOne(), x); unbiasedErr = biasedErr = FScaleAdd(targetVelocity, velMultiplier, FNeg(scaledBias)); @@ -752,19 +733,17 @@ FloatV setupExtSolverContact(const SolverExtBody& b0, const SolverExtBody& b1, else { const BoolV ccdSeparationCondition = FIsGrtrOrEq(ccdMaxSeparation, penetration); - velMultiplier = FSel(FIsGrtr(FLoad(DY_ARTICULATION_MIN_RESPONSE), unitResponse), zero, FRecip(FAdd(unitResponse, cfm))); - scaledBias = FMul(velMultiplier, FMax(maxPenBias, FMul(penetration, invDtp8))); + velMultiplier = FSel(FIsGrtr(unitResponse, FZero()), FRecip(FAdd(unitResponse, cfm)), zero); + FloatV scaledBias = FMul(velMultiplier, FMax(maxPenBias, FMul(penetration, invDtp8))); scaledBias = FSel(BAnd(ccdSeparationCondition, isGreater2), zero, scaledBias); biasedErr = FScaleAdd(targetVelocity, velMultiplier, FNeg(scaledBias)); unbiasedErr = FScaleAdd(targetVelocity, velMultiplier, FSel(isGreater2, zero, FNeg(FMax(scaledBias, zero)))); impulseMultiplier = FOne(); - } const FloatV deltaF = FMax(FMul(FSub(tVel, FAdd(vrel, FMax(penetrationInvDt, zero))), velMultiplier), zero); - FStore(biasedErr, &solverContact.biasedErr); FStore(unbiasedErr, &solverContact.unbiasedErr); @@ -779,7 +758,6 @@ FloatV setupExtSolverContact(const SolverExtBody& b0, const SolverExtBody& b1, return deltaF; } - bool createFinalizeSolverContacts(PxSolverContactDesc& contactDesc, PxsContactManagerOutput& output, ThreadContext& threadContext, diff --git a/physx/source/lowleveldynamics/src/DyContactPrep4.cpp b/physx/source/lowleveldynamics/src/DyContactPrep4.cpp index acddb7206..a5099b6f1 100644 --- a/physx/source/lowleveldynamics/src/DyContactPrep4.cpp +++ b/physx/source/lowleveldynamics/src/DyContactPrep4.cpp @@ -60,11 +60,10 @@ inline bool ValidateVec4(const Vec4V v) } static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT descs, CorrelationBuffer& c, PxU8* PX_RESTRICT workspace, - const PxReal invDtF32, const PxReal dtF32, PxReal bounceThresholdF32, + PxReal invDtF32, PxReal dtF32, PxReal bounceThresholdF32, const aos::Vec4VArg invMassScale0, const aos::Vec4VArg invInertiaScale0, const aos::Vec4VArg invMassScale1, const aos::Vec4VArg invInertiaScale1) { - //OK, we have a workspace of pre-allocated space to store all 4 descs in. We now need to create the constraints in it const Vec4V ccdMaxSeparation = aos::V4LoadXYZW(descs[0].maxCCDSeparation, descs[1].maxCCDSeparation, descs[2].maxCCDSeparation, descs[3].maxCCDSeparation); @@ -74,10 +73,10 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const BoolV bFalse = BFFFF(); const FloatV fZero = FZero(); - PxU8 flags[4] = { PxU8(descs[0].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), - PxU8(descs[1].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), - PxU8(descs[2].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), - PxU8(descs[3].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0) }; + const PxU8 flags[4] = { PxU8(descs[0].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), + PxU8(descs[1].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), + PxU8(descs[2].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), + PxU8(descs[3].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0) }; bool hasMaxImpulse = descs[0].hasMaxImpulse || descs[1].hasMaxImpulse || descs[2].hasMaxImpulse || descs[3].hasMaxImpulse; @@ -109,7 +108,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V restDistance = V4LoadXYZW(descs[0].restDistance, descs[1].restDistance, descs[2].restDistance, descs[3].restDistance); - //load up velocities Vec4V linVel00 = V4LoadA(&descs[0].data0->linearVelocity.x); Vec4V linVel10 = V4LoadA(&descs[1].data0->linearVelocity.x); @@ -207,7 +205,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des PX_TRANSPOSE_44_34(invInertia01Y, invInertia11Y, invInertia21Y, invInertia31Y, invInertia1X1, invInertia1Y1, invInertia1Z1); PX_TRANSPOSE_44_34(invInertia01Z, invInertia11Z, invInertia21Z, invInertia31Z, invInertia1X2, invInertia1Y2, invInertia1Z2); - const FloatV invDt = FLoad(invDtF32); const FloatV dt = FLoad(dtF32); const FloatV p8 = FLoad(0.8f); @@ -228,7 +225,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des Vec4V bodyFrame0pX, bodyFrame0pY, bodyFrame0pZ; PX_TRANSPOSE_44_34(bodyFrame00p4, bodyFrame01p4, bodyFrame02p4, bodyFrame03p4, bodyFrame0pX, bodyFrame0pY, bodyFrame0pZ); - const Vec3V bodyFrame10p = V3LoadU(descs[0].bodyFrame1.p); const Vec3V bodyFrame11p = V3LoadU(descs[1].bodyFrame1.p); @@ -243,7 +239,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des Vec4V bodyFrame1pX, bodyFrame1pY, bodyFrame1pZ; PX_TRANSPOSE_44_34(bodyFrame10p4, bodyFrame11p4, bodyFrame12p4, bodyFrame13p4, bodyFrame1pX, bodyFrame1pY, bodyFrame1pZ); - const QuatV bodyFrame00q = QuatVLoadU(&descs[0].bodyFrame0.q.x); const QuatV bodyFrame01q = QuatVLoadU(&descs[1].bodyFrame0.q.x); const QuatV bodyFrame02q = QuatVLoadU(&descs[2].bodyFrame0.q.x); @@ -265,7 +260,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des PxU32 frictionIndex0 = 0, frictionIndex1 = 0, frictionIndex2 = 0, frictionIndex3 = 0; //PxU32 contactIndex0 = 0, contactIndex1 = 0, contactIndex2 = 0, contactIndex3 = 0; - //OK, we iterate through all friction patch counts in the constraint patch, building up the constraint list etc. PxU32 maxPatches = PxMax(descs[0].numFrictionPatches, PxMax(descs[1].numFrictionPatches, PxMax(descs[2].numFrictionPatches, descs[3].numFrictionPatches))); @@ -273,7 +267,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V p1 = V4Splat(FLoad(0.0001f)); const Vec4V orthoThreshold = V4Splat(FLoad(0.70710678f)); - PxU32 contact0 = 0, contact1 = 0, contact2 = 0, contact3 = 0; PxU32 patch0 = 0, patch1 = 0, patch2 = 0, patch3 = 0; @@ -290,21 +283,20 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des hasFinished[2] = i >= descs[2].numFrictionPatches; hasFinished[3] = i >= descs[3].numFrictionPatches; - frictionIndex0 = hasFinished[0] ? frictionIndex0 : descs[0].startFrictionPatchIndex + i; frictionIndex1 = hasFinished[1] ? frictionIndex1 : descs[1].startFrictionPatchIndex + i; frictionIndex2 = hasFinished[2] ? frictionIndex2 : descs[2].startFrictionPatchIndex + i; frictionIndex3 = hasFinished[3] ? frictionIndex3 : descs[3].startFrictionPatchIndex + i; - PxU32 clampedContacts0 = hasFinished[0] ? 0 : c.frictionPatchContactCounts[frictionIndex0]; - PxU32 clampedContacts1 = hasFinished[1] ? 0 : c.frictionPatchContactCounts[frictionIndex1]; - PxU32 clampedContacts2 = hasFinished[2] ? 0 : c.frictionPatchContactCounts[frictionIndex2]; - PxU32 clampedContacts3 = hasFinished[3] ? 0 : c.frictionPatchContactCounts[frictionIndex3]; + const PxU32 clampedContacts0 = hasFinished[0] ? 0 : c.frictionPatchContactCounts[frictionIndex0]; + const PxU32 clampedContacts1 = hasFinished[1] ? 0 : c.frictionPatchContactCounts[frictionIndex1]; + const PxU32 clampedContacts2 = hasFinished[2] ? 0 : c.frictionPatchContactCounts[frictionIndex2]; + const PxU32 clampedContacts3 = hasFinished[3] ? 0 : c.frictionPatchContactCounts[frictionIndex3]; - PxU32 firstPatch0 = c.correlationListHeads[frictionIndex0]; - PxU32 firstPatch1 = c.correlationListHeads[frictionIndex1]; - PxU32 firstPatch2 = c.correlationListHeads[frictionIndex2]; - PxU32 firstPatch3 = c.correlationListHeads[frictionIndex3]; + const PxU32 firstPatch0 = c.correlationListHeads[frictionIndex0]; + const PxU32 firstPatch1 = c.correlationListHeads[frictionIndex1]; + const PxU32 firstPatch2 = c.correlationListHeads[frictionIndex2]; + const PxU32 firstPatch3 = c.correlationListHeads[frictionIndex3]; const PxContactPoint* contactBase0 = descs[0].contacts + c.contactPatches[firstPatch0].start; const PxContactPoint* contactBase1 = descs[1].contacts + c.contactPatches[firstPatch1].start; @@ -317,8 +309,7 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des SolverContactHeader4* PX_RESTRICT header = reinterpret_cast(ptr); ptr += sizeof(SolverContactHeader4); - - + header->flags[0] = flags[0]; header->flags[1] = flags[1]; header->flags[2] = flags[2]; @@ -474,7 +465,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des PX_ASSERT(ValidateVec4(rbY)); PX_ASSERT(ValidateVec4(rbZ)); - //raXn = cross(ra, normal) which = 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); Vec4V raXnX = V4NegMulSub(raZ, normalY, V4Mul(raY, normalZ)); @@ -518,14 +508,12 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des delAngVel0Y = V4MulAdd(invInertia0Z1, raXnZ, delAngVel0Y); delAngVel0Z = V4MulAdd(invInertia0Z2, raXnZ, delAngVel0Z); - PX_ASSERT(ValidateVec4(delAngVel0X)); PX_ASSERT(ValidateVec4(delAngVel0Y)); PX_ASSERT(ValidateVec4(delAngVel0Z)); const Vec4V dotDelAngVel0 = V4MulAdd(delAngVel0X, delAngVel0X, V4MulAdd(delAngVel0Y, delAngVel0Y, V4Mul(delAngVel0Z, delAngVel0Z))); - Vec4V unitResponse = V4MulAdd(dotDelAngVel0, angDom0, invMass0D0); Vec4V vrel = V4Add(relNorVel, relAng); @@ -560,7 +548,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des dynamicContact->rbXnX = delAngVel1X; dynamicContact->rbXnY = delAngVel1Y; dynamicContact->rbXnZ = delAngVel1Z; - } const Vec4V penetration = V4Sub(separation, restDistance); @@ -574,8 +561,7 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V x = V4Recip(V4MulAdd(a, unitResponse, V4One())); const Vec4V velMultiplier = V4Sel(isCompliant, V4Mul(x, a), V4Sel(V4IsGrtr(unitResponse, zero), V4Recip(unitResponse), zero)); const Vec4V impulseMultiplier = V4Sub(V4One(), V4Sel(isCompliant, x, zero)); - - + Vec4V scaledBias = V4Mul(penInvDtPt8, velMultiplier); const Vec4V penetrationInvDt = V4Scale(penetration, invDt); @@ -589,13 +575,13 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V targetVelocity = V4Mul(V4Add(V4Sub(cTargetNorVel, vrel), V4Sel(isGreater2, V4Mul(vrel, restitution), zero)), velMultiplier); - Vec4V biasedErr = V4Add(targetVelocity, scaledBias); + const Vec4V biasedErr = V4Add(targetVelocity, scaledBias); //These values are present for static and dynamic contacts solverContact->raXnX = delAngVel0X; solverContact->raXnY = delAngVel0Y; solverContact->raXnZ = delAngVel0Z; - solverContact->velMultiplier =V4Sel(bFinished, zero, velMultiplier); + solverContact->velMultiplier = V4Sel(bFinished, zero, velMultiplier); solverContact->biasedErr = V4Sel(bFinished, zero, biasedErr); solverContact->impulseMultiplier = impulseMultiplier; @@ -650,28 +636,27 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des Vec4V maxImpulseScale = V4One(); { - const FrictionPatch& frictionPatch0 = c.frictionPatches[frictionIndex0]; const FrictionPatch& frictionPatch1 = c.frictionPatches[frictionIndex1]; const FrictionPatch& frictionPatch2 = c.frictionPatches[frictionIndex2]; const FrictionPatch& frictionPatch3 = c.frictionPatches[frictionIndex3]; - PxU32 anchorCount0 = frictionPatch0.anchorCount; - PxU32 anchorCount1 = frictionPatch1.anchorCount; - PxU32 anchorCount2 = frictionPatch2.anchorCount; - PxU32 anchorCount3 = frictionPatch3.anchorCount; + const PxU32 anchorCount0 = frictionPatch0.anchorCount; + const PxU32 anchorCount1 = frictionPatch1.anchorCount; + const PxU32 anchorCount2 = frictionPatch2.anchorCount; + const PxU32 anchorCount3 = frictionPatch3.anchorCount; - PxU32 clampedAnchorCount0 = hasFinished[0] || (contactBase0->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount0; - PxU32 clampedAnchorCount1 = hasFinished[1] || (contactBase1->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount1; - PxU32 clampedAnchorCount2 = hasFinished[2] || (contactBase2->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount2; - PxU32 clampedAnchorCount3 = hasFinished[3] || (contactBase3->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount3; + const PxU32 clampedAnchorCount0 = hasFinished[0] || (contactBase0->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount0; + const PxU32 clampedAnchorCount1 = hasFinished[1] || (contactBase1->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount1; + const PxU32 clampedAnchorCount2 = hasFinished[2] || (contactBase2->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount2; + const PxU32 clampedAnchorCount3 = hasFinished[3] || (contactBase3->materialFlags & PxMaterialFlag::eDISABLE_FRICTION) ? 0 : anchorCount3; const PxU32 maxAnchorCount = PxMax(clampedAnchorCount0, PxMax(clampedAnchorCount1, PxMax(clampedAnchorCount2, clampedAnchorCount3))); - PxReal coefficient0 = (contactBase0->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount0 == 2) ? 0.5f : 1.f; - PxReal coefficient1 = (contactBase1->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount1 == 2) ? 0.5f : 1.f; - PxReal coefficient2 = (contactBase2->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount2 == 2) ? 0.5f : 1.f; - PxReal coefficient3 = (contactBase3->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount3 == 2) ? 0.5f : 1.f; + const PxReal coefficient0 = (contactBase0->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount0 == 2) ? 0.5f : 1.f; + const PxReal coefficient1 = (contactBase1->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount1 == 2) ? 0.5f : 1.f; + const PxReal coefficient2 = (contactBase2->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount2 == 2) ? 0.5f : 1.f; + const PxReal coefficient3 = (contactBase3->materialFlags & PxMaterialFlag::eIMPROVED_PATCH_FRICTION && anchorCount3 == 2) ? 0.5f : 1.f; const Vec4V staticFriction = V4LoadXYZW(contactBase0->staticFriction*coefficient0, contactBase1->staticFriction*coefficient1, contactBase2->staticFriction*coefficient2, contactBase3->staticFriction*coefficient3); @@ -683,12 +668,9 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des header->dynamicFriction = dynamicFriction; header->staticFriction = staticFriction; - - //if(clampedAnchorCount0 != clampedAnchorCount1 || clampedAnchorCount0 != clampedAnchorCount2 || clampedAnchorCount0 != clampedAnchorCount3) // PxDebugBreak(); - //const bool haveFriction = maxAnchorCount != 0; header->numFrictionConstr = PxTo8(maxAnchorCount*2); header->numFrictionConstr0 = PxTo8(clampedAnchorCount0*2); @@ -701,14 +683,13 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des if(maxAnchorCount) { - //Allocate the shared friction data... SolverFrictionSharedData4* PX_RESTRICT fd = reinterpret_cast(ptr); ptr += sizeof(SolverFrictionSharedData4); PX_UNUSED(fd); - const BoolV cond =V4IsGrtr(orthoThreshold, V4Abs(normalX)); + const BoolV cond = V4IsGrtr(orthoThreshold, V4Abs(normalX)); const Vec4V t0FallbackX = V4Sel(cond, zero, V4Neg(normalY)); const Vec4V t0FallbackY = V4Sel(cond, V4Neg(normalZ), normalX); @@ -727,7 +708,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des Vec4V t0Y = V4Sel(bcon2, vrelSubNorVelY, t0FallbackY); Vec4V t0Z = V4Sel(bcon2, vrelSubNorVelZ, t0FallbackZ); - //Now normalize this... const Vec4V recipLen = V4Rsqrt(V4MulAdd(t0Z, t0Z, V4MulAdd(t0Y, t0Y, V4Mul(t0X, t0X)))); @@ -744,7 +724,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des PX_ASSERT((uintptr_t(descs[2].frictionPtr) & 0xF) == 0); PX_ASSERT((uintptr_t(descs[3].frictionPtr) & 0xF) == 0); - PxU8* PX_RESTRICT writeback0 = descs[0].frictionPtr + frictionPatchWritebackAddrIndex0*sizeof(FrictionPatch); PxU8* PX_RESTRICT writeback1 = descs[1].frictionPtr + frictionPatchWritebackAddrIndex1*sizeof(FrictionPatch); PxU8* PX_RESTRICT writeback2 = descs[2].frictionPtr + frictionPatchWritebackAddrIndex2*sizeof(FrictionPatch); @@ -758,7 +737,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des fd->frictionBrokenWritebackByte[2] = writeback2; fd->frictionBrokenWritebackByte[3] = writeback3; - fd->normalX[0] = t0X; fd->normalY[0] = t0Y; fd->normalZ[0] = t0Z; @@ -804,11 +782,10 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des t1Y = V4Mul(maxImpulseScale, t1Y); t1Z = V4Mul(maxImpulseScale, t1Z); - - Vec3V body0Anchor0 = V3LoadU(frictionPatch0.body0Anchors[index0]); - Vec3V body0Anchor1 = V3LoadU(frictionPatch1.body0Anchors[index1]); - Vec3V body0Anchor2 = V3LoadU(frictionPatch2.body0Anchors[index2]); - Vec3V body0Anchor3 = V3LoadU(frictionPatch3.body0Anchors[index3]); + const Vec3V body0Anchor0 = V3LoadU(frictionPatch0.body0Anchors[index0]); + const Vec3V body0Anchor1 = V3LoadU(frictionPatch1.body0Anchors[index1]); + const Vec3V body0Anchor2 = V3LoadU(frictionPatch2.body0Anchors[index2]); + const Vec3V body0Anchor3 = V3LoadU(frictionPatch3.body0Anchors[index3]); Vec4V ra0 = Vec4V_From_Vec3V(QuatRotate(bodyFrame00q, body0Anchor0)); Vec4V ra1 = Vec4V_From_Vec3V(QuatRotate(bodyFrame01q, body0Anchor1)); @@ -826,10 +803,10 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V raWorldY = V4Add(raY, bodyFrame0pY); const Vec4V raWorldZ = V4Add(raZ, bodyFrame0pZ); - Vec3V body1Anchor0 = V3LoadU(frictionPatch0.body1Anchors[index0]); - Vec3V body1Anchor1 = V3LoadU(frictionPatch1.body1Anchors[index1]); - Vec3V body1Anchor2 = V3LoadU(frictionPatch2.body1Anchors[index2]); - Vec3V body1Anchor3 = V3LoadU(frictionPatch3.body1Anchors[index3]); + const Vec3V body1Anchor0 = V3LoadU(frictionPatch0.body1Anchors[index0]); + const Vec3V body1Anchor1 = V3LoadU(frictionPatch1.body1Anchors[index1]); + const Vec3V body1Anchor2 = V3LoadU(frictionPatch2.body1Anchors[index2]); + const Vec3V body1Anchor3 = V3LoadU(frictionPatch3.body1Anchors[index3]); Vec4V rb0 = Vec4V_From_Vec3V(QuatRotate(bodyFrame10q, body1Anchor0)); Vec4V rb1 = Vec4V_From_Vec3V(QuatRotate(bodyFrame11q, body1Anchor1)); @@ -847,21 +824,21 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V rbWorldY = V4Add(rbY, bodyFrame1pY); const Vec4V rbWorldZ = V4Add(rbZ, bodyFrame1pZ); - Vec4V errorX = V4Sub(raWorldX, rbWorldX); - Vec4V errorY = V4Sub(raWorldY, rbWorldY); - Vec4V errorZ = V4Sub(raWorldZ, rbWorldZ); + const Vec4V errorX = V4Sub(raWorldX, rbWorldX); + const Vec4V errorY = V4Sub(raWorldY, rbWorldY); + const Vec4V errorZ = V4Sub(raWorldZ, rbWorldZ); /*errorX = V4Sel(V4IsGrtr(solverOffsetSlop, V4Abs(errorX)), zero, errorX); errorY = V4Sel(V4IsGrtr(solverOffsetSlop, V4Abs(errorY)), zero, errorY); errorZ = V4Sel(V4IsGrtr(solverOffsetSlop, V4Abs(errorZ)), zero, errorZ);*/ //KS - todo - get this working with per-point friction - PxU32 contactIndex0 = c.contactID[frictionIndex0][index0]; - PxU32 contactIndex1 = c.contactID[frictionIndex1][index1]; - PxU32 contactIndex2 = c.contactID[frictionIndex2][index2]; - PxU32 contactIndex3 = c.contactID[frictionIndex3][index3]; + const PxU32 contactIndex0 = c.contactID[frictionIndex0][index0]; + const PxU32 contactIndex1 = c.contactID[frictionIndex1][index1]; + const PxU32 contactIndex2 = c.contactID[frictionIndex2][index2]; + const PxU32 contactIndex3 = c.contactID[frictionIndex3][index3]; - //Ensure that the ocntact indices are valid + //Ensure that the contact indices are valid PX_ASSERT(contactIndex0 == 0xffff || contactIndex0 < descs[0].numContacts); PX_ASSERT(contactIndex1 == 0xffff || contactIndex1 < descs[1].numContacts); PX_ASSERT(contactIndex2 == 0xffff || contactIndex2 < descs[2].numContacts); @@ -875,7 +852,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des Vec4V targetVelX, targetVelY, targetVelZ; PX_TRANSPOSE_44_34(targetVel0, targetVel1, targetVel2, targetVel3, targetVelX, targetVelY, targetVelZ); - { Vec4V raXnX = V4NegMulSub(raZ, t0Y, V4Mul(raY, t0Z)); Vec4V raXnY = V4NegMulSub(raX, t0Z, V4Mul(raZ, t0X)); @@ -955,7 +931,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des vrel = V4Sub(vrel, dotRbXnAngVel1); } - const Vec4V velMultiplier = V4Mul(maxImpulseScale, V4Sel(V4IsGrtr(resp, zero), V4Div(p84, resp), zero)); Vec4V bias = V4Scale(V4MulAdd(t0Z, errorZ, V4MulAdd(t0Y, errorY, V4Mul(t0X, errorX))), invDt); @@ -1038,7 +1013,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des const Vec4V vel1 = V4MulAdd(rbXnZ, angVelT21, V4MulAdd(rbXnY, angVelT11, V4MulAdd(rbXnX, angVelT01, tVel1))); vrel = V4Sub(vrel, vel1); - } else if(hasKinematic) { @@ -1052,7 +1026,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des vrel = V4Sub(vrel, dotRbXnAngVel1); } - const Vec4V velMultiplier = V4Mul(maxImpulseScale, V4Sel(V4IsGrtr(resp, zero), V4Div(p84, resp), zero)); Vec4V bias = V4Scale(V4MulAdd(t1Z, errorZ, V4MulAdd(t1Y, errorY, V4Mul(t1X, errorX))), invDt); @@ -1078,8 +1051,6 @@ static void setupFinalizeSolverConstraints4(PxSolverContactDesc* PX_RESTRICT des } } - - PX_FORCE_INLINE void computeBlockStreamFrictionByteSizes(const CorrelationBuffer& c, PxU32& _frictionPatchByteSize, PxU32& _numFrictionPatches, PxU32 frictionPatchStartIndex, PxU32 frictionPatchEndIndex) @@ -1103,10 +1074,8 @@ PX_FORCE_INLINE void computeBlockStreamFrictionByteSizes(const CorrelationBuffer } static bool reserveFrictionBlockStreams(const CorrelationBuffer& c, PxConstraintAllocator& constraintAllocator, PxU32 frictionPatchStartIndex, PxU32 frictionPatchEndIndex, - FrictionPatch*& _frictionPatches, - PxU32& numFrictionPatches) + FrictionPatch*& _frictionPatches, PxU32& numFrictionPatches) { - //From frictionPatchStream we just need to reserve a single buffer. PxU32 frictionPatchByteSize = 0; //Compute the sizes of all the buffers. @@ -1195,7 +1164,6 @@ void computeBlockStreamByteSizes4(PxSolverContactDesc* descs, maxFrictionPatches++; } - PxU32 totalContacts = 0, totalFriction = 0; for(PxU32 a = 0; a < maxPatches; ++a) { @@ -1212,7 +1180,6 @@ void computeBlockStreamByteSizes4(PxSolverContactDesc* descs, { hasDynamicBody = hasDynamicBody || ((descs[a].bodyState1 == PxSolverContactDesc::eDYNAMIC_BODY)); } - const bool isStatic = !hasDynamicBody; @@ -1227,7 +1194,7 @@ void computeBlockStreamByteSizes4(PxSolverContactDesc* descs, if(hasMaxImpulse) constraintSize += sizeof(aos::Vec4V) * totalContacts; - _solverConstraintByteSize = ((constraintSize + headerSize + 0x0f) & ~0x0f); + _solverConstraintByteSize = ((constraintSize + headerSize + 0x0f) & ~0x0f); PX_ASSERT(0 == (_solverConstraintByteSize & 0x0f)); } @@ -1379,8 +1346,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( PxU8* solverConstraint = NULL; PxU32 solverConstraintByteSize = 0; - - { PxU32 axisConstraintCount[4]; SolverConstraintPrepState::Enum state = reserveBlockStreams4(blockDescs, c, @@ -1391,10 +1356,8 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( if (state != SolverConstraintPrepState::eSUCCESS) return state; - for (PxU32 a = 0; a < 4; ++a) { - FrictionPatch* frictionPatches = frictionPatchArray[a]; PxSolverContactDesc& blockDesc = blockDescs[a]; @@ -1422,7 +1385,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( } } - blockDesc.axisConstraintCount += PxTo16(axisConstraintCount[a]); desc.constraint = solverConstraint; @@ -1445,7 +1407,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( return SolverConstraintPrepState::eSUCCESS; } - //This returns 1 of 3 states: success, unbatchable or out-of-memory. If the constraint is unbatchable, we must fall back on 4 separate constraint //prep calls SolverConstraintPrepState::Enum createFinalizeSolverContacts4( @@ -1455,11 +1416,10 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( const PxReal invDtF32, const PxReal dtF32, PxReal bounceThresholdF32, - PxReal frictionOffsetThreshold, + PxReal frictionOffsetThreshold, PxReal correlationDistance, PxConstraintAllocator& constraintAllocator) { - for (PxU32 a = 0; a < 4; ++a) { blockDescs[a].desc->constraintLengthOver16 = 0; @@ -1486,7 +1446,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( PxPrefetchLine(desc.bodyA); PxPrefetchLine(desc.bodyB); - if ((buffer.count + cmOutputs[a]->nbContacts) > 64) { return SolverConstraintPrepState::eUNBATCHABLE; @@ -1527,18 +1486,13 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4( //blockDesc.frictionPtr = &blockDescs[a].frictionPtr; //blockDesc.frictionCount = blockDescs[a].frictionCount; - } return createFinalizeSolverContacts4(c, blockDescs, invDtF32, dtF32, bounceThresholdF32, frictionOffsetThreshold, correlationDistance, constraintAllocator); } - - - } - } diff --git a/physx/source/lowleveldynamics/src/DyContactPrep4PF.cpp b/physx/source/lowleveldynamics/src/DyContactPrep4PF.cpp index 55bcbb0f4..202260c8b 100644 --- a/physx/source/lowleveldynamics/src/DyContactPrep4PF.cpp +++ b/physx/source/lowleveldynamics/src/DyContactPrep4PF.cpp @@ -25,7 +25,6 @@ // Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "foundation/PxPreprocessor.h" #include "foundation/PxVecMath.h" @@ -133,8 +132,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR const Vec4V vrelY = V4Sub(linVelT10, linVelT11); const Vec4V vrelZ = V4Sub(linVelT20, linVelT21); - - //Load up masses and invInertia const Vec4V invMass0 = V4Merge(FLoad(descs[0].data0->invMass), FLoad(descs[1].data0->invMass), FLoad(descs[2].data0->invMass), @@ -216,7 +213,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR Vec4V bodyFrame0pX, bodyFrame0pY, bodyFrame0pZ; PX_TRANSPOSE_44_34(bodyFrame00p4, bodyFrame01p4, bodyFrame02p4, bodyFrame03p4, bodyFrame0pX, bodyFrame0pY, bodyFrame0pZ); - const Vec3V bodyFrame10p = V3LoadU(descs[0].bodyFrame1.p); const Vec3V bodyFrame11p = V3LoadU(descs[1].bodyFrame1.p); const Vec3V bodyFrame12p = V3LoadU(descs[2].bodyFrame1.p); @@ -230,13 +226,11 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR Vec4V bodyFrame1pX, bodyFrame1pY, bodyFrame1pZ; PX_TRANSPOSE_44_34(bodyFrame10p4, bodyFrame11p4, bodyFrame12p4, bodyFrame13p4, bodyFrame1pX, bodyFrame1pY, bodyFrame1pZ); - PxPrefetchLine(c.contactID); PxPrefetchLine(c.contactID, 128); PxU32 frictionIndex0 = 0, frictionIndex1 = 0, frictionIndex2 = 0, frictionIndex3 = 0; - PxU32 maxPatches = PxMax(descs[0].numFrictionPatches, PxMax(descs[1].numFrictionPatches, PxMax(descs[2].numFrictionPatches, descs[3].numFrictionPatches))); PxU32 maxContacts = numContactPoints4; @@ -252,30 +246,28 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR const bool hasFinished2 = i >= descs[2].numFrictionPatches; const bool hasFinished3 = i >= descs[3].numFrictionPatches; - frictionIndex0 = hasFinished0 ? frictionIndex0 : descs[0].startFrictionPatchIndex + i; frictionIndex1 = hasFinished1 ? frictionIndex1 : descs[1].startFrictionPatchIndex + i; frictionIndex2 = hasFinished2 ? frictionIndex2 : descs[2].startFrictionPatchIndex + i; frictionIndex3 = hasFinished3 ? frictionIndex3 : descs[3].startFrictionPatchIndex + i; - PxU32 clampedContacts0 = hasFinished0 ? 0 : c.frictionPatchContactCounts[frictionIndex0]; - PxU32 clampedContacts1 = hasFinished1 ? 0 : c.frictionPatchContactCounts[frictionIndex1]; - PxU32 clampedContacts2 = hasFinished2 ? 0 : c.frictionPatchContactCounts[frictionIndex2]; - PxU32 clampedContacts3 = hasFinished3 ? 0 : c.frictionPatchContactCounts[frictionIndex3]; - - PxU32 clampedFric0 = clampedContacts0 * numFrictionPerPoint; - PxU32 clampedFric1 = clampedContacts1 * numFrictionPerPoint; - PxU32 clampedFric2 = clampedContacts2 * numFrictionPerPoint; - PxU32 clampedFric3 = clampedContacts3 * numFrictionPerPoint; + const PxU32 clampedContacts0 = hasFinished0 ? 0 : c.frictionPatchContactCounts[frictionIndex0]; + const PxU32 clampedContacts1 = hasFinished1 ? 0 : c.frictionPatchContactCounts[frictionIndex1]; + const PxU32 clampedContacts2 = hasFinished2 ? 0 : c.frictionPatchContactCounts[frictionIndex2]; + const PxU32 clampedContacts3 = hasFinished3 ? 0 : c.frictionPatchContactCounts[frictionIndex3]; + const PxU32 clampedFric0 = clampedContacts0 * numFrictionPerPoint; + const PxU32 clampedFric1 = clampedContacts1 * numFrictionPerPoint; + const PxU32 clampedFric2 = clampedContacts2 * numFrictionPerPoint; + const PxU32 clampedFric3 = clampedContacts3 * numFrictionPerPoint; const PxU32 numContacts = PxMax(clampedContacts0, PxMax(clampedContacts1, PxMax(clampedContacts2, clampedContacts3))); const PxU32 numFrictions = PxMax(clampedFric0, PxMax(clampedFric1, PxMax(clampedFric2, clampedFric3))); - PxU32 firstPatch0 = c.correlationListHeads[frictionIndex0]; - PxU32 firstPatch1 = c.correlationListHeads[frictionIndex1]; - PxU32 firstPatch2 = c.correlationListHeads[frictionIndex2]; - PxU32 firstPatch3 = c.correlationListHeads[frictionIndex3]; + const PxU32 firstPatch0 = c.correlationListHeads[frictionIndex0]; + const PxU32 firstPatch1 = c.correlationListHeads[frictionIndex1]; + const PxU32 firstPatch2 = c.correlationListHeads[frictionIndex2]; + const PxU32 firstPatch3 = c.correlationListHeads[frictionIndex3]; const PxContactPoint* contactBase0 = descs[0].contacts + c.contactPatches[firstPatch0].start; const PxContactPoint* contactBase1 = descs[1].contacts + c.contactPatches[firstPatch1].start; @@ -297,7 +289,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR SolverFrictionHeader4* PX_RESTRICT fricHeader = reinterpret_cast(ptr2); ptr2 += sizeof(SolverFrictionHeader4) + sizeof(Vec4V) * numContacts; - header->numNormalConstr0 = PxTo8(clampedContacts0); header->numNormalConstr1 = PxTo8(clampedContacts1); header->numNormalConstr2 = PxTo8(clampedContacts2); @@ -353,9 +344,8 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR const Vec4V invMassNorLenSq0 = V4Mul(invMass0_dom0fV, normalLenSq); const Vec4V invMassNorLenSq1 = V4Mul(invMass1_dom1fV, normalLenSq); - //Calculate friction directions - const BoolV cond =V4IsGrtr(orthoThreshold, V4Abs(normalX)); + const BoolV cond = V4IsGrtr(orthoThreshold, V4Abs(normalX)); const Vec4V t0FallbackX = V4Sel(cond, zero, V4Neg(normalY)); const Vec4V t0FallbackY = V4Sel(cond, V4Neg(normalZ), normalX); @@ -389,7 +379,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR const Vec4V tFallbackY[2] = {t0Y, t1Y}; const Vec4V tFallbackZ[2] = {t0Z, t1Z}; - //For all correlation heads - need to pull this out I think //OK, we have a counter for all our patches... @@ -504,7 +493,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR Vec4V unitResponse = V4Add(invMassNorLenSq0, dotDelAngVel0); Vec4V vrel = V4Add(linNorVel0, dotRaXnAngVel0); - //The dynamic-only parts - need to if-statement these up. A branch here shouldn't cost us too much if(isDynamic) { @@ -525,7 +513,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR const Vec4V delAngVel1Y = V4MulAdd(invInertia1Z1, rbXnZ, v0PlusV1b1); const Vec4V delAngVel1Z = V4MulAdd(invInertia1Z2, rbXnZ, v0PlusV1b2); - //V3Dot(raXn, delAngVel0) const Vec4V dotDelAngVel1 = V4MulAdd(delAngVel1Z, delAngVel1Z, V4MulAdd(delAngVel1Y, delAngVel1Y, V4Mul(delAngVel1X, delAngVel1X))); @@ -543,7 +530,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR dynamicContact->rbXnX = delAngVel1X; dynamicContact->rbXnY = delAngVel1Y; dynamicContact->rbXnZ = delAngVel1Z; - } const Vec4V velMultiplier = V4Sel(V4IsGrtr(unitResponse, zero), V4Recip(unitResponse), zero); @@ -701,8 +687,6 @@ static bool setupFinalizeSolverConstraintsCoulomb4(PxSolverContactDesc* PX_RESTR return true; } - - //The persistent friction patch correlation/allocation will already have happenned as this is per-pair. //This function just computes the size of the combined solve data. void computeBlockStreamByteSizesCoulomb4(PxSolverContactDesc* descs, @@ -757,7 +741,6 @@ void computeBlockStreamByteSizesCoulomb4(PxSolverContactDesc* descs, _numContactPoints4 = totalContacts; - //OK, we have a given number of friction patches, contact points and friction constraints so we can calculate how much memory we need const bool isStatic = (((descs[0].bodyState1 | descs[1].bodyState1 | descs[2].bodyState1 | descs[3].bodyState1) & PxSolverContactDesc::eDYNAMIC_BODY) == 0); @@ -767,11 +750,10 @@ void computeBlockStreamByteSizesCoulomb4(PxSolverContactDesc* descs, const PxU32 constraintSize = isStatic ? ((sizeof(SolverContact4Base) + sizeof(Vec4V)) * totalContacts) + ( sizeof(SolverFriction4Base) * totalFriction) : ((sizeof(SolverContact4Dynamic) + sizeof(Vec4V)) * totalContacts) + (sizeof(SolverFriction4Dynamic) * totalFriction); - _solverConstraintByteSize = ((constraintSize + headerSize + 0x0f) & ~0x0f); + _solverConstraintByteSize = ((constraintSize + headerSize + 0x0f) & ~0x0f); PX_ASSERT(0 == (_solverConstraintByteSize & 0x0f)); } - static SolverConstraintPrepState::Enum reserveBlockStreamsCoulomb4(PxSolverContactDesc* descs, ThreadContext& threadContext, const CorrelationBuffer& c, PxU8*& solverConstraint, const PxU32 numFrictionPerContactPoint, PxU32& solverConstraintByteSize, @@ -862,7 +844,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Coulomb2D( frictionOffsetThreshold, correlationDistance, constraintAllocator, PxFrictionType::eTWO_DIRECTIONAL); } - SolverConstraintPrepState::Enum createFinalizeSolverContacts4Coulomb( PxsContactManagerOutput** outputs, ThreadContext& threadContext, @@ -951,7 +932,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Coulomb( invMassScale1[a] *= blockDesc.invMassScales.linear1; invInertiaScale0[a] *= blockDesc.invMassScales.angular0; invInertiaScale1[a] *= blockDesc.invMassScales.angular1; - } //OK, now we need to work out how much memory to allocate, allocate it and then block-create the constraints... @@ -991,7 +971,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Coulomb( const Vec4V iMassScale1 = V4LoadA(invMassScale1); const Vec4V iInertiaScale1 = V4LoadA(invInertiaScale1); - bool hasFriction = setupFinalizeSolverConstraintsCoulomb4(blockDescs, solverConstraint, invDtF32, bounceThresholdF32, c, numFrictionPerPoint, numContactPoints4, solverConstraintByteSize, iMassScale0, iInertiaScale0, iMassScale1, iInertiaScale1); @@ -999,7 +978,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Coulomb( *(reinterpret_cast(solverConstraint + solverConstraintByteSize)) = 0; *(reinterpret_cast(solverConstraint + solverConstraintByteSize + 4)) = hasFriction ? 0xFFFFFFFF : 0; - return SolverConstraintPrepState::eSUCCESS; } diff --git a/physx/source/lowleveldynamics/src/DyContactPrepPF.cpp b/physx/source/lowleveldynamics/src/DyContactPrepPF.cpp index 1f1c984aa..dbd4d6f79 100644 --- a/physx/source/lowleveldynamics/src/DyContactPrepPF.cpp +++ b/physx/source/lowleveldynamics/src/DyContactPrepPF.cpp @@ -43,7 +43,6 @@ namespace physx { namespace Dy { - bool createFinalizeSolverContactsCoulomb(PxSolverContactDesc& contactDesc, PxsContactManagerOutput& output, ThreadContext& threadContext, @@ -56,8 +55,7 @@ bool createFinalizeSolverContactsCoulomb(PxSolverContactDesc& contactDesc, PxFrictionType::Enum frictionType, Cm::SpatialVectorF* Z); -static bool setupFinalizeSolverConstraintsCoulomb( - Sc::ShapeInteraction* shapeInteraction, +static bool setupFinalizeSolverConstraintsCoulomb(Sc::ShapeInteraction* shapeInteraction, const PxContactBuffer& buffer, const CorrelationBuffer& c, const PxTransform& bodyFrame0, @@ -99,13 +97,11 @@ static bool setupFinalizeSolverConstraintsCoulomb( const PxU8 pointHeaderType = PxTo8(staticBody ? DY_SC_TYPE_STATIC_CONTACT : DY_SC_TYPE_RB_CONTACT); const PxU8 frictionHeaderType = PxTo8(staticBody ? DY_SC_TYPE_STATIC_FRICTION : DY_SC_TYPE_FRICTION); - const Vec3V linVel0 = V3LoadU(data0.linearVelocity); const Vec3V linVel1 = V3LoadU(data1.linearVelocity); const Vec3V angVel0 = V3LoadU(data0.angularVelocity); const Vec3V angVel1 = V3LoadU(data1.angularVelocity); - const FloatV invMass0 = FLoad(data0.invMass); const FloatV invMass1 = FLoad(data1.invMass); @@ -145,7 +141,6 @@ static bool setupFinalizeSolverConstraintsCoulomb( const FloatV invMass0_dom0fV = FMul(d0, invMass0); const FloatV invMass1_dom1fV = FMul(nDom1fV, invMass1); - for(PxU32 i=0;i< frictionPatchCount;i++) { const PxU32 contactCount = c.frictionPatchContactCounts[i]; @@ -170,7 +165,6 @@ static bool setupFinalizeSolverConstraintsCoulomb( const FloatV invMassNorLenSq0 = FMul(invMass0_dom0fV, normalLenSq); const FloatV invMassNorLenSq1 = FMul(invMass1_dom1fV, normalLenSq); - SolverContactCoulombHeader* PX_RESTRICT header = reinterpret_cast(ptr); ptr += sizeof(SolverContactCoulombHeader); @@ -178,7 +172,6 @@ static bool setupFinalizeSolverConstraintsCoulomb( PxPrefetchLine(ptr, 256); PxPrefetchLine(ptr, 384); - header->numNormalConstr = PxU8(contactCount); header->type = pointHeaderType; //header->setRestitution(n.restitution); @@ -192,15 +185,13 @@ static bool setupFinalizeSolverConstraintsCoulomb( header->flags = flags; header->shapeInteraction = shapeInteraction; - for(PxU32 patch=c.correlationListHeads[i]; patch!=CorrelationBuffer::LIST_END; patch = c.contactPatches[patch].next) { const PxU32 count = c.contactPatches[patch].count; const PxContactPoint* contactBase = buffer.contacts + c.contactPatches[patch].start; - - + PxU8* p = ptr; for(PxU32 j=0;jnormalXYZ_appliedForceW = V4SetW(Vec4V_From_Vec3V(t0), zero); f0->raXnXYZ_velMultiplierW = V4SetW(Vec4V_From_Vec3V(delAngVel0), velMultiplier); //f0->rbXnXYZ_targetVelocityW = V4SetW(Vec4V_From_Vec3V(delAngVel1), FSub(V3Dot(targetVel, t0), vrel)); @@ -346,12 +336,9 @@ static bool setupFinalizeSolverConstraintsCoulomb( return hasFriction; } - - -static void computeBlockStreamByteSizesCoulomb(const CorrelationBuffer& c, - const PxU32 frictionCountPerPoint, PxU32& _solverConstraintByteSize, - PxU32& _axisConstraintCount, - bool useExtContacts) +static void computeBlockStreamByteSizesCoulomb( const CorrelationBuffer& c, + const PxU32 frictionCountPerPoint, PxU32& _solverConstraintByteSize, + PxU32& _axisConstraintCount, bool useExtContacts) { PX_ASSERT(0 == _solverConstraintByteSize); PX_ASSERT(0 == _axisConstraintCount); @@ -367,7 +354,6 @@ static void computeBlockStreamByteSizesCoulomb(const CorrelationBuffer& c, if(c.correlationListHeads[i] != CorrelationBuffer::LIST_END) numFrictionPatches++; - const FrictionPatch& frictionPatch = c.frictionPatches[i]; const bool haveFriction = (frictionPatch.materialFlags & PxMaterialFlag::eDISABLE_FRICTION) == 0; @@ -406,7 +392,7 @@ static void computeBlockStreamByteSizesCoulomb(const CorrelationBuffer& c, _axisConstraintCount = axisConstraintCount; //16-byte alignment. - _solverConstraintByteSize = ((solverConstraintByteSize + 0x0f) & ~0x0f); + _solverConstraintByteSize = ((solverConstraintByteSize + 0x0f) & ~0x0f); PX_ASSERT(0 == (_solverConstraintByteSize & 0x0f)); } @@ -420,7 +406,6 @@ static bool reserveBlockStreamsCoulomb(const CorrelationBuffer& c, PX_ASSERT(0 == solverConstraintByteSize); PX_ASSERT(0 == axisConstraintCount); - //From constraintBlockStream we need to reserve contact points, contact forces, and a char buffer for the solver constraint data (already have a variable for this). //From frictionPatchStream we just need to reserve a single buffer. @@ -496,7 +481,6 @@ bool createFinalizeSolverContactsCoulomb2D(PxSolverContactDesc& contactDesc, PxReal correlationDistance, PxConstraintAllocator& constraintAllocator, Cm::SpatialVectorF* Z) - { return createFinalizeSolverContactsCoulomb(contactDesc, output, threadContext, invDtF32, dtF32, bounceThresholdF32, frictionOffsetThreshold, correlationDistance, constraintAllocator, PxFrictionType::eTWO_DIRECTIONAL, Z); @@ -565,13 +549,9 @@ bool createFinalizeSolverContactsCoulomb(PxSolverContactDesc& contactDesc, PX_UNUSED(overflow); #if PX_CHECKED if(overflow) - { - PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, - "Dropping contacts in solver because we exceeded limit of 32 friction patches."); - } + PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL, "Dropping contacts in solver because we exceeded limit of 32 friction patches."); #endif - //PX_ASSERT(patchCount == c.frictionPatchCount); PxU8* solverConstraint = NULL; diff --git a/physx/source/lowleveldynamics/src/DyContactPrepShared.h b/physx/source/lowleveldynamics/src/DyContactPrepShared.h index 570a6f57e..183e71bba 100644 --- a/physx/source/lowleveldynamics/src/DyContactPrepShared.h +++ b/physx/source/lowleveldynamics/src/DyContactPrepShared.h @@ -68,7 +68,6 @@ PX_FORCE_INLINE bool isSeparated(const FrictionPatch& patch, const PxTransform& return false; } - inline bool getFrictionPatches(CorrelationBuffer& c, const PxU8* frictionCookie, PxU32 frictionPatchCount, @@ -76,7 +75,6 @@ inline bool getFrictionPatches(CorrelationBuffer& c, const PxTransform& bodyFrame1, PxReal correlationDistance) { - PX_UNUSED(correlationDistance); if(frictionCookie == NULL || frictionPatchCount == 0) return true; @@ -99,15 +97,13 @@ inline bool getFrictionPatches(CorrelationBuffer& c, if(patch.anchorCount != 0 && !(patch.materialFlags & PxMaterialFlag::eDISABLE_STRONG_FRICTION)) { PX_ASSERT(patch.anchorCount <= 2); - - + if(!evaluated) { body1ToBody0 = bodyFrame0.transformInv(bodyFrame1); evaluated = true; } - if(patch.body0Normal.dot(body1ToBody0.rotate(patch.body1Normal)) > PXC_SAME_NORMAL) { if(!isSeparated(patch, body1ToBody0, correlationDistance)) @@ -204,7 +200,7 @@ struct CorrelationListIterator } //Returns true if it has another contact pre-loaded. Returns false otherwise - PX_FORCE_INLINE bool hasNextContact() + PX_FORCE_INLINE bool hasNextContact() const { return (currPatch != CorrelationBuffer::LIST_END && currContact < buffer.contactPatches[currPatch].count); } @@ -233,11 +229,10 @@ struct CorrelationListIterator }; - - PX_FORCE_INLINE void constructContactConstraint(const Mat33V& invSqrtInertia0, const Mat33V& invSqrtInertia1, const FloatVArg invMassNorLenSq0, + PX_FORCE_INLINE void constructContactConstraint(const Mat33V& invSqrtInertia0, const Mat33V& invSqrtInertia1, const FloatVArg invMassNorLenSq0, const FloatVArg invMassNorLenSq1, const FloatVArg angD0, const FloatVArg angD1, const Vec3VArg bodyFrame0p, const Vec3VArg bodyFrame1p, const Vec3VArg normal, const FloatVArg norVel, const VecCrossV& norCross, const Vec3VArg angVel0, const Vec3VArg angVel1, - const FloatVArg invDt, const FloatVArg invDtp8, const FloatVArg dt, const FloatVArg restDistance, const FloatVArg maxPenBias, const FloatVArg restitution, + const FloatVArg invDt, const FloatVArg invDtp8, const FloatVArg dt, const FloatVArg restDistance, const FloatVArg maxPenBias, const FloatVArg restitution, const FloatVArg bounceThreshold, const PxContactPoint& contact, SolverContactPoint& solverContact, const FloatVArg ccdMaxSeparation, const Vec3VArg solverOffsetSlop, const FloatVArg damping) { @@ -267,7 +262,6 @@ struct CorrelationListIterator const FloatV vrel = FAdd(norVel, vRelAng); - const Vec3V raXnSqrtInertia = M33MulV3(invSqrtInertia0, raXn); const Vec3V rbXnSqrtInertia = M33MulV3(invSqrtInertia1, rbXn); @@ -279,18 +273,17 @@ struct CorrelationListIterator const FloatV penetration = FSub(separation, restDistance); const FloatV penetrationInvDt = FMul(penetration, invDt); - FloatV velMultiplier, scaledBias, impulseMultiplier; const FloatV sumVRel(vrel); const BoolV isGreater2 = BAnd(BAnd(FIsGrtr(restitution, zero), FIsGrtr(bounceThreshold, vrel)), FIsGrtr(FNeg(vrel), penetrationInvDt)); - FloatV targetVelocity = FAdd(cTargetVel, FSel(isGreater2, FMul(FNeg(sumVRel), restitution), zero)); //Note - we add on the initial target velocity targetVelocity = FSub(targetVelocity, vrel); FloatV biasedErr, unbiasedErr; + FloatV velMultiplier, impulseMultiplier; if (FAllGrtr(zero, restitution)) { @@ -302,8 +295,8 @@ struct CorrelationListIterator const FloatV x = FRecip(FScaleAdd(a, unitResponse, FOne())); velMultiplier = FMul(x, a); - //scaledBias = FSel(isSeparated, FNeg(invStepDt), FDiv(FMul(nrdt, FMul(x, unitResponse)), velMultiplier)); - scaledBias = FMul(x, b); + //FloatV scaledBias = FSel(isSeparated, FNeg(invStepDt), FDiv(FMul(nrdt, FMul(x, unitResponse)), velMultiplier)); + const FloatV scaledBias = FMul(x, b); impulseMultiplier = FSub(FOne(), x); unbiasedErr = biasedErr = FScaleAdd(targetVelocity, velMultiplier, FNeg(scaledBias)); @@ -314,23 +307,18 @@ struct CorrelationListIterator const FloatV penetrationInvDtPt8 = FMax(maxPenBias, FMul(penetration, invDtp8)); - scaledBias = FMul(velMultiplier, penetrationInvDtPt8); + FloatV scaledBias = FMul(velMultiplier, penetrationInvDtPt8); const BoolV ccdSeparationCondition = FIsGrtrOrEq(ccdMaxSeparation, penetration); scaledBias = FSel(BAnd(ccdSeparationCondition, isGreater2), zero, scaledBias); - impulseMultiplier = FLoad(1.f); + impulseMultiplier = FLoad(1.0f); biasedErr = FScaleAdd(targetVelocity, velMultiplier, FNeg(scaledBias)); unbiasedErr = FScaleAdd(targetVelocity, velMultiplier, FSel(isGreater2, zero, FNeg(FMax(scaledBias, zero)))); - } - - - - //const FloatV unbiasedErr = FScaleAdd(targetVelocity, velMultiplier, FNeg(FMax(scaledBias, zero))); FStore(biasedErr, &solverContact.biasedErr); diff --git a/physx/source/lowleveldynamics/src/DyContactReduction.h b/physx/source/lowleveldynamics/src/DyContactReduction.h index e162f8f3c..8d469b376 100644 --- a/physx/source/lowleveldynamics/src/DyContactReduction.h +++ b/physx/source/lowleveldynamics/src/DyContactReduction.h @@ -294,7 +294,7 @@ namespace Dy { for(PxU32 b = 0; b < tmpPatch->stride; ++b) { - PxReal magSq = (mOriginalContacts[tmpPatch->startIndex + b].point - p0).dot(dir); + PxReal magSq = (mOriginalContacts[tmpPatch->startIndex + b].point - p0).dot(dir); if(magSq > maxDist) { ind = tmpPatch->startIndex + b; diff --git a/physx/source/lowleveldynamics/src/DyCorrelationBuffer.h b/physx/source/lowleveldynamics/src/DyCorrelationBuffer.h index 8b61cebfd..407552f05 100644 --- a/physx/source/lowleveldynamics/src/DyCorrelationBuffer.h +++ b/physx/source/lowleveldynamics/src/DyCorrelationBuffer.h @@ -40,13 +40,8 @@ namespace physx { - -struct PxcNpWorkUnit; -struct PxsMaterialInfo; - namespace Dy { - struct CorrelationBuffer { static const PxU32 MAX_FRICTION_PATCHES = 32; @@ -54,20 +49,24 @@ struct CorrelationBuffer struct ContactPatchData { - PxU16 start; - PxU16 next; - PxU8 flags; - PxU8 count; - PxReal staticFriction, dynamicFriction, restitution; - PxBounds3 patchBounds; + PxBounds3 patchBounds; + PxU32 boundsPadding; + + PxReal staticFriction; + PxReal dynamicFriction; + PxReal restitution; + PxU16 start; + PxU16 next; + PxU8 flags; + PxU8 count; }; // we can have as many contact patches as contacts, unfortunately - ContactPatchData contactPatches[PxContactBuffer::MAX_CONTACTS]; + ContactPatchData PX_ALIGN(16, contactPatches[PxContactBuffer::MAX_CONTACTS]); - FrictionPatch PX_ALIGN(16, frictionPatches[MAX_FRICTION_PATCHES]); + FrictionPatch PX_ALIGN(16, frictionPatches[MAX_FRICTION_PATCHES]); PxVec3 PX_ALIGN(16, frictionPatchWorldNormal[MAX_FRICTION_PATCHES]); - PxBounds3 patchBounds[MAX_FRICTION_PATCHES]; + PxBounds3 patchBounds[MAX_FRICTION_PATCHES]; PxU32 frictionPatchContactCounts[MAX_FRICTION_PATCHES]; PxU32 correlationListHeads[MAX_FRICTION_PATCHES+1]; @@ -76,8 +75,7 @@ struct CorrelationBuffer // targets have been set. PxU16 contactID[MAX_FRICTION_PATCHES][2]; - PxU32 contactPatchCount, frictionPatchCount; - + PxU32 contactPatchCount, frictionPatchCount; }; bool createContactPatches(CorrelationBuffer& fb, const PxContactPoint* cb, PxU32 contactCount, PxReal normalTolerance); diff --git a/physx/source/lowleveldynamics/src/DyDynamics.cpp b/physx/source/lowleveldynamics/src/DyDynamics.cpp index 34515c73d..48fbb6997 100644 --- a/physx/source/lowleveldynamics/src/DyDynamics.cpp +++ b/physx/source/lowleveldynamics/src/DyDynamics.cpp @@ -61,7 +61,8 @@ #include "PxvSimStats.h" #include "PxsContactManagerState.h" #include "DyContactPrepShared.h" - +#include "DySleep.h" + //KS - used to turn on/off batched SIMD constraints. #define DY_BATCH_CONSTRAINTS 1 //KS - used to specifically turn on/off batches 1D SIMD constraints. @@ -71,7 +72,6 @@ namespace physx { namespace Dy { - struct SolverIslandObjects { PxsRigidBody** bodies; @@ -98,43 +98,14 @@ struct SolverIslandObjects } }; -Context* createDynamicsContext( PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, +Context* createDynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager, IG::SimpleIslandManager* islandManager, PxU64 contextID, - const bool enableStabilization, const bool useEnhancedDeterminism, - const PxReal maxBiasCoefficient, const bool frictionEveryIteration, const PxReal lengthScale - ) -{ - return DynamicsContext::create(memBlockPool, scratchAllocator, taskPool, simStats, taskManager, allocatorCallback, materialManager, islandManager, - contextID, enableStabilization, useEnhancedDeterminism, maxBiasCoefficient, frictionEveryIteration, lengthScale); -} - -// PT: TODO: consider removing this function. We already have "createDynamicsContext". -DynamicsContext* DynamicsContext::create( PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocatorCallback, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal maxBiasCoefficient, - const bool frictionEveryIteration, - const PxReal lengthScale - ) + bool enableStabilization, bool useEnhancedDeterminism, + PxReal maxBiasCoefficient, bool frictionEveryIteration, PxReal lengthScale) { - // PT: TODO: inherit from UserAllocated, remove placement new - DynamicsContext* dc = reinterpret_cast(PX_ALLOC(sizeof(DynamicsContext), "DynamicsContext")); - if(dc) - { - PX_PLACEMENT_NEW(dc, DynamicsContext(memBlockPool, scratchAllocator, taskPool, simStats, taskManager, allocatorCallback, materialManager, islandManager, contextID, - enableStabilization, useEnhancedDeterminism, maxBiasCoefficient, frictionEveryIteration, lengthScale)); - } - return dc; + return PX_NEW(DynamicsContext)( memBlockPool, scratchAllocator, taskPool, simStats, taskManager, allocatorCallback, materialManager, islandManager, contextID, + enableStabilization, useEnhancedDeterminism, maxBiasCoefficient, frictionEveryIteration, lengthScale); } void DynamicsContext::destroy() @@ -155,10 +126,8 @@ void DynamicsContext::resetThreadContexts() } } - // =========================== Basic methods - DynamicsContext::DynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, @@ -168,19 +137,18 @@ DynamicsContext::DynamicsContext( PxcNpMemBlockPool* memBlockPool, PxsMaterialManager* materialManager, IG::SimpleIslandManager* islandManager, PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal maxBiasCoefficient, - const bool frictionEveryIteration, - const PxReal lengthScale - ) : - Dy::Context (islandManager, allocatorCallback, simStats, enableStabilization, useEnhancedDeterminism, maxBiasCoefficient, lengthScale), + bool enableStabilization, + bool useEnhancedDeterminism, + PxReal maxBiasCoefficient, + bool frictionEveryIteration, + PxReal lengthScale) : + Dy::Context (islandManager, allocatorCallback, simStats, enableStabilization, useEnhancedDeterminism, maxBiasCoefficient, lengthScale, contextID), + // PT: TODO: would make sense to move all the following members to the base class but include paths get in the way atm mThreadContextPool (memBlockPool), mMaterialManager (materialManager), mScratchAllocator (scratchAllocator), mTaskPool (taskPool), - mTaskManager (taskManager), - mContextID (contextID) + mTaskManager (taskManager) { createThresholdStream(*allocatorCallback); createForceChangeThresholdStream(*allocatorCallback); @@ -188,6 +156,7 @@ DynamicsContext::DynamicsContext( PxcNpMemBlockPool* memBlockPool, mExceededForceThresholdStream[1] = PX_NEW(ThresholdStream)(*allocatorCallback); mThresholdStreamOut = 0; mCurrentIndex = 0; + mWorldSolverBody.linearVelocity = PxVec3(0); mWorldSolverBody.angularState = PxVec3(0); mWorldSolverBodyData.invMass = 0; @@ -231,7 +200,7 @@ void DynamicsContext::addThreadStats(const ThreadContext::ThreadSimStats& stats) // =========================== Solve methods! -void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, const IG::IslandSim& islandSim, const PxsIndexedInteraction& constraint, const PxU32 solverBodyOffset) +void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, const IG::IslandSim& islandSim, const PxsIndexedInteraction& constraint, PxU32 solverBodyOffset) { PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eBODY == 0); PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eKINEMATIC == 1); @@ -278,8 +247,7 @@ void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, const IG: } } -void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeIndex edgeIndex, const IG::SimpleIslandManager& islandManager, - PxU32* bodyRemap, const PxU32 solverBodyOffset) +void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeIndex edgeIndex, const IG::SimpleIslandManager& islandManager, PxU32* bodyRemap, PxU32 solverBodyOffset) { PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eBODY == 0); PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eKINEMATIC == 1); @@ -374,21 +342,19 @@ class PxsPreIntegrateTask : public Cm::Task PxsBodyCore*const* bodyArray, PxsRigidBody*const* originalBodyArray, PxU32 const* nodeIndexArray, - PxSolverBody* solverBodies, PxSolverBodyData* solverBodyDataPool, PxF32 dt, PxU32 numBodies, volatile PxU32* maxSolverPositionIterations, volatile PxU32* maxSolverVelocityIterations, - const PxU32 startIndex, - const PxU32 numToIntegrate, + PxU32 startIndex, + PxU32 numToIntegrate, const PxVec3& gravity) : Cm::Task (context.getContextId()), mContext (context), mBodyArray (bodyArray), mOriginalBodyArray (originalBodyArray), mNodeIndexArray (nodeIndexArray), - mSolverBodies (solverBodies), mSolverBodyDataPool (solverBodyDataPool), mDt (dt), mNumBodies (numBodies), @@ -422,15 +388,13 @@ class PxsPreIntegrateTask : public Cm::Task PxVec3 mGravity; }; - - class PxsParallelSolverTask : public Cm::Task { PxsParallelSolverTask& operator=(PxsParallelSolverTask&); public: - PxsParallelSolverTask(SolverIslandParams& params, DynamicsContext& context, PxFrictionType::Enum frictionType, IG::IslandSim& islandSim) - : Cm::Task(context.getContextId()), mParams(params), mContext(context), mFrictionType(frictionType), mIslandSim(islandSim) + PxsParallelSolverTask(SolverIslandParams& params, DynamicsContext& context, IG::IslandSim& islandSim) + : Cm::Task(context.getContextId()), mParams(params), mContext(context), mIslandSim(islandSim) { } @@ -446,7 +410,6 @@ class PxsParallelSolverTask : public Cm::Task SolverIslandParams& mParams; DynamicsContext& mContext; - PxFrictionType::Enum mFrictionType; IG::IslandSim& mIslandSim; }; @@ -460,7 +423,7 @@ class PxsSolverConstraintPostProcessTask : public Cm::Task PxsSolverConstraintPostProcessTask(DynamicsContext& context, ThreadContext& threadContext, const SolverIslandObjects& objects, - const PxU32 solverBodyOffset, + PxU32 solverBodyOffset, PxU32 startIndex, PxU32 stride, PxsMaterialManager* materialManager, @@ -600,9 +563,9 @@ class PxsSolverConstraintPostProcessTask : public Cm::Task DynamicsContext& mContext; ThreadContext& mThreadContext; const SolverIslandObjects mObjects; - PxU32 mSolverBodyOffset; - PxU32 mStartIndex; - PxU32 mStride; + const PxU32 mSolverBodyOffset; + const PxU32 mStartIndex; + const PxU32 mStride; PxsMaterialManager* mMaterialManager; PxsContactManagerOutputIterator& mOutputs; }; @@ -834,8 +797,8 @@ class PxsSolverStartTask : public Cm::Task PxsSolverStartTask(DynamicsContext& context, IslandContext& islandContext, const SolverIslandObjects& objects, - const PxU32 solverBodyOffset, - const PxU32 kinematicCount, + PxU32 solverBodyOffset, + PxU32 kinematicCount, IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, PxsMaterialManager* materialManager, @@ -915,7 +878,6 @@ class PxsSolverStartTask : public Cm::Task while (currentIndex.isValid()) { - const IG::Node& node = islandSim.getNode(currentIndex); if (node.getNodeType() == IG::Node::eARTICULATION_TYPE) @@ -935,9 +897,7 @@ class PxsSolverStartTask : public Cm::Task //Bodies can come in a slightly jumbled order from islandGen. It's deterministic if the scene is //identical but can vary if there are additional bodies in the scene in a different island. if (mEnhancedDeterminism) - { PxSort(nodeIndexArray, bodyIndex); - } for (PxU32 a = 0; a < bodyIndex; ++a) { @@ -974,7 +934,6 @@ class PxsSolverStartTask : public Cm::Task PX_ASSERT(!nodeIndex1.isStaticBody()); { - const IG::Node& node1 = islandSim.getNode(nodeIndex1); //Is it an articulation or not??? @@ -998,7 +957,6 @@ class PxsSolverStartTask : public Cm::Task } PX_ASSERT(indexedManager.solverBody0 < (mIslandContext.mCounts.bodies + mContext.mKinematicCount + 1)); } - } if(nodeIndex2.isStaticBody()) @@ -1031,16 +989,13 @@ class PxsSolverStartTask : public Cm::Task PX_ASSERT(indexedManager.solverBody1 < (mIslandContext.mCounts.bodies + mContext.mKinematicCount + 1)); } } - } contactEdgeIndex = edge.mNextIslandEdge; } } if (mEnhancedDeterminism) - { PxSort(indexedManagers, currentContactIndex, EnhancedSortPredicate()); - } mIslandContext.mCounts.contactManagers = currentContactIndex; } @@ -1117,7 +1072,6 @@ class PxsSolverStartTask : public Cm::Task contactDescPtr++; edgeId = edge.mNextIslandEdge; } - } #if 1 @@ -1296,7 +1250,7 @@ class PxsSolverStartTask : public Cm::Task || gDisableConstraintWelding ) //If this is the first thing and no contacts...then we skip { - PxU32 stride = a - startIndex; + const PxU32 stride = a - startIndex; if(contactCount > 0) { if(stride > 1) @@ -1334,7 +1288,7 @@ class PxsSolverStartTask : public Cm::Task contactCount += output.nbContacts; } - PxU32 stride = mIslandContext.mCounts.contactManagers - startIndex; + const PxU32 stride = mIslandContext.mCounts.contactManagers - startIndex; if(contactCount > 0) { if(stride > 1) @@ -1398,7 +1352,7 @@ class PxsSolverStartTask : public Cm::Task PxU32* mBodyRemapTable; PxsMaterialManager* mMaterialManager; PxsContactManagerOutputIterator& mOutputs; - bool mEnhancedDeterminism; + const bool mEnhancedDeterminism; }; class PxsSolverConstraintPartitionTask : public Cm::Task @@ -1406,15 +1360,12 @@ class PxsSolverConstraintPartitionTask : public Cm::Task PxsSolverConstraintPartitionTask& operator=(const PxsSolverConstraintPartitionTask&); public: - PxsSolverConstraintPartitionTask(DynamicsContext& context, - IslandContext& islandContext, - const SolverIslandObjects& objects, - const PxU32 solverBodyOffset, bool enhancedDeterminism) : - Cm::Task(context.getContextId()), - mContext(context), - mIslandContext(islandContext), - mObjects(objects), - mSolverBodyOffset(solverBodyOffset), + PxsSolverConstraintPartitionTask(DynamicsContext& context, IslandContext& islandContext, const SolverIslandObjects& objects, PxU32 solverBodyOffset, bool enhancedDeterminism) : + Cm::Task (context.getContextId()), + mContext (context), + mIslandContext (islandContext), + mObjects (objects), + mSolverBodyOffset (solverBodyOffset), mEnhancedDeterminism(enhancedDeterminism) {} @@ -1424,10 +1375,10 @@ class PxsSolverConstraintPartitionTask : public Cm::Task ThreadContext& mThreadContext = *mIslandContext.mThreadContext; //Compact articulation pairs... - ArticulationSolverDesc* artics = mThreadContext.getArticulations().begin(); + const ArticulationSolverDesc* artics = mThreadContext.getArticulations().begin(); - PxSolverConstraintDesc* descBegin = mThreadContext.contactConstraintDescArray; - PxU32 descCount = mThreadContext.contactDescArraySize; + const PxSolverConstraintDesc* descBegin = mThreadContext.contactConstraintDescArray; + const PxU32 descCount = mThreadContext.contactDescArraySize; PxSolverBody* solverBodies = mContext.mSolverBodyPool.begin() + mSolverBodyOffset; @@ -1456,10 +1407,10 @@ class PxsSolverConstraintPartitionTask : public Cm::Task args.mNumDifferentBodyConstraints = args.mNumSelfConstraints = args.mNumStaticConstraints = 0; args.mConstraintsPerPartition = &mThreadContext.mConstraintsPerPartition; args.mNumOverflowConstraints = 0; - args.mBitField = &mThreadContext.mPartitionNormalizationBitmap; - args.enhancedDeterminism = mEnhancedDeterminism; - args.forceStaticConstraintsToSolver = mContext.getFrictionType() != PxFrictionType::ePATCH; - args.maxPartitions = PX_MAX_U32; + //args.mBitField = &mThreadContext.mPartitionNormalizationBitmap; // PT: removed, unused + args.mEnhancedDeterminism = mEnhancedDeterminism; + args.mForceStaticConstraintsToSolver = mContext.getFrictionType() != PxFrictionType::ePATCH; + args.mMaxPartitions = PX_MAX_U32; mThreadContext.mMaxPartitions = partitionContactConstraints(args); mThreadContext.mNumDifferentBodyConstraints = args.mNumDifferentBodyConstraints; @@ -1480,8 +1431,8 @@ class PxsSolverConstraintPartitionTask : public Cm::Task DynamicsContext& mContext; IslandContext& mIslandContext; const SolverIslandObjects mObjects; - PxU32 mSolverBodyOffset; - bool mEnhancedDeterminism; + const PxU32 mSolverBodyOffset; + const bool mEnhancedDeterminism; }; class PxsSolverSetupSolveTask : public Cm::Task @@ -1489,18 +1440,13 @@ class PxsSolverSetupSolveTask : public Cm::Task PxsSolverSetupSolveTask& operator=(const PxsSolverSetupSolveTask&); public: - PxsSolverSetupSolveTask( - DynamicsContext& context, - IslandContext& islandContext, - const SolverIslandObjects& objects, - const PxU32 solverBodyOffset, - IG::IslandSim& islandSim) : - Cm::Task(context.getContextId()), - mContext(context), - mIslandContext(islandContext), - mObjects(objects), - mSolverBodyOffset(solverBodyOffset), - mIslandSim(islandSim) + PxsSolverSetupSolveTask(DynamicsContext& context, IslandContext& islandContext, const SolverIslandObjects& objects, PxU32 solverBodyOffset, IG::IslandSim& islandSim) : + Cm::Task (context.getContextId()), + mContext (context), + mIslandContext (islandContext), + mObjects (objects), + mSolverBodyOffset (solverBodyOffset), + mIslandSim (islandSim) {} virtual void runInternal() @@ -1633,7 +1579,7 @@ class PxsSolverSetupSolveTask : public Cm::Task PX_ASSERT(desc.constraint); SolverContactCoulombHeader* header = reinterpret_cast(desc.constraint); PxU32 frictionOffset = header->frictionOffset; - PxU8* PX_RESTRICT constraint = reinterpret_cast(header) + frictionOffset; + PxU8* PX_RESTRICT constraint = reinterpret_cast(header) + frictionOffset; const PxU32 origLength = getConstraintLength(desc); const PxU32 length = (origLength - frictionOffset); @@ -1662,7 +1608,7 @@ class PxsSolverSetupSolveTask : public Cm::Task PX_ASSERT(contactDescBegin[_header.startIndex].constraint); SolverContactCoulombHeader4* head = reinterpret_cast(contactDescBegin[_header.startIndex].constraint); PxU32 frictionOffset = head->frictionOffset; - PxU8* PX_RESTRICT constraint = reinterpret_cast(head) + frictionOffset; + PxU8* PX_RESTRICT constraint = reinterpret_cast(head) + frictionOffset; const PxU32 origLength = getConstraintLength(contactDescBegin[_header.startIndex]); const PxU32 length = (origLength - frictionOffset); PxU8 type = *constraint; @@ -1728,11 +1674,11 @@ class PxsSolverSetupSolveTask : public Cm::Task params.articulationListSize = mThreadContext.getArticulations().size(); params.constraintList = contactDescs; params.constraintIndex = 0; - params.constraintIndex2 = 0; + params.constraintIndexCompleted = 0; params.bodyListIndex = 0; - params.bodyListIndex2 = 0; + params.bodyListIndexCompleted = 0; params.articSolveIndex = 0; - params.articSolveIndex2 = 0; + params.articSolveIndexCompleted = 0; params.bodyIntegrationListIndex = 0; params.thresholdStream = mContext.getThresholdStream().begin(); params.thresholdStreamLength = mContext.getThresholdStream().size(); @@ -1771,7 +1717,7 @@ class PxsSolverSetupSolveTask : public Cm::Task { void* tsk = mContext.getTaskPool().allocate(sizeof(PxsParallelSolverTask)); PxsParallelSolverTask* pTask = PX_PLACEMENT_NEW(tsk, PxsParallelSolverTask)( - params, mContext, mContext.getFrictionType(), mIslandSim); + params, mContext, mIslandSim); //Force to complete before merge task! pTask->setContinuation(mCont); @@ -1805,7 +1751,7 @@ class PxsSolverSetupSolveTask : public Cm::Task params.deltaV = mThreadContext.mDeltaV.begin(); //Only one task - a small island so do a sequential solve (avoid the atomic overheads) - solveVBlock(mContext.mSolverCore[mContext.getFrictionType()], params); + mContext.mSolverCore[mContext.getFrictionType()]->solveV_Blocks(params); const PxU32 bodyCountMin1 = mIslandContext.mCounts.bodies - 1u; PxSolverBodyData* solverBodyData2 = solverBodyDatas + mSolverBodyOffset + 1; @@ -1831,9 +1777,8 @@ class PxsSolverSetupSolveTask : public Cm::Task core.linearVelocity = solverBodyData.linearVelocity; core.angularVelocity = solverBodyData.angularVelocity; - bool hasStaticTouch = mIslandSim.getIslandStaticTouchCount(PxNodeIndex(solverBodyData.nodeIndex)) != 0; - sleepCheck(const_cast(mObjects.bodies[k]), mContext.mDt, mContext.mInvDt, mContext.mEnableStabilization, mThreadContext.motionVelocityArray[k], - hasStaticTouch); + const bool hasStaticTouch = mIslandSim.getIslandStaticTouchCount(PxNodeIndex(solverBodyData.nodeIndex)) != 0; + sleepCheck(const_cast(mObjects.bodies[k]), mContext.mDt, mContext.mEnableStabilization, mThreadContext.motionVelocityArray[k], hasStaticTouch); } for(PxU32 cnt=0;cntsetContinuation(next); next->removeReference(); } -PxBaseTask* createSolverTaskChain(DynamicsContext& dynamicContext, - const SolverIslandObjects& objects, - const PxsIslandIndices& counts, - const PxU32 solverBodyOffset, - IG::SimpleIslandManager& islandManager, - PxU32* bodyRemapTable, PxsMaterialManager* materialManager, PxBaseTask* continuation, - PxsContactManagerOutputIterator& iterator, bool useEnhancedDeterminism) +static void createSolverTaskChain( DynamicsContext& dynamicContext, + const SolverIslandObjects& objects, + const PxsIslandIndices& counts, + PxU32 solverBodyOffset, + IG::SimpleIslandManager& islandManager, + PxU32* bodyRemapTable, PxsMaterialManager* materialManager, PxBaseTask* continuation, + PxsContactManagerOutputIterator& iterator, bool useEnhancedDeterminism) { - Cm::FlushPool& taskPool = dynamicContext.getTaskPool(); - + Cm::FlushPool& taskPool = dynamicContext.getTaskPool(); taskPool.lock(); IslandContext* islandContext = reinterpret_cast(taskPool.allocate(sizeof(IslandContext))); @@ -2026,6 +1961,8 @@ PxBaseTask* createSolverTaskChain(DynamicsContext& dynamicContext, PxsSolverConstraintPartitionTask* partitionConstraintsTask = PX_PLACEMENT_NEW(taskPool.allocateNotThreadSafe(sizeof(PxsSolverConstraintPartitionTask)), PxsSolverConstraintPartitionTask)(dynamicContext, *islandContext, objects, solverBodyOffset, useEnhancedDeterminism); + taskPool.unlock(); + endTask->setContinuation(continuation); // set up task chain in reverse order @@ -2034,11 +1971,11 @@ PxBaseTask* createSolverTaskChain(DynamicsContext& dynamicContext, chainTasks(partitionConstraintsTask, createFinalizeConstraintsTask); chainTasks(startTask, partitionConstraintsTask); - taskPool.unlock(); - - return startTask; + startTask->removeReference(); } +namespace +{ class UpdateContinuationTask : public Cm::Task { DynamicsContext& mContext; @@ -2051,8 +1988,8 @@ class UpdateContinuationTask : public Cm::Task UpdateContinuationTask(DynamicsContext& context, IG::SimpleIslandManager& simpleIslandManager, - PxBaseTask* lostTouchTask, - PxU64 contextID, const PxU32 maxLinks) : Cm::Task(contextID), mContext(context), mSimpleIslandManager(simpleIslandManager), + PxBaseTask* lostTouchTask, PxU64 contextID, PxU32 maxLinks) : + Cm::Task(contextID), mContext(context), mSimpleIslandManager(simpleIslandManager), mLostTouchTask(lostTouchTask), mMaxArticulationLinks(maxLinks) { } @@ -2069,10 +2006,10 @@ class UpdateContinuationTask : public Cm::Task class KinematicCopyTask : public Cm::Task { - const PxNodeIndex* const mKinematicIndices; - const PxU32 mNbKinematics; - const IG::IslandSim& mIslandSim; - PxSolverBodyData* mBodyData; + const PxNodeIndex* const mKinematicIndices; + const PxU32 mNbKinematics; + const IG::IslandSim& mIslandSim; + PxSolverBodyData* mBodyData; PX_NOCOPY(KinematicCopyTask) @@ -2081,8 +2018,8 @@ class KinematicCopyTask : public Cm::Task static const PxU32 NbKinematicsPerTask = 1024; KinematicCopyTask(const PxNodeIndex* const kinematicIndices, - const PxU32 nbKinematics, const IG::IslandSim& islandSim, - PxSolverBodyData* datas, PxU64 contextID) : Cm::Task(contextID), + PxU32 nbKinematics, const IG::IslandSim& islandSim, + PxSolverBodyData* datas, PxU64 contextID) : Cm::Task(contextID), mKinematicIndices(kinematicIndices), mNbKinematics(nbKinematics), mIslandSim(islandSim), mBodyData(datas) { @@ -2103,15 +2040,14 @@ class KinematicCopyTask : public Cm::Task } } }; +} void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, - PxvNphaseImplementationContext* nphase, const PxU32 /*maxPatches*/, const PxU32 maxArticulationLinks, - const PxReal dt, const PxVec3& gravity, PxBitMapPinned& /*changedHandleMap*/) + PxvNphaseImplementationContext* nphase, PxU32 /*maxPatches*/, PxU32 maxArticulationLinks, + PxReal dt, const PxVec3& gravity, PxBitMapPinned& /*changedHandleMap*/) { PX_PROFILE_ZONE("Dynamics.solverQueueTasks", mContextID); - PX_UNUSED(simpleIslandManager); - mOutputIterator = nphase->getContactManagerOutputs(); mDt = dt; @@ -2129,9 +2065,7 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas { PxsContactManager* cm = simpleIslandManager.getContactManager(activatingEdges[a]); if (cm) - { cm->getWorkUnit().frictionPatchCount = 0; //KS - zero the friction patch count on any activating edges - } } #if PX_ENABLE_SIM_STATS @@ -2156,10 +2090,8 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas resetThreadContexts(); //If there is no work to do then we can do nothing at all. - if (0 == islandCount) - { + if(!islandCount) return; - } //Block to make sure it doesn't run before stage2 of update! lostTouchTask->addReference(); @@ -2171,8 +2103,8 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas //KS - test that world solver body's velocities are finite and 0, then set it to 0. //Technically, the velocity should always be 0 but can be stomped if a NAN creeps into the simulation. - PX_ASSERT(mWorldSolverBody.linearVelocity == PxVec3(0.f)); - PX_ASSERT(mWorldSolverBody.angularState == PxVec3(0.f)); + PX_ASSERT(mWorldSolverBody.linearVelocity == PxVec3(0.0f)); + PX_ASSERT(mWorldSolverBody.angularState == PxVec3(0.0f)); PX_ASSERT(mWorldSolverBody.linearVelocity.isFinite()); PX_ASSERT(mWorldSolverBody.angularState.isFinite()); @@ -2186,7 +2118,6 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas const PxU32 numArtics = islandSim.getNbActiveNodes(IG::Node::eARTICULATION_TYPE); - { if (kinematicCount + bodyCount > mSolverBodyPool.capacity()) { @@ -2210,6 +2141,7 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas mSolverBodyDataPool[0] = mWorldSolverBodyData; + if(kinematicCount) { PX_PROFILE_ZONE("Dynamics.updateKinematics", mContextID); PxMemZero(mSolverBodyPool.begin(), kinematicCount * sizeof(PxSolverBody)); @@ -2229,12 +2161,12 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas //Resize arrays of solver constraints... - PxU32 numArticulationConstraints = numArtics* maxArticulationLinks; //Just allocate enough memory to fit worst-case maximum size articulations... + const PxU32 numArticulationConstraints = numArtics* maxArticulationLinks; //Just allocate enough memory to fit worst-case maximum size articulations... const PxU32 nbActiveContactManagers = islandSim.getNbActiveEdges(IG::Edge::eCONTACT_MANAGER); const PxU32 nbActiveConstraints = islandSim.getNbActiveEdges(IG::Edge::eCONSTRAINT); - PxU32 totalConstraintCount = nbActiveConstraints + nbActiveContactManagers + numArticulationConstraints; + const PxU32 totalConstraintCount = nbActiveConstraints + nbActiveContactManagers + numArticulationConstraints; mSolverConstraintDescPool.forceSize_Unsafe(0); mSolverConstraintDescPool.reserve((totalConstraintCount + 63) & (~63)); @@ -2286,7 +2218,7 @@ void DynamicsContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBas task->removeReference(); } -void DynamicsContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* /*continuation*/, PxBaseTask* lostTouchTask, const PxU32 maxLinks) +void DynamicsContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* /*continuation*/, PxBaseTask* lostTouchTask, PxU32 maxLinks) { const IG::IslandSim& islandSim = simpleIslandManager.getAccurateIslandSim(); @@ -2299,7 +2231,7 @@ void DynamicsContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandM PxU32 minimumConstraintCount = 1; //create force threshold tasks to produce force change events - PxsForceThresholdTask* forceThresholdTask = PX_PLACEMENT_NEW(getTaskPool().allocate(sizeof(PxsForceThresholdTask)), PxsForceThresholdTask)(*this); + PxsForceThresholdTask* forceThresholdTask = PX_PLACEMENT_NEW(getTaskPool().allocate(sizeof(PxsForceThresholdTask)), PxsForceThresholdTask)(*this); forceThresholdTask->setContinuation(lostTouchTask); const IG::IslandId*const islandIds = islandSim.getActiveIslands(); @@ -2333,6 +2265,8 @@ void DynamicsContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandM PxU32 nbConstraints = 0; PxU32 nbContactManagers =0; + // islandSim.checkInternalConsistency(); + //KS - logic is a bit funky here. We will keep rolling the island together provided currentIsland < islandCount AND either we haven't exceeded the max number of bodies or we have //zero constraints AND we haven't exceeded articulation batch counts (it's still currently beneficial to keep articulations in separate islands but this is only temporary). while((currentIsland < islandCount && (nbBodies < solverBatchMax || constraintCount < minimumConstraintCount)) && @@ -2360,9 +2294,9 @@ void DynamicsContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandM counts.contactManagers = nbContactManagers; if(counts.articulations + counts.bodies > 0) { - PxBaseTask* task = createSolverTaskChain(*this, objectStarts, counts, - mKinematicCount + currentBodyIndex, simpleIslandManager, mSolverBodyRemapTable.begin(), mMaterialManager, forceThresholdTask, mOutputIterator, mUseEnhancedDeterminism); - task->removeReference(); + createSolverTaskChain(*this, objectStarts, counts, + mKinematicCount + currentBodyIndex, simpleIslandManager, mSolverBodyRemapTable.begin(), mMaterialManager, + forceThresholdTask, mOutputIterator, mUseEnhancedDeterminism); } currentBodyIndex += nbBodies; @@ -2376,11 +2310,6 @@ void DynamicsContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandM forceThresholdTask->removeReference(); } -void DynamicsContext::updateBodyCore(PxBaseTask* continuation) -{ - PX_UNUSED(continuation); -} - void DynamicsContext::mergeResults() { PX_PROFILE_ZONE("Dynamics.solverMergeResults", mContextID); @@ -2403,16 +2332,15 @@ void DynamicsContext::mergeResults() } static void preIntegrationParallel( - const PxF32 dt, - PxsBodyCore*const* bodyArray, // INOUT: core body attributes - PxsRigidBody*const* originalBodyArray, // IN: original bodies (LEGACY - DON'T deref the ptrs!!) - PxU32 const* nodeIndexArray, // IN: island node index - PxU32 bodyCount, // IN: body count - PxSolverBody* solverBodyPool, // IN: solver body pool (space preallocated) - PxSolverBodyData* solverBodyDataPool, // IN: solver body data pool (space preallocated) - volatile PxU32* maxSolverPositionIterations, - volatile PxU32* maxSolverVelocityIterations, - const PxVec3& gravity) + PxF32 dt, + PxsBodyCore*const* bodyArray, // INOUT: core body attributes + PxsRigidBody*const* originalBodyArray, // IN: original bodies (LEGACY - DON'T deref the ptrs!!) + PxU32 const* nodeIndexArray, // IN: island node index + PxU32 bodyCount, // IN: body count + PxSolverBodyData* solverBodyDataPool, // IN: solver body data pool (space preallocated) + volatile PxU32* maxSolverPositionIterations, + volatile PxU32* maxSolverVelocityIterations, + const PxVec3& gravity) { PxU32 localMaxPosIter = 0; PxU32 localMaxVelIter = 0; @@ -2428,7 +2356,7 @@ static void preIntegrationParallel( PxsBodyCore& core = *bodyArray[i]; const PxsRigidBody& rBody = *originalBodyArray[i]; - PxU16 iterWord = core.solverIterationCounts; + const PxU16 iterWord = core.solverIterationCounts; localMaxPosIter = PxMax(PxU32(iterWord & 0xff), localMaxPosIter); localMaxVelIter = PxMax(PxU32(iterWord >> 8), localMaxVelIter); @@ -2438,9 +2366,6 @@ static void preIntegrationParallel( copyToSolverBodyData(core.linearVelocity, core.angularVelocity, core.inverseMass, core.inverseInertia, core.body2World, core.maxPenBias, core.maxContactImpulse, nodeIndexArray[i], core.contactReportThreshold, solverBodyDataPool[i + 1], core.lockFlags, dt, core.mFlags & PxRigidBodyFlag::eENABLE_GYROSCOPIC_FORCES); - solverBodyPool[i].solverProgress = 0; - solverBodyPool[i].maxSolverNormalProgress = 0; - solverBodyPool[i].maxSolverFrictionProgress = 0; } const PxU32 i = bodyCount - 1; PxsBodyCore& core = *bodyArray[i]; @@ -2455,9 +2380,6 @@ static void preIntegrationParallel( copyToSolverBodyData(core.linearVelocity, core.angularVelocity, core.inverseMass, core.inverseInertia, core.body2World, core.maxPenBias, core.maxContactImpulse, nodeIndexArray[i], core.contactReportThreshold, solverBodyDataPool[i + 1], core.lockFlags, dt, core.mFlags & PxRigidBodyFlag::eENABLE_GYROSCOPIC_FORCES); - solverBodyPool[i].solverProgress = 0; - solverBodyPool[i].maxSolverNormalProgress = 0; - solverBodyPool[i].maxSolverFrictionProgress = 0; physx::PxAtomicMax(reinterpret_cast(maxSolverPositionIterations), PxI32(localMaxPosIter)); physx::PxAtomicMax(reinterpret_cast(maxSolverVelocityIterations), PxI32(localMaxVelIter)); @@ -2465,27 +2387,24 @@ static void preIntegrationParallel( void PxsPreIntegrateTask::runInternal() { - { - PX_PROFILE_ZONE("PreIntegration", mContext.getContextId()); - preIntegrationParallel(mDt, mBodyArray + mStartIndex, mOriginalBodyArray + mStartIndex, mNodeIndexArray + mStartIndex, mNumToIntegrate, - mSolverBodies + mStartIndex, mSolverBodyDataPool + mStartIndex, - mMaxSolverPositionIterations, mMaxSolverVelocityIterations, mGravity); - } + PX_PROFILE_ZONE("PreIntegration", mContext.getContextId()); + preIntegrationParallel(mDt, mBodyArray + mStartIndex, mOriginalBodyArray + mStartIndex, mNodeIndexArray + mStartIndex, mNumToIntegrate, + mSolverBodyDataPool + mStartIndex, mMaxSolverPositionIterations, mMaxSolverVelocityIterations, mGravity); } void DynamicsContext::preIntegrationParallel( - const PxF32 dt, - PxsBodyCore*const* bodyArray, // INOUT: core body attributes - PxsRigidBody*const* originalBodyArray, // IN: original bodies (LEGACY - DON'T deref the ptrs!!) - PxU32 const* nodeIndexArray, // IN: island node index - PxU32 bodyCount, // IN: body count - PxSolverBody* solverBodyPool, // IN: solver body pool (space preallocated) - PxSolverBodyData* solverBodyDataPool, // IN: solver body data pool (space preallocated) - Cm::SpatialVector* /*motionVelocityArray*/, // OUT: motion velocities - PxU32& maxSolverPositionIterations, - PxU32& maxSolverVelocityIterations, - PxBaseTask& task - ) + PxF32 dt, + PxsBodyCore*const* bodyArray, // INOUT: core body attributes + PxsRigidBody*const* originalBodyArray, // IN: original bodies (LEGACY - DON'T deref the ptrs!!) + PxU32 const* nodeIndexArray, // IN: island node index + PxU32 bodyCount, // IN: body count + PxSolverBody* solverBodyPool, // IN: solver body pool (space preallocated) + PxSolverBodyData* solverBodyDataPool, // IN: solver body data pool (space preallocated) + Cm::SpatialVector* /*motionVelocityArray*/, // OUT: motion velocities + PxU32& maxSolverPositionIterations, + PxU32& maxSolverVelocityIterations, + PxBaseTask& task + ) { //TODO - make this based on some variables so we can try different configurations const PxU32 IntegrationPerThread = 256; @@ -2502,7 +2421,7 @@ void DynamicsContext::preIntegrationParallel( PxU32 startIndex = (i+a)*IntegrationPerThread; PxU32 nbToIntegrate = PxMin((bodyCount-startIndex), IntegrationPerThread); PxsPreIntegrateTask* pTask = PX_PLACEMENT_NEW(&tasks[a], PxsPreIntegrateTask)(*this, bodyArray, - originalBodyArray, nodeIndexArray, solverBodyPool, solverBodyDataPool, dt, bodyCount, + originalBodyArray, nodeIndexArray, solverBodyDataPool, dt, bodyCount, &maxSolverPositionIterations, &maxSolverVelocityIterations, startIndex, nbToIntegrate, mGravity); @@ -2537,14 +2456,7 @@ void solveParallel(SOLVER_PARALLEL_METHOD_ARGS) void DynamicsContext::solveParallel(SolverIslandParams& params, IG::IslandSim& islandSim, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV) { - PxI32 targetCount = mSolverCore[mFrictionType]->solveVParallelAndWriteBack(params, Z, deltaV); - - PxI32* solveCount = ¶ms.constraintIndex2; - - //PxI32 targetCount = (PxI32)(params.numConstraintHeaders * (params.velocityIterations + params.positionIterations)); - - WAIT_FOR_PROGRESS_NO_TIMER(solveCount, targetCount); - + mSolverCore[mFrictionType]->solveVParallelAndWriteBack(params, Z, deltaV); integrateCoreParallel(params, deltaV, islandSim); } @@ -2616,19 +2528,16 @@ void DynamicsContext::integrateCoreParallel(SolverIslandParams& params, Cm::Spat PxsRigidBody& rBody = *rigidBodies[index]; PxsBodyCore& core = rBody.getCore(); - - integrateCore(motionVelocityArray[index].linear, motionVelocityArray[index].angular, solverBodies[index], data, mDt, core.lockFlags); - - + rBody.mLastTransform = core.body2World; core.body2World = data.body2World; core.linearVelocity = data.linearVelocity; core.angularVelocity = data.angularVelocity; - bool hasStaticTouch = islandSim.getIslandStaticTouchCount(PxNodeIndex(data.nodeIndex)) != 0; - sleepCheck(rigidBodies[index], mDt, mInvDt, mEnableStabilization, motionVelocityArray[index], hasStaticTouch); + const bool hasStaticTouch = islandSim.getIslandStaticTouchCount(PxNodeIndex(data.nodeIndex)) != 0; + sleepCheck(rigidBodies[index], mDt, mEnableStabilization, motionVelocityArray[index], hasStaticTouch); ++numIntegrated; } @@ -2672,7 +2581,7 @@ static PxU32 createFinalizeContacts_Parallel(PxSolverBodyData* solverBodyData, T Cm::SpatialVectorF* Z = threadContext->mZVector.begin(); - PxTransform idt(PxIdentity); + const PxTransform idt(PxIdentity); BlockAllocator blockAllocator(mThreadContext.mConstraintBlockManager, threadContext->mConstraintBlockStream, threadContext->mFrictionPatchStreamPair, threadContext->mConstraintSize); @@ -2764,7 +2673,6 @@ static PxU32 createFinalizeContacts_Parallel(PxSolverBodyData* solverBodyData, T frictionOffsetThreshold, correlationDist, blockAllocator); - } if(SolverConstraintPrepState::eSUCCESS != state) #endif @@ -2793,7 +2701,6 @@ static PxU32 createFinalizeContacts_Parallel(PxSolverBodyData* solverBodyData, T unit.frictionDataPtr = blockDescs[i].frictionPtr; unit.frictionPatchCount = blockDescs[i].frictionCount; axisConstraintCount += blockDescs[i].axisConstraintCount; - } } else if(contactDescPtr[header.startIndex].constraintLengthOver16 == DY_SC_TYPE_RB_1D) @@ -2801,8 +2708,6 @@ static PxU32 createFinalizeContacts_Parallel(PxSolverBodyData* solverBodyData, T SolverConstraintShaderPrepDesc shaderDescs[4]; PxSolverConstraintPrepDesc descs[4]; - const PxTransform id(PxIdentity); - for (PxU32 i = 0; i < header.stride; ++i) { PxSolverConstraintDesc& desc = contactDescPtr[header.startIndex + i]; @@ -2814,8 +2719,8 @@ static PxU32 createFinalizeContacts_Parallel(PxSolverBodyData* solverBodyData, T const PxConstraintSolverPrep solverPrep = constraint->solverPrep; const void* constantBlock = constraint->constantBlock; const PxU32 constantBlockByteSize = constraint->constantBlockSize; - const PxTransform& pose0 = (constraint->body0 ? constraint->body0->getPose() : id); - const PxTransform& pose1 = (constraint->body1 ? constraint->body1->getPose() : id); + const PxTransform& pose0 = (constraint->body0 ? constraint->body0->getPose() : idt); + const PxTransform& pose1 = (constraint->body1 ? constraint->body1->getPose() : idt); const PxSolverBody* sbody0 = desc.bodyA; const PxSolverBody* sbody1 = desc.bodyB; PxSolverBodyData* sbodyData0 = &solverBodyData[desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY ? desc.bodyADataIndex : 0]; diff --git a/physx/source/lowleveldynamics/src/DyDynamics.h b/physx/source/lowleveldynamics/src/DyDynamics.h index 6bde0250f..844f82af5 100644 --- a/physx/source/lowleveldynamics/src/DyDynamics.h +++ b/physx/source/lowleveldynamics/src/DyDynamics.h @@ -30,7 +30,6 @@ #define DY_DYNAMICS_H #include "PxvConfig.h" -#include "CmSpatialVector.h" #include "CmTask.h" #include "CmPool.h" #include "PxcThreadCoherentCache.h" @@ -44,7 +43,6 @@ namespace physx { - namespace Cm { class FlushPool; @@ -53,7 +51,6 @@ namespace Cm namespace IG { class SimpleIslandManager; - struct Edge; } class PxsRigidBody; @@ -73,27 +70,13 @@ namespace Dy { class SolverCore; struct SolverIslandParams; - struct ArticulationSolverDesc; - class Articulation; class DynamicsContext; - - - -#define SOLVER_PARALLEL_METHOD_ARGS \ - DynamicsContext& context, \ - SolverIslandParams& params, \ +#define SOLVER_PARALLEL_METHOD_ARGS \ + DynamicsContext& context, \ + SolverIslandParams& params, \ IG::IslandSim& islandSim -//typedef void (*PxsSolveParallelMethod)(SOLVER_PARALLEL_METHOD_ARGS); -//extern PxsSolveParallelMethod solveParallel[3]; - -void solveParallel(SOLVER_PARALLEL_METHOD_ARGS); -void solveParallelCouloumFriction(SOLVER_PARALLEL_METHOD_ARGS); - - -struct SolverIslandObjects; - /** \brief Solver body pool (array) that enforces 128-byte alignment for base address of array. \note This reduces cache misses on platforms with 128-byte-size cache lines by aligning the start of the array to the beginning of a cache line. @@ -134,7 +117,6 @@ struct IslandContext PxsIslandIndices mCounts; }; - /** \brief Encapsules the data used by the constraint solver. */ @@ -144,137 +126,63 @@ struct IslandContext #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. #endif - class DynamicsContext : public Context { PX_NOCOPY(DynamicsContext) public: - /** - \brief Creates a DynamicsContext associated with a PxsContext - \return A pointer to the newly-created DynamicsContext. - */ - static DynamicsContext* create( PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocator, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal maxBiasCoefficient, - const bool frictionEveryIteration, - const PxReal lengthScale - ); - - /** - \brief Destroys this DynamicsContext - */ - void destroy(); - - /** - \brief Returns the static world solver body - \return The static world solver body. - */ - PX_FORCE_INLINE PxSolverBody& getWorldSolverBody() { return mWorldSolverBody; } - - PX_FORCE_INLINE Cm::FlushPool& getTaskPool() { return mTaskPool; } - - PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; } - - PX_FORCE_INLINE PxvSimStats& getSimStats() { return mSimStats; } - -#if PX_ENABLE_SIM_STATS - void addThreadStats(const ThreadContext::ThreadSimStats& stats); -#else - PX_CATCH_UNDEFINED_ENABLE_SIM_STATS -#endif - - /** - \brief The entry point for the constraint solver. - \param[in] dt The simulation time-step - \param[in] continuation The continuation task for the solver - - This method is called after the island generation has completed. Its main responsibilities are: - (1) Reserving the solver body pools - (2) Initializing the static and kinematic solver bodies, which are shared resources between islands. - (3) Construct the solver task chains for each island - - Each island is solved as an independent solver task chain in parallel. + DynamicsContext(PxcNpMemBlockPool* memBlockPool, + PxcScratchAllocator& scratchAllocator, + Cm::FlushPool& taskPool, + PxvSimStats& simStats, + PxTaskManager* taskManager, + PxVirtualAllocatorCallback* allocator, + PxsMaterialManager* materialManager, + IG::SimpleIslandManager* islandManager, + PxU64 contextID, + bool enableStabilization, + bool useEnhancedDeterminism, + PxReal maxBiasCoefficient, + bool frictionEveryIteration, + PxReal lengthScale + ); - */ + virtual ~DynamicsContext(); + // Context + virtual void destroy() PX_OVERRIDE; virtual void update(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, - PxvNphaseImplementationContext* nPhase, const PxU32 maxPatchesPerCM, const PxU32 maxArticulationLinks, const PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap); - - - void updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, const PxU32 maxLinks); - - virtual void processLostPatches(IG::SimpleIslandManager& /*simpleIslandManager*/, PxsContactManager** /*lostPatchManagers*/, PxU32 /*nbLostPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/){} - virtual void processFoundPatches(IG::SimpleIslandManager& /*simpleIslandManager*/, PxsContactManager** /*foundPatchManagers*/, PxU32 /*nbFoundPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/) {} - - virtual void updateBodyCore(PxBaseTask* continuation); - - virtual void setSimulationController(PxsSimulationController* simulationController ){ mSimulationController = simulationController; } - /** - \brief This method combines the results of several islands, e.g. constructing scene-level simulation statistics and merging together threshold streams for contact notification. - */ - virtual void mergeResults(); - - virtual void getDataStreamBase(void*& /*contactStreamBase*/, void*& /*patchStreamBase*/, void*& /*forceAndIndicesStreamBase*/){} - - virtual PxSolverType::Enum getSolverType() const { return PxSolverType::ePGS; } + PxvNphaseImplementationContext* nPhase, PxU32 maxPatchesPerCM, PxU32 maxArticulationLinks, PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap) PX_OVERRIDE; + virtual void mergeResults() PX_OVERRIDE; + virtual void setSimulationController(PxsSimulationController* simulationController ) PX_OVERRIDE { mSimulationController = simulationController; } + virtual PxSolverType::Enum getSolverType() const PX_OVERRIDE { return PxSolverType::ePGS; } + //~Context /** \brief Allocates and returns a thread context object. \return A thread context. */ - PX_FORCE_INLINE ThreadContext* getThreadContext() - { - return mThreadContextPool.get(); - } + PX_FORCE_INLINE ThreadContext* getThreadContext() { return mThreadContextPool.get(); } /** \brief Returns a thread context to the thread context pool. \param[in] context The thread context to return to the thread context pool. */ - void putThreadContext(ThreadContext* context) - { - mThreadContextPool.put(context); - } + void putThreadContext(ThreadContext* context) { mThreadContextPool.put(context); } + PX_FORCE_INLINE Cm::FlushPool& getTaskPool() { return mTaskPool; } + PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; } + PX_FORCE_INLINE PxvSimStats& getSimStats() { return mSimStats; } + PX_FORCE_INLINE PxU32 getKinematicCount() const { return mKinematicCount; } - PX_FORCE_INLINE PxU32 getKinematicCount() const { return mKinematicCount; } - PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; } - + void updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, PxU32 maxLinks); protected: - /** - \brief Constructor for DynamicsContext - */ - DynamicsContext(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocator, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal maxBiasCoefficient, - const bool frictionEveryIteration, - const PxReal lengthScale - ); - /** - \brief Destructor for DynamicsContext - */ - virtual ~DynamicsContext(); - +#if PX_ENABLE_SIM_STATS + void addThreadStats(const ThreadContext::ThreadSimStats& stats); +#else + PX_CATCH_UNDEFINED_ENABLE_SIM_STATS +#endif // Solver helper-methods /** @@ -289,11 +197,11 @@ class DynamicsContext : public Context \param[in] constraint The PxsIndexedInteraction */ void setDescFromIndices(PxSolverConstraintDesc& desc, const IG::IslandSim& islandSim, - const PxsIndexedInteraction& constraint, const PxU32 solverBodyOffset); + const PxsIndexedInteraction& constraint, PxU32 solverBodyOffset); void setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeIndex edgeIndex, - const IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, const PxU32 solverBodyOffset); + const IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, PxU32 solverBodyOffset); /** \brief Compute the unconstrained velocity for set of bodies in parallel. This function may spawn additional tasks. @@ -310,7 +218,7 @@ class DynamicsContext : public Context \param[out] integrateTask The continuation task for any tasks spawned by this function. */ void preIntegrationParallel( - const PxF32 dt, + PxF32 dt, PxsBodyCore*const* bodyArray, // INOUT: core body attributes PxsRigidBody*const* originalBodyArray, // IN: original body atom names (LEGACY - DON'T deref the ptrs!!) PxU32 const* nodeIndexArray, // IN: island node index @@ -331,13 +239,8 @@ class DynamicsContext : public Context void solveParallel(SolverIslandParams& params, IG::IslandSim& islandSim, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV); - - void integrateCoreParallel(SolverIslandParams& params, Cm::SpatialVectorF* deltaV, IG::IslandSim& islandSim); - - - /** \brief Resets the thread contexts */ @@ -371,7 +274,7 @@ class DynamicsContext : public Context SolverConstraintDescPool mSolverConstraintDescPool; /** - \brief Ordered sover constraint desc array (after partitioning) + \brief Ordered solver constraint desc array (after partitioning) */ SolverConstraintDescPool mOrderedSolverConstraintDescPool; @@ -414,7 +317,6 @@ class DynamicsContext : public Context */ SolverBodyDataPool mSolverBodyDataPool; - ThresholdStream* mExceededForceThresholdStream[2]; //this store previous and current exceeded force thresholdStream PxArray mExceededForceThresholdStreamMask; @@ -441,20 +343,16 @@ class DynamicsContext : public Context */ PxI32 mThresholdStreamOut; - - PxsMaterialManager* mMaterialManager; PxsContactManagerOutputIterator mOutputIterator; private: //private: - PxcScratchAllocator& mScratchAllocator; - Cm::FlushPool& mTaskPool; - PxTaskManager* mTaskManager; - PxU32 mCurrentIndex; // this is the index point to the current exceeded force threshold stream - - PxU64 mContextID; + PxcScratchAllocator& mScratchAllocator; + Cm::FlushPool& mTaskPool; + PxTaskManager* mTaskManager; + PxU32 mCurrentIndex; // this is the index point to the current exceeded force threshold stream protected: diff --git a/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp b/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp index 0e376a053..50e6414da 100644 --- a/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp +++ b/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp @@ -50,52 +50,16 @@ #define FEATURESTONE_DEBUG 0 #endif - // we encode articulation link handles in the lower bits of the pointer, so the // articulation has to be aligned, which in an aligned pool means we need to size it // appropriately namespace physx { - namespace Dy { - extern PxcCreateFinalizeSolverContactMethod createFinalizeMethods[3]; - void SolverCoreRegisterArticulationFns(); - - void SolverCoreRegisterArticulationFnsCoulomb(); - - ArticulationPImpl::ComputeUnconstrainedVelocitiesFn ArticulationPImpl::sComputeUnconstrainedVelocities = NULL; - ArticulationPImpl::UpdateBodiesFn ArticulationPImpl::sUpdateBodies = NULL; - ArticulationPImpl::UpdateBodiesFn ArticulationPImpl::sUpdateBodiesTGS = NULL; - ArticulationPImpl::SaveVelocityFn ArticulationPImpl::sSaveVelocity = NULL; - ArticulationPImpl::SaveVelocityTGSFn ArticulationPImpl::sSaveVelocityTGS = NULL; - - ArticulationPImpl::UpdateDeltaMotionFn ArticulationPImpl::sUpdateDeltaMotion = NULL; - ArticulationPImpl::DeltaMotionToMotionVelFn ArticulationPImpl::sDeltaMotionToMotionVel = NULL; - ArticulationPImpl::ComputeUnconstrainedVelocitiesTGSFn ArticulationPImpl::sComputeUnconstrainedVelocitiesTGS = NULL; - - ArticulationPImpl::SetupInternalConstraintsTGSFn ArticulationPImpl::sSetupInternalConstraintsTGS = NULL; - - void PxvRegisterArticulationsReducedCoordinate() - { - ArticulationPImpl::sComputeUnconstrainedVelocities = &FeatherstoneArticulation::computeUnconstrainedVelocities; - ArticulationPImpl::sUpdateBodies = &FeatherstoneArticulation::updateBodies; - ArticulationPImpl::sUpdateBodiesTGS = &FeatherstoneArticulation::updateBodiesTGS; - ArticulationPImpl::sSaveVelocity = &FeatherstoneArticulation::saveVelocity; - ArticulationPImpl::sSaveVelocityTGS = &FeatherstoneArticulation::saveVelocityTGS; - - ArticulationPImpl::sUpdateDeltaMotion = &FeatherstoneArticulation::recordDeltaMotion; - ArticulationPImpl::sDeltaMotionToMotionVel = &FeatherstoneArticulation::deltaMotionToMotionVelocity; - ArticulationPImpl::sComputeUnconstrainedVelocitiesTGS = &FeatherstoneArticulation::computeUnconstrainedVelocitiesTGS; - ArticulationPImpl::sSetupInternalConstraintsTGS = &FeatherstoneArticulation::setupSolverConstraintsTGS; - - SolverCoreRegisterArticulationFns(); - SolverCoreRegisterArticulationFnsCoulomb(); - } - ArticulationData::~ArticulationData() { PX_FREE(mLinksData); @@ -110,12 +74,21 @@ namespace Dy mMotionVelocities.reserve(linkCount); mMotionVelocities.forceSize_Unsafe(linkCount); - mSolverSpatialForces.reserve(linkCount); - mSolverSpatialForces.forceSize_Unsafe(linkCount); + mSolverLinkSpatialDeltaVels.reserve(linkCount); + mSolverLinkSpatialDeltaVels.forceSize_Unsafe(linkCount); + + mSolverLinkSpatialImpulses.reserve(linkCount); + mSolverLinkSpatialImpulses.forceSize_Unsafe(linkCount); + + mSolverLinkSpatialForces.reserve(linkCount); + mSolverLinkSpatialForces.forceSize_Unsafe(linkCount); mMotionAccelerations.reserve(linkCount); mMotionAccelerations.forceSize_Unsafe(linkCount); + mLinkIncomingJointForces.reserve(linkCount); + mLinkIncomingJointForces.forceSize_Unsafe(linkCount); + mMotionAccelerationsInternal.reserve(linkCount); mMotionAccelerationsInternal.forceSize_Unsafe(linkCount); @@ -191,7 +164,6 @@ namespace Dy if (oldSize < linkCount) { - ArticulationLinkData* oldLinks = mLinksData; ArticulationJointCoreData* oldJoints = mJointData; ArticulationJointTargetData* oldJointTran = mJointTranData; @@ -270,8 +242,8 @@ namespace Dy qstZIntIc.reserve(dofs); qstZIntIc.forceSize_Unsafe(dofs); - mIsInvDW.reserve(dofs); - mIsInvDW.forceSize_Unsafe(dofs); + mISInvStIS.reserve(dofs); + mISInvStIS.forceSize_Unsafe(dofs); mPosIterJointVelocities.reserve(dofs); mPosIterJointVelocities.forceSize_Unsafe(dofs); @@ -312,7 +284,7 @@ namespace Dy { } - void FeatherstoneArticulation::copyJointData(ArticulationData& data, PxReal* toJointData, const PxReal* fromJointData) + void FeatherstoneArticulation::copyJointData(const ArticulationData& data, PxReal* toJointData, const PxReal* fromJointData) { const PxU32 dofCount = data.getDofs(); @@ -348,11 +320,8 @@ namespace Dy mUpdateSolverData = false; if (linkCount != mSolverDesc.linkCount) - { - mArticulationData.resizeLinkData(linkCount); - } return true; } @@ -380,7 +349,6 @@ namespace Dy mArticulationData.mExternalAcceleration = mSolverDesc.acceleration; mArticulationData.mArticulation = this; - //allocate memory for articulation data PxU32 totalDofs = computeDofs(); @@ -404,12 +372,10 @@ namespace Dy void FeatherstoneArticulation::initPathToRoot() { - Dy::ArticulationLink* links = mArticulationData.getLinks(); const PxU32 linkCount = mArticulationData.getLinkCount(); - links[0].mPathToRootCount = 0; links[0].mPathToRootStartIndex = 0; @@ -462,7 +428,6 @@ namespace Dy void FeatherstoneArticulation::assignTendons(const PxU32 nbTendons, Dy::ArticulationFixedTendon** tendons) { - mArticulationData.mFixedTendons = tendons; mArticulationData.mNumFixedTendons = nbTendons; } @@ -474,10 +439,9 @@ namespace Dy mArticulationData.mSensorForces = sensorForces; } - PxU32 FeatherstoneArticulation::getDofs() + PxU32 FeatherstoneArticulation::getDofs() const { return mArticulationData.getDofs(); - } PxU32 FeatherstoneArticulation::getDof(const PxU32 linkID) @@ -486,15 +450,13 @@ namespace Dy return jointDatum.dof; } - bool FeatherstoneArticulation::applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, bool& shouldWake) { return applyCacheToDest(mArticulationData, cache, mArticulationData.getJointVelocities(), mArticulationData.getJointAccelerations(), mArticulationData.getJointPositions(), mArticulationData.getJointForces(), flag, shouldWake); } - void FeatherstoneArticulation::copyInternalStateToCache(PxArticulationCache& cache, - const PxArticulationCacheFlags flag) + void FeatherstoneArticulation::copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, const bool isGpuSimEnabled) { if (flag & PxArticulationCacheFlag::eVELOCITY) { @@ -535,19 +497,102 @@ namespace Dy if (flag & PxArticulationCacheFlag::eLINK_ACCELERATION) { - const PxU32 numLinks = mArticulationData.getLinkCount(); + const PxU32 linkCount = mArticulationData.getLinkCount(); - if (mArticulationData.getDt() > 0.f) - recomputeAccelerations(mArticulationData.getDt()); + if(mArticulationData.getDt() == 0.0f) + { + PxMemZero(cache.linkAcceleration, sizeof(PxSpatialVelocity)*linkCount); + } + else if(isGpuSimEnabled) + { + const Cm::SpatialVectorF* linkMotionAccelerationsW = mArticulationData.mMotionAccelerations.begin(); - const Cm::SpatialVectorF* accels = mArticulationData.getMotionAccelerations(); + //Iterate over all links and compute the acceleration for each link. + for (PxU32 i = 0; i < linkCount; ++i) + { + cache.linkAcceleration[i].linear = linkMotionAccelerationsW[i].bottom; + cache.linkAcceleration[i].angular = linkMotionAccelerationsW[i].top; + } + } + else + { + const PxReal invDt = 1.0f/mArticulationData.getDt(); - for (PxU32 i = 0; i < numLinks; ++i) + const Cm::SpatialVectorF* linkMotionAccelerationsW = mArticulationData.mMotionAccelerations.begin(); + const Cm::SpatialVectorF* linkSpatialDeltaVelsW = mArticulationData.mSolverLinkSpatialDeltaVels.begin(); + + //Iterate over all links and compute the acceleration for each link. + for (PxU32 i = 0; i < linkCount; ++i) + { + cache.linkAcceleration[i].linear = linkMotionAccelerationsW[i].bottom + linkSpatialDeltaVelsW[i].bottom*invDt; + cache.linkAcceleration[i].angular = linkMotionAccelerationsW[i].top + linkSpatialDeltaVelsW[i].top*invDt; + } + } + } + + if(flag & PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCE) + { + const PxU32 linkCount = mArticulationData.getLinkCount(); + if (mArticulationData.getDt() == 0.0f) { - const Cm::SpatialVectorF& accel = accels[i]; - cache.linkAcceleration[i].linear = accel.bottom; - cache.linkAcceleration[i].angular = accel.top; - } + PxMemZero(cache.linkIncomingJointForce, sizeof(PxSpatialForce)*linkCount); + } + else if(isGpuSimEnabled) + { + //Calculation already completed on gpu. + const Cm::SpatialVectorF* incomingJointForces = mArticulationData.getLinkIncomingJointForces(); + + //Root links have no incoming joint. + cache.linkIncomingJointForce[0].force = PxVec3(PxZero); + cache.linkIncomingJointForce[0].torque = PxVec3(PxZero); + + //Iterate over all links and get the incoming joint force for each link. + for (PxU32 i = 1; i < linkCount; ++i) + { + cache.linkIncomingJointForce[i].force = incomingJointForces[i].top; + cache.linkIncomingJointForce[i].torque = incomingJointForces[i].bottom; + } + } + else + { + const PxReal invDt = 1.0f/mArticulationData.getDt(); + + //Get everything we need. + const Cm::SpatialVectorF* linkZAForcesExtW = mArticulationData.mZAForces.begin(); + const Cm::SpatialVectorF* linkZAForcesIntW = mArticulationData.mZAInternalForces.begin(); + const Cm::SpatialVectorF* linkMotionAccelerationsW = mArticulationData.mMotionAccelerations.begin(); + const SpatialMatrix* linkSpatialInertiasW = mArticulationData.mWorldSpatialArticulatedInertia.begin(); + const Cm::SpatialVectorF* linkSpatialDeltaVelsW = mArticulationData.mSolverLinkSpatialDeltaVels.begin(); + const Cm::SpatialVectorF* linkSpatialImpulsesW = mArticulationData.mSolverLinkSpatialImpulses.begin(); + + //Root links have no incoming joint. + cache.linkIncomingJointForce[0].force = PxVec3(PxZero); + cache.linkIncomingJointForce[0].torque = PxVec3(PxZero); + + //Iterate over all links and compute the incoming joint force for each link. + for (PxU32 i = 1; i < linkCount; ++i) + { + const ArticulationLink& link = mArticulationData.getLink(i); + const ArticulationJointCore* joint = link.inboundJoint; + const PxTransform Gc = link.bodyCore->body2World; + const PxTransform Lc = joint->childPose; + const PxTransform GcLc = Gc*Lc; + const PxVec3 dW = Gc.rotate(Lc.p); + + //Compute the force measured at the link. + const Cm::SpatialVectorF incomingJointForceAtLinkW = + linkSpatialInertiasW[i]*(linkMotionAccelerationsW[i] + linkSpatialDeltaVelsW[i]*invDt) + + (linkZAForcesExtW[i] + linkZAForcesIntW[i] + linkSpatialImpulsesW[i]*invDt); + + //Compute the equivalent force measured at the joint. + const Cm::SpatialVectorF incomingJointForceAtJointW = + FeatherstoneArticulation::translateSpatialVector(-dW, incomingJointForceAtLinkW); + + //Transform the force to the child joint frame. + cache.linkIncomingJointForce[i].force = GcLc.rotateInv(incomingJointForceAtJointW.top); + cache.linkIncomingJointForce[i].torque = GcLc.rotateInv(incomingJointForceAtJointW.bottom); + } + } } if (flag & PxArticulationCacheFlag::eROOT_TRANSFORM) @@ -555,6 +600,7 @@ namespace Dy const ArticulationLink& rLink = mArticulationData.getLink(0); const PxsBodyCore& rBodyCore = *rLink.bodyCore; const PxTransform& body2World = rBodyCore.body2World; + // PT:: tag: scalar transform*transform cache.rootLinkData->transform = body2World * rBodyCore.getBody2Actor().getInverse(); } @@ -576,6 +622,129 @@ namespace Dy } } + PxU32 FeatherstoneArticulation::getCacheDataSize(PxU32 totalDofs, PxU32 linkCount, PxU32 sensorCount) + { + const PxU32 totalSize = + sizeof(PxSpatialForce) * linkCount // external force + + sizeof(PxSpatialForce) * sensorCount // sensors (PxArticulationCacheFlag::eSENSOR_FORCES) + + sizeof(PxReal) * (6 + totalDofs) * (linkCount * 6) // Free floating base dofs = 6 + totalDofs, and each link (incl. base) velocity has 6 elements + // == offset to end of dense jacobian (assuming free floating base) + + sizeof(PxReal) * totalDofs * totalDofs // mass matrix + + sizeof(PxReal) * totalDofs * 5 // jointVelocity (PxArticulationCacheFlag::eVELOCITY) + // jointAcceleration (PxArticulationCacheFlag::eACCELERATION) + // jointPosition (PxArticulationCacheFlag::ePOSITION) + // joint force (PxArticulationCacheFlag::eFORCE) + // joint constraint force (PxArticulationCacheFlag::eJOINT_SOLVER_FORCES) + + sizeof(PxSpatialVelocity) * linkCount * 2 // link velocity, (PxArticulationCacheFlag::eLINK_VELOCITY) + // link acceleration (PxArticulationCacheFlag::eLINK_ACCELERATION) + + sizeof(PxSpatialForce) * linkCount // link incoming joint forces (PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCE) + + sizeof(PxArticulationRootLinkData); // root link data (PxArticulationCacheFlag::eROOT_TRANSFORM, PxArticulationCacheFlag::eROOT_VELOCITIES) + + return totalSize; + } + + // AD: attention - some of the types here have 16B alignment requirements. + // But the size of PxArticulationCache is not necessarily a multiple of 16B. + PX_COMPILE_TIME_ASSERT(sizeof(Cm::SpatialVector)==sizeof(PxSpatialForce)); + PxArticulationCache* FeatherstoneArticulation::createCache(PxU32 totalDofs, PxU32 linkCount, PxU32 sensorCount) + { + const PxU32 pxArticulationCacheSize16BAligned = (sizeof(PxArticulationCache) + 15) & ~15; + + const PxU32 totalSize = getCacheDataSize(totalDofs, linkCount, sensorCount) + pxArticulationCacheSize16BAligned; + + PxU8* tCache = reinterpret_cast(PX_ALLOC(totalSize, "Articulation cache")); + PX_ASSERT(((size_t)tCache & 15) == 0); + + PxMemZero(tCache, totalSize); + + PxArticulationCache* cache = reinterpret_cast(tCache); + + PxU32 offset = pxArticulationCacheSize16BAligned; + + // the following code assumes that the size of PxSpatialForce and PxSpatialVelocity are multiples of 16B + PX_COMPILE_TIME_ASSERT((sizeof(PxSpatialForce) & 15) == 0); + PX_COMPILE_TIME_ASSERT((sizeof(PxSpatialVelocity) & 15) == 0); + + // PT: filled in FeatherstoneArticulation::getGeneralizedExternalForce, size = mArticulationData.getLinkCount() + // 16B aligned + PX_ASSERT((offset & 15) == 0); + cache->externalForces = reinterpret_cast(tCache + offset); + offset += sizeof(PxSpatialForce) * linkCount; + + // PT: PxArticulationCacheFlag::eSENSOR_FORCES + // 16B aligned + PX_ASSERT((offset & 15) == 0); + cache->sensorForces = reinterpret_cast(tCache + offset); + offset += sizeof(PxSpatialForce) * sensorCount; + + // PT: PxArticulationCacheFlag::eLINK_VELOCITY + // 16B aligned + PX_ASSERT((offset & 15) == 0); + cache->linkVelocity = reinterpret_cast(tCache + offset); + offset += sizeof(PxSpatialVelocity) * linkCount; + + // PT: PxArticulationCacheFlag::eLINK_ACCELERATION + // 16B aligned + PX_ASSERT((offset & 15) == 0); + cache->linkAcceleration = reinterpret_cast(tCache + offset); + offset += sizeof(PxSpatialVelocity) * linkCount; + + // PT: PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCE + // 16B aligned + PX_ASSERT((offset & 15) == 0); + cache->linkIncomingJointForce = reinterpret_cast(tCache + offset); + offset += sizeof(PxSpatialForce) * linkCount; + + cache->denseJacobian = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * (6 + totalDofs) * (linkCount * 6); //size of dense jacobian assuming free floating base link. + + cache->massMatrix = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * totalDofs * totalDofs; + + // PT: PxArticulationCacheFlag::eVELOCITY + cache->jointVelocity = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * totalDofs; + + // PT: PxArticulationCacheFlag::eACCELERATION + cache->jointAcceleration = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * totalDofs; + + // PT: PxArticulationCacheFlag::ePOSITION + cache->jointPosition = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * totalDofs; + + // PT: PxArticulationCacheFlag::eFORCE + cache->jointForce = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * totalDofs; + + // PT: PxArticulationCacheFlag::eJOINT_SOLVER_FORCES + cache->jointSolverForces = reinterpret_cast(tCache + offset); + offset += sizeof(PxReal) * totalDofs; + + // PT: PxArticulationCacheFlag::eROOT_TRANSFORM, PxArticulationCacheFlag::eROOT_VELOCITIES + cache->rootLinkData = reinterpret_cast(tCache + offset); + PX_ASSERT((offset + sizeof(PxArticulationRootLinkData)) == totalSize); + + cache->coefficientMatrix = NULL; + cache->lambda =NULL; + + PxU32 scratchMemorySize = + sizeof(Cm::SpatialVectorF) * linkCount * 5 //motionVelocity, motionAccelerations, coriolisVectors, spatialZAVectors, externalAccels; + + sizeof(Dy::SpatialMatrix) * linkCount //compositeSpatialInertias; + + sizeof(PxReal) * totalDofs * 5; //jointVelocity, jointAcceleration, jointForces, jointPositions, jointFrictionForces + + scratchMemorySize = (scratchMemorySize+15)&~15; + + void* scratchMemory = PX_ALLOC(scratchMemorySize, "Cache scratch memory"); + cache->scratchMemory = scratchMemory; + + PxcScratchAllocator* sa = PX_NEW(PxcScratchAllocator); + sa->setBlock(scratchMemory, scratchMemorySize); + cache->scratchAllocator = sa; + + return cache; + } + static PX_FORCE_INLINE Mat33V loadPxMat33(const PxMat33& m) { return Mat33V(Vec3V_From_Vec4V(V4LoadU(&m.column0.x)), @@ -691,38 +860,10 @@ namespace Dy //p(impluse) = |n| // |0| -#if 0 - const PxTransform& body2World = mArticulationData.getPreTransform(linkID); - - //transform p(impulse) from world space to the local space of linkId - const Cm::SpatialVectorF impl(body2World.rotateInv(impulse.linear), body2World.rotateInv(impulse.angular)); - - getZ(linkID, mArticulationData, Z, impl); - - const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; - - const Cm::SpatialVectorF deltaV = getDeltaV(fixBase, linkID, mArticulationData, Z); - PX_ASSERT(deltaV.pad0 == 0.f && deltaV.pad1 == 0.f); - - ////Cm::SpatialVectorF resp = mArticulationData.getImpulseResponseMatrix()[linkID].getResponse(Cm::SpatialVectorF(impulse.linear, impulse.angular)); - //Cm::SpatialVectorF resp = mArticulationData.getImpulseResponseMatrix()[linkID].getResponse(impl); - - //Cm::SpatialVectorF test = resp - deltaV; - - //PX_ASSERT(test.magnitude() < 1e-5f); - - //this is in world space - deltaVV.linear = body2World.rotate(deltaV.bottom); - deltaVV.angular = body2World.rotate(deltaV.top); - -#else Cm::SpatialVectorF deltaV = mArticulationData.getImpulseResponseMatrixWorld()[linkID].getResponse(reinterpret_cast(impulse)); deltaVV.linear = deltaV.bottom; deltaVV.angular = deltaV.top; -#endif - - } void FeatherstoneArticulation::getImpulseResponse( @@ -772,7 +913,6 @@ namespace Dy return Cm::SpatialVector(motionVelocity.bottom, motionVelocity.top); } - Cm::SpatialVectorV FeatherstoneArticulation::getLinkMotionVector(const PxU32 linkID) const { const Cm::SpatialVectorF& motionVector = mArticulationData.getDeltaMotionVector(linkID); @@ -792,28 +932,36 @@ namespace Dy return Cm::SpatialVector(motionVelocity.bottom, motionVelocity.top); } - Cm::SpatialVector FeatherstoneArticulation::getMotionAcceleration(const PxU32 linkID) const + Cm::SpatialVector FeatherstoneArticulation::getMotionAcceleration(const PxU32 linkID, const bool isGpuSimEnabled) const { - const PxReal dt = mArticulationData.getDt(); - if(0.0f == dt) - return Cm::SpatialVector(PxVec3(0.f), PxVec3(0.f)); - return recomputeAcceleration(linkID, dt); + Cm::SpatialVector a = Cm::SpatialVector::zero(); + if(mArticulationData.getDt() > 0.0f) + { + if(isGpuSimEnabled) + { + const Cm::SpatialVectorF& linkAccel = mArticulationData.mMotionAccelerations[linkID]; + a = Cm::SpatialVector(linkAccel.bottom, linkAccel.top); + } + else + { + const PxReal invDt = 1.0f/mArticulationData.getDt(); + const Cm::SpatialVectorF linkAccel = + mArticulationData.mMotionAccelerations[linkID] + mArticulationData.mSolverLinkSpatialDeltaVels[linkID]*invDt; + a = Cm::SpatialVector(linkAccel.bottom, linkAccel.top); + } + } + return a; } - void FeatherstoneArticulation::fillIndexType(const PxU32 linkId, PxU8& indexType) { ArticulationLink& link = mArticulationData.getLink(linkId); - //turn the kinematic link to static for the solver - if (link.bodyCore->kinematicLink) - { + //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 @@ -879,11 +1027,11 @@ namespace Dy /*if(computeForces) data.getSolverSpatialForce(i) += data.getWorldSpatialArticulatedInertia(i) * dV;*/ + data.incrementSolverSpatialDeltaVel(i, dV); if (computeForces) data.getSolverSpatialForce(i) += dV; PX_ASSERT(motionVelocities[i].isFinite()); - } //PxMemZero(deferredZ, sizeof(Cm::SpatialVectorF)*linkCount); @@ -971,8 +1119,6 @@ namespace Dy data.mDeltaQ[linkID] = dq; - - /*PxVec3 lin, ang; calculateNewVelocity(newPose, data.mPreTransform[linkID], 1.f, lin, ang);*/ @@ -986,7 +1132,6 @@ namespace Dy deltaMotion[linkID].bottom = lin;// motionVeloties[linkID].top * dt; posMotionVelocities[linkID] += delta; - //Record the new current pose data.mAccumulatedPoses[linkID] = newPose; } @@ -1029,7 +1174,6 @@ namespace Dy deltaV = mArticulationData.mBaseInvSpatialArticulatedInertiaW * -mArticulationData.getRootDeferredZ(); } - const PxU32 startIndex = links[linkID].mPathToRootStartIndex; const PxU32 elementCount = links[linkID].mPathToRootCount; @@ -1068,7 +1212,6 @@ namespace Dy deltaV = mArticulationData.mBaseInvSpatialArticulatedInertiaW * (-mArticulationData.mRootDeferredZ); } - const PxU32* pathToRootElements = mArticulationData.mPathToRootElements; Dy::ArticulationLink& link0 = links[linkID]; @@ -1107,7 +1250,6 @@ namespace Dy deltaV = propagateAccelerationW(mArticulationData.getRw(index), mArticulationData.mInvStIs[index], &mArticulationData.mWorldMotionMatrix[jointOffset], deltaV, dofCount, &mArticulationData.mIsW[jointOffset], &mArticulationData.mDeferredQstZ[jointOffset]); - } for (PxU32 idx = offset; idx < numElems1; ++idx) @@ -1120,11 +1262,8 @@ namespace Dy deltaV1 = propagateAccelerationW(mArticulationData.getRw(index), mArticulationData.mInvStIs[index], &mArticulationData.mWorldMotionMatrix[jointOffset], deltaV1, dofCount, &mArticulationData.mIsW[jointOffset], &mArticulationData.mDeferredQstZ[jointOffset]); - } - - Cm::SpatialVectorF vel = mArticulationData.getMotionVelocity(linkID) + deltaV; v0 = Cm::SpatialVector(vel.bottom, vel.top); @@ -1168,14 +1307,18 @@ namespace Dy V4StoreA(Vec4V_From_Vec3V(linear), &impulse.linear.x); Cm::SpatialVectorF Z0(-impulse.linear, -impulse.angular); - - for (PxU32 i = linkID; i; i = links[i].parent) { const PxU32 jointOffset = mArticulationData.getJointData(i).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(i).dof; + const PxU8 dofCount = mArticulationData.getJointData(i).dof; + + data.mSolverLinkSpatialImpulses[i] += Z0; - Z0 = propagateImpulseW(&data.mIsInvDW[jointOffset], mArticulationData.getRw(i), &data.mWorldMotionMatrix[jointOffset], Z0, dofCount, &mArticulationData.mDeferredQstZ[jointOffset]); + Z0 = FeatherstoneArticulation::propagateImpulseW( + mArticulationData.getRw(i), + Z0, + &data.mISInvStIS[jointOffset], &data.mWorldMotionMatrix[jointOffset], dofCount, + &mArticulationData.mDeferredQstZ[jointOffset]); } data.mRootDeferredZ += Z0; @@ -1198,13 +1341,15 @@ namespace Dy { ArticulationLink& tLink = links[linkID]; const PxU32 jointOffset = mArticulationData.getJointData(linkID).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(linkID).dof; + const PxU8 dofCount = mArticulationData.getJointData(linkID).dof; Cm::SpatialVectorF ZA = Z[linkID]; - Z[tLink.parent] += propagateImpulseW(&data.mIsInvDW[jointOffset], mArticulationData.getRw(linkID), &data.mWorldMotionMatrix[jointOffset], ZA, - dofCount, &mArticulationData.mDeferredQstZ[jointOffset]); - + Z[tLink.parent] += propagateImpulseW( + mArticulationData.getRw(linkID), + ZA, + &data.mISInvStIS[jointOffset], &data.mWorldMotionMatrix[jointOffset], dofCount, + &mArticulationData.mDeferredQstZ[jointOffset]); } data.mRootDeferredZ += Z[0]; } @@ -1262,16 +1407,23 @@ namespace Dy for (PxU32 i = linkID2; i != commonLink; i = links[i].parent) { const PxU32 jointOffset = mArticulationData.getJointData(i).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(i).dof; - Z2 = propagateImpulseW(&data.mIsInvDW[jointOffset], mArticulationData.getRw(i), &data.mWorldMotionMatrix[jointOffset], Z2, dofCount, &data.mDeferredQstZ[jointOffset]); + const PxU8 dofCount = mArticulationData.getJointData(i).dof; + Z2 = propagateImpulseW( + mArticulationData.getRw(i), + Z2, + &data.mISInvStIS[jointOffset], &data.mWorldMotionMatrix[jointOffset], dofCount, + &data.mDeferredQstZ[jointOffset]); } for (PxU32 i = linkID; i != commonLink; i = links[i].parent) { const PxU32 jointOffset = mArticulationData.getJointData(i).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(i).dof; - Z1 = propagateImpulseW(&data.mIsInvDW[jointOffset], mArticulationData.getRw(i), &data.mWorldMotionMatrix[jointOffset], Z1, dofCount, - &data.mDeferredQstZ[jointOffset]); + const PxU8 dofCount = mArticulationData.getJointData(i).dof; + Z1 = propagateImpulseW( + mArticulationData.getRw(i), + Z1, + &data.mISInvStIS[jointOffset], &data.mWorldMotionMatrix[jointOffset],dofCount, + &data.mDeferredQstZ[jointOffset]); } Cm::SpatialVectorF ZCommon = Z1 + Z2; @@ -1279,9 +1431,12 @@ namespace Dy for (PxU32 i = commonLink; i; i = links[i].parent) { const PxU32 jointOffset = mArticulationData.getJointData(i).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(i).dof; - ZCommon = propagateImpulseW(&data.mIsInvDW[jointOffset], mArticulationData.getRw(i), &data.mWorldMotionMatrix[jointOffset], ZCommon, dofCount, - &data.mDeferredQstZ[jointOffset]); + const PxU8 dofCount = mArticulationData.getJointData(i).dof; + ZCommon = propagateImpulseW( + mArticulationData.getRw(i), + ZCommon, + &data.mISInvStIS[jointOffset], &data.mWorldMotionMatrix[jointOffset], dofCount, + &data.mDeferredQstZ[jointOffset]); } data.mRootDeferredZ += ZCommon; @@ -1305,9 +1460,12 @@ namespace Dy { ArticulationLink& tLink = links[linkID]; const PxU32 jointOffset = mArticulationData.getJointData(linkID).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(linkID).dof; + const PxU8 dofCount = mArticulationData.getJointData(linkID).dof; - Z[tLink.parent] += propagateImpulseW(&data.mIsInvDW[jointOffset], mArticulationData.getRw(linkID), &data.mWorldMotionMatrix[jointOffset], Z[linkID], dofCount); + Z[tLink.parent] += propagateImpulseW( + mArticulationData.getRw(linkID), + Z[linkID], + &data.mISInvStIS[jointOffset],&data.mWorldMotionMatrix[jointOffset], dofCount); } getDeltaV(Z, deltaV); @@ -1329,7 +1487,6 @@ namespace Dy } else { - deltaV[0] = mArticulationData.mBaseInvSpatialArticulatedInertiaW * (-Z[0]); motionVelocities[0] += deltaV[0]; @@ -1737,7 +1894,6 @@ namespace Dy return motionAcceleration; } - Cm::SpatialVectorF FeatherstoneArticulation::propagateAccelerationW(const PxVec3& c2p, const InvStIs& invStIs, const Cm::UnAlignedSpatialVector* motionMatrix, PxReal* jointVelocity, const Cm::SpatialVectorF& pAcceleration, Cm::SpatialVectorF& Z, const PxU32 dofCount, const Cm::SpatialVectorF* IsW) @@ -1772,7 +1928,6 @@ namespace Dy return motionAcceleration; } - //This method calculate the velocity change due to collision/constraint impulse Cm::SpatialVectorF FeatherstoneArticulation::propagateVelocityTestImpulseW(const PxVec3& c2p, const Dy::SpatialMatrix& spatialInertia, const InvStIs& invStIs, const Cm::UnAlignedSpatialVector* motionMatrix, const Cm::SpatialVectorF& Z, const Cm::SpatialVectorF& hDeltaV, const PxU32 dofCount) @@ -1807,7 +1962,6 @@ namespace Dy return pDeltaV + jointSpatialDeltaV; } - //Cm::SpatialVectorF FeatherstoneArticulation::propagateImpulse(const IsInvD& isInvD, // const SpatialTransform& childToParent, const SpatialSubspaceMatrix& motionMatrix, const Cm::SpatialVectorF& Z) //{ @@ -1825,39 +1979,29 @@ namespace Dy // return childToParent * (Z - temp); //} - Cm::SpatialVectorF FeatherstoneArticulation::propagateImpulseW(const Cm::SpatialVectorF* isInvD, const PxVec3& childToParent, - const Cm::UnAlignedSpatialVector* motionMatrix, const Cm::SpatialVectorF& Z, const PxU32 dofCount) - { - Cm::SpatialVectorF temp(PxVec3(0.f), PxVec3(0.f)); - for (PxU32 ind = 0; ind < dofCount; ++ind) - { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind]; - const PxReal stZ = sa.innerProduct(Z); - temp += isInvD[ind] * stZ; - } - - //parent space's spatial zero acceleration impulse - - return FeatherstoneArticulation::translateSpatialVector(childToParent, (Z-temp)); - /*Cm::SpatialVectorF temp2 = (Z - temp); - temp2.bottom += childToParent.cross(temp2.top); - return temp2;*/ - } - - Cm::SpatialVectorF FeatherstoneArticulation::propagateImpulseW(const Cm::SpatialVectorF* isInvD, const PxVec3& childToParent, - const Cm::UnAlignedSpatialVector* motionMatrix, const Cm::SpatialVectorF& Z, const PxU32 dofCount, PxReal* qsztZ) + Cm::SpatialVectorF FeatherstoneArticulation::propagateImpulseW( + const PxVec3& childToParent, + const Cm::SpatialVectorF& linkYW, + const Cm::SpatialVectorF* jointDofISInvStISW, const Cm::UnAlignedSpatialVector* jointDofMotionMatrixW, const PxU8 dofCount, + PxReal* jointDofQStY) { - Cm::SpatialVectorF temp = Z; - - for (PxU32 ind = 0; ind < dofCount; ++ind) + //See Mirtich Figure 5.7 page 141 + //Mirtich equivalent: {1 - [(I * s)/(s^T * I * s)] * s^T} * Y + //We actually compute: Y - [(I * s)/(s^T * I * s)] * s^T * Y + Cm::SpatialVectorF temp = linkYW; + for (PxU8 ind = 0; ind < dofCount; ++ind) { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind]; - const PxReal stZ = -sa.innerProduct(Z); - PX_ASSERT(PxIsFinite(stZ)); - qsztZ[ind] += stZ; - PX_ASSERT(PxIsFinite(qsztZ[ind])); - temp += isInvD[ind] * stZ; + //Y - [(I * s)/(s^T * I * s)] * s^T * Y + const Cm::UnAlignedSpatialVector& sa = jointDofMotionMatrixW[ind]; + const PxReal stZY = -(sa.innerProduct(linkYW)); + PX_ASSERT(PxIsFinite(stZY)); + temp += jointDofISInvStISW[ind] * stZY; + + //Accumulate (-s^T * Y) + PX_ASSERT(!jointDofQStY || PxIsFinite(jointDofQStY[ind])); + if(jointDofQStY) + jointDofQStY[ind] += stZY; } //parent space's spatial zero acceleration impulse @@ -1895,39 +2039,6 @@ namespace Dy return deltaV; } - Cm::SpatialVectorF FeatherstoneArticulation::getDeltaV(const bool fixBase, const PxU32 linkID, - const ArticulationData& data, Cm::SpatialVectorF* Z) - { - Cm::SpatialVectorF deltaV = Cm::SpatialVectorF::Zero(); - if (!fixBase) - { - //velocity change - //SpatialMatrix inverseArticulatedInertia = hLinkDatum.spatialArticulatedInertia.getInverse(); - const SpatialMatrix& inverseArticulatedInertia = data.mBaseInvSpatialArticulatedInertiaW; - deltaV = inverseArticulatedInertia * (-Z[0]); - } - - ArticulationLink* links = data.getLinks(); - ArticulationLink& link = links[linkID]; - const PxU32* pathToRoot = &data.mPathToRootElements[link.mPathToRootStartIndex]; - const PxU32 numElems = link.mPathToRootCount; - - for (PxU32 i = 0; i < numElems; ++i) - { - const PxU32 index = pathToRoot[i]; - PX_ASSERT(links[index].parent < index); - - const PxU32 jointOffset = data.getJointData(index).jointOffset; - const PxU32 dofCount = data.getJointData(index).dof; - - PxReal jDeltaV[3]; - deltaV = propagateAccelerationW(data.getRw(index), data.mInvStIs[index], - &data.mWorldMotionMatrix[jointOffset], jDeltaV, deltaV, Z[index], dofCount, &data.mIsW[jointOffset]); - } - - return deltaV; - } - void FeatherstoneArticulation::getZ(const PxU32 linkID, const ArticulationData& data, Cm::SpatialVectorF* Z, const Cm::SpatialVectorF& impulse) @@ -1941,9 +2052,11 @@ namespace Dy { ArticulationLink& tLink = links[i]; const PxU32 jointOffset = data.getJointData(i).jointOffset; - const PxU32 dofCount = data.getJointData(i).dof; - Z[tLink.parent] = FeatherstoneArticulation::propagateImpulseW(&data.mIsInvDW[jointOffset], data.getRw(i), - &data.mWorldMotionMatrix[jointOffset], Z[i], dofCount); + const PxU8 dofCount = data.getJointData(i).dof; + Z[tLink.parent] = FeatherstoneArticulation::propagateImpulseW( + data.getRw(i), + Z[i], + &data.mISInvStIS[jointOffset], &data.mWorldMotionMatrix[jointOffset], dofCount); } } @@ -1969,16 +2082,15 @@ namespace Dy return getDeltaVWithDeltaJV(fixBase, linkID, data, Z, jointVelocites); } - void FeatherstoneArticulation::saveVelocity(const ArticulationSolverDesc& d, Cm::SpatialVectorF* deltaV) + void FeatherstoneArticulation::saveVelocity(FeatherstoneArticulation* articulation, Cm::SpatialVectorF* deltaV) { - FeatherstoneArticulation* arti = static_cast(d.articulation); - ArticulationData& data = arti->mArticulationData; + ArticulationData& data = articulation->mArticulationData; //update all links' motion velocity, joint delta velocity if there are contacts/constraints if (data.mJointDirty) { bool doForces = (data.getArticulationFlags() & PxArticulationFlag::eCOMPUTE_JOINT_FORCES) || data.getSensorCount(); - PxcFsFlushVelocity(*arti, deltaV, doForces); + PxcFsFlushVelocity(*articulation, deltaV, doForces); } const PxU32 linkCount = data.getLinkCount(); @@ -1996,7 +2108,7 @@ namespace Dy PxMemCopy(jPosVels, jNewVels, sizeof(PxReal) * dofs); - static_cast(d.articulation)->concludeInternalConstraints(false); + articulation->concludeInternalConstraints(false); /* for (PxU32 i = 0; i < dofs; ++i) { @@ -2004,10 +2116,9 @@ namespace Dy }*/ } - void FeatherstoneArticulation::saveVelocityTGS(const ArticulationSolverDesc& d, PxReal invDtF32) + void FeatherstoneArticulation::saveVelocityTGS(FeatherstoneArticulation* articulation, PxReal invDtF32) { - FeatherstoneArticulation* arti = static_cast(d.articulation); - ArticulationData& data = arti->mArticulationData; + ArticulationData& data = articulation->mArticulationData; //KS - we should not need to flush velocity because we will have already stepped the articulation with TGS @@ -2077,18 +2188,26 @@ namespace Dy for (i0 = 0; linkID0 != common; linkID0 = links[linkID0].parent) { const PxU32 jointOffset = data.getJointData(linkID0).jointOffset; - const PxU32 dofCount = data.getJointData(linkID0).dof; - Z0 = FeatherstoneArticulation::propagateImpulseW(&data.getWorldIsInvD(jointOffset), data.getRw(linkID0), - &data.getWorldMotionMatrix(jointOffset), Z0, dofCount, &qstZ[jointOffset]); + const PxU8 dofCount = data.getJointData(linkID0).dof; + Z0 = FeatherstoneArticulation::propagateImpulseW( + data.getRw(linkID0), + Z0, + &data.getWorldIsInvD(jointOffset), + &data.getWorldMotionMatrix(jointOffset), dofCount, + &qstZ[jointOffset]); stack[i0++] = linkID0; } for (i1 = i0; linkID1 != common; linkID1 = links[linkID1].parent) { const PxU32 jointOffset = data.getJointData(linkID1).jointOffset; - const PxU32 dofCount = data.getJointData(linkID1).dof; - Z1 = FeatherstoneArticulation::propagateImpulseW(&data.getWorldIsInvD(jointOffset), data.getRw(linkID1), - &data.getWorldMotionMatrix(jointOffset), Z1, dofCount, &qstZ[jointOffset]); + const PxU8 dofCount = data.getJointData(linkID1).dof; + Z1 = FeatherstoneArticulation::propagateImpulseW( + data.getRw(linkID1), + Z1, + &data.getWorldIsInvD(jointOffset), + &data.getWorldMotionMatrix(jointOffset), dofCount, + &qstZ[jointOffset]); stack[i1++] = linkID1; } @@ -2134,7 +2253,6 @@ namespace Dy const Cm::SpatialVectorV& impulse1, Cm::SpatialVectorV& deltaV1) { - ArticulationLink& link = links[linkID1]; if (link.parent == linkID0) @@ -2154,11 +2272,14 @@ namespace Dy Cm::SpatialVectorF Z1W(-imp1.top, -imp1.bottom); const PxU32 jointOffset1 = data.getJointData(linkID1).jointOffset; - const PxU32 dofCount1 = data.getJointData(linkID1).dof; + const PxU8 dofCount1 = data.getJointData(linkID1).dof; PxReal qstZ[3] = { 0.f, 0.f, 0.f }; - Cm::SpatialVectorF Z0W = FeatherstoneArticulation::propagateImpulseW(&data.mIsInvDW[jointOffset1], data.getRw(linkID1), - &data.mWorldMotionMatrix[jointOffset1], Z1W, dofCount1, qstZ); + const Cm::SpatialVectorF Z0W = FeatherstoneArticulation::propagateImpulseW( + data.getRw(linkID1), + Z1W, + &data.mISInvStIS[jointOffset1], &data.mWorldMotionMatrix[jointOffset1], dofCount1, + qstZ); //in parent space const Cm::SpatialVectorF impulseDifW = imp0 - Z0W; @@ -2177,7 +2298,6 @@ namespace Dy deltaV0.angular = Vec3V_From_Vec4V(V4LoadA(&delV0W.top.x)); deltaV1.linear = Vec3V_From_Vec4V(V4LoadA(&delV1W.bottom.x)); deltaV1.angular = Vec3V_From_Vec4V(V4LoadA(&delV1W.top.x)); - } else { @@ -2188,7 +2308,6 @@ namespace Dy } } - struct ArticulationStaticConstraintSortPredicate { bool operator()(const PxSolverConstraintDesc& left, const PxSolverConstraintDesc& right) const @@ -2286,8 +2405,6 @@ namespace Dy mStatic1DConstraints.remove(i); i--; } - - } for (PxU32 i = 0; i < mStaticContactConstraints.size(); ++i) @@ -2370,12 +2487,9 @@ namespace Dy mStaticContactConstraints.remove(i); i--; } - - } } - void FeatherstoneArticulation::prepareStaticConstraints(const PxReal dt, const PxReal invDt, PxsContactManagerOutputIterator& outputs, Dy::ThreadContext& threadContext, PxReal correlationDist, PxReal bounceThreshold, PxReal frictionOffsetThreshold, PxReal ccdMaxSeparation, PxSolverBodyData* solverBodyData, PxsConstraintBlockManager& blockManager, @@ -2444,7 +2558,6 @@ namespace Dy mStatic1DConstraints.remove(i); i--; } - } for (PxU32 i = 0; i < mStaticContactConstraints.size(); ++i) @@ -2519,7 +2632,6 @@ namespace Dy } } - static void setupDrive(ArticulationInternalConstraint* constraints, bool hasDrive, PxArticulationDriveType::Enum driveType, PxReal stiffness, PxReal damping, const PxReal dt, const PxReal unitResponse, const PxReal recipResponse, const PxReal error, const PxReal targetVelocity, const bool isTGS, @@ -2529,7 +2641,6 @@ namespace Dy { PxReal x = 0.f; - if (driveType == PxArticulationDriveType::eTARGET) { stiffness = 1e+25f; @@ -2633,7 +2744,6 @@ namespace Dy limit.highImpulse = 0.f; } - void FeatherstoneArticulation::setupInternalConstraintsRecursive( ArticulationLink* links, const PxU32 linkCount, @@ -2665,7 +2775,6 @@ namespace Dy const PxReal fCoefficient = j.frictionCoefficient * stepDt; - const PxU32 limitedRows = jointDatum.limitMask; PxU8 driveRows = 0; @@ -2689,6 +2798,7 @@ namespace Dy { const PxReal transmissionForce = data.getTransmittedForce(linkID).magnitude() * fCoefficient; + // PT:: tag: scalar transform*transform const PxTransform cA2w = pLink.bodyCore->body2World.transform(j.parentPose); const PxTransform cB2w = link.bodyCore->body2World.transform(j.childPose); @@ -2696,7 +2806,6 @@ namespace Dy const PxReal cfm = PxMax(link.cfm, pLink.cfm); - //Linear, then angular... PxVec3 driveError(0.f); @@ -2734,10 +2843,8 @@ namespace Dy tmpDofId++; } } - - + { - PxQuat qB2qA = cA2w.q.getConjugate() * cB2w.q; { @@ -2794,20 +2901,17 @@ namespace Dy { const bool hasDrive = (j.motion[i] != PxArticulationMotion::eLOCKED && j.drives[i].driveType != PxArticulationDriveType::eNONE); - if (j.motion[i] == PxArticulationMotion::eLIMITED || hasDrive || frictionRows) { dofMask |= (1 << dofId); //Impulse response vector and axes are common for all constraints on this axis besides locked axis!!! const PxVec3 axis = row[i]; - Cm::SpatialVectorV deltaVA, deltaVB; FeatherstoneArticulation::getImpulseSelfResponse(links, Z, data, parent, Cm::SpatialVector(PxVec3(0), axis), deltaVA, linkID, Cm::SpatialVector(PxVec3(0), -axis), deltaVB); - const Cm::SpatialVector& deltaV0 = unsimdRef(deltaVA); const Cm::SpatialVector& deltaV1 = unsimdRef(deltaVB); @@ -2822,8 +2926,6 @@ namespace Dy data.mInternalConstraints.forceSize_Unsafe(count + 1); ArticulationInternalConstraint* constraints = &data.mInternalConstraints[count]; - - constraints->recipResponse = recipResponse; constraints->response = unitResponse; constraints->row0 = Cm::SpatialVectorF(PxVec3(0), axis); @@ -2854,7 +2956,6 @@ namespace Dy limits->lowImpulse = 0.f; limits->highImpulse = 0.f; } - } dofId++; @@ -2869,7 +2970,6 @@ namespace Dy if (j.motion[i] == PxArticulationMotion::eLIMITED || hasDrive || frictionRows) { - dofMask |= (1 << dofId); //Impulse response vector and axes are common for all constraints on this axis besides locked axis!!! const PxVec3 axis = data.mWorldMotionMatrix[jointDatum.jointOffset + dofId].bottom; @@ -2929,8 +3029,6 @@ namespace Dy limits->lowImpulse = 0.f; limits->highImpulse = 0.f; } - - } dofId++; } @@ -2943,7 +3041,6 @@ namespace Dy PxU32 i = j.dofIds[dof]; if (j.motion[i] == PxArticulationMotion::eLOCKED) { - const PxU32 count = data.mInternalConstraints.size(); data.mInternalConstraints.forceSize_Unsafe(count + 1); ArticulationInternalConstraint* constraints = &data.mInternalConstraints[count]; @@ -2966,7 +3063,6 @@ namespace Dy } } jointDatum.dofInternalConstraintMask = dofMask; - } const PxU32 numChildren = link.mNumChildren; @@ -2976,7 +3072,6 @@ namespace Dy const PxU32 child = offset + i; setupInternalConstraintsRecursive(links, linkCount, fixBase, data, Z, stepDt, dt, invDt, erp, isTGSSolver, child, maxForceScale); } - } void FeatherstoneArticulation::setupInternalSpatialTendonConstraintsRecursive( @@ -3008,18 +3103,15 @@ namespace Dy const PxVec3 cAttachPoint = cBody2World.p + rb; - const PxVec3 dif = pAttachPoint - cAttachPoint; const PxReal distanceSq = dif.magnitudeSquared(); const PxReal distance = PxSqrt(distanceSq); const PxReal u = distance * attachment.coefficient + accumLength; - const PxU32 childCount = attachment.childCount; if (childCount) - { - + { for (ArticulationBitField children = attachment.children; children != 0; children &= (children - 1)) { //index of child of link h on path to link linkID @@ -3059,7 +3151,6 @@ namespace Dy ArticulationInternalTendonConstraint* constraint = &data.mInternalSpatialTendonConstraints[count]; attachment.mConstraintInd = PxU16(count); - constraint->row0 = Cm::SpatialVectorF(startAxis, startRaXn); constraint->row1 = Cm::SpatialVectorF(axis, rbXn); constraint->linkID0 = startLink; @@ -3069,9 +3160,8 @@ namespace Dy const PxReal a = stepDt * (stepDt*stiffness + damping); const PxReal a2 = stepDt * (stepDt*limitStiffness + damping); - PxReal x = unitResponse > 0.f ? 1.0f / (1.0f + a * unitResponse) : 0.f; - PxReal x2 = unitResponse > 0.f ? 1.0f / (1.0f + a2 * unitResponse) : 0.f; - + const PxReal x = unitResponse > 0.f ? 1.0f / (1.0f + a * unitResponse) : 0.f; + const PxReal x2 = unitResponse > 0.f ? 1.0f / (1.0f + a2 * unitResponse) : 0.f; constraint->velMultiplier = -x * a;// * unitResponse; //constraint->velMultiplier = -x * damping*stepDt; @@ -3091,7 +3181,6 @@ namespace Dy } } - void FeatherstoneArticulation::updateSpatialTendonConstraintsRecursive(ArticulationAttachment* attachments, ArticulationData& data, const PxU32 attachmentID, PxReal accumLength, const PxVec3& pAttachPoint) { @@ -3105,7 +3194,6 @@ namespace Dy const PxVec3 cAttachPoint = cBody2World.p + rb; - const PxVec3 dif = pAttachPoint - cAttachPoint; const PxReal distanceSq = dif.magnitudeSquared(); const PxReal distance = PxSqrt(distanceSq); @@ -3172,7 +3260,6 @@ namespace Dy //jointPose += accumulatedJointPose;*/ - { PxVec3 axis, rbXn; if (tendonJointAxis < PxArticulationAxis::eX) @@ -3183,20 +3270,18 @@ namespace Dy } else { + // PT:: tag: scalar transform*transform const PxTransform cB2w = cBody2World.transform(joint.childPose); const PxVec3 tAxis = data.mWorldMotionMatrix[jointDatum.jointOffset + dofIndex].bottom; axis = tAxis; rbXn = (cB2w.p - cBody2World.p).cross(axis); } - Cm::SpatialVectorV deltaVA, deltaVB; FeatherstoneArticulation::getImpulseSelfResponse(links, Z, data, startLink, Cm::SpatialVector(startAxis, startRaXn), deltaVA, tendonJoint.linkInd, Cm::SpatialVector(-axis, -rbXn), deltaVB); - - const Cm::SpatialVector& deltaV0 = unsimdRef(deltaVA); const Cm::SpatialVector& deltaV1 = unsimdRef(deltaVB); @@ -3208,7 +3293,6 @@ namespace Dy const PxReal r0 = deltaV0.linear.dot(startAxis) + deltaV0.angular.dot(startRaXn); const PxReal r1 = deltaV1.linear.dot(axis) + deltaV1.angular.dot(rbXn); - const PxReal unitResponse = r0 - r1; const PxReal recipResponse = 1.0f / (unitResponse + cfm); @@ -3219,7 +3303,6 @@ namespace Dy ArticulationInternalTendonConstraint* constraint = &data.mInternalFixedTendonConstraints[count]; tendonJoint.mConstraintInd = PxU16(count); - constraint->row0 = Cm::UnAlignedSpatialVector(startAxis, startRaXn); constraint->row1 = Cm::UnAlignedSpatialVector(axis, rbXn); constraint->deltaVA = r0; //We only need to record the change in velocity projected onto the dof for this! @@ -3236,7 +3319,6 @@ namespace Dy PxReal x2 = unitResponse > 0.f ? 1.0f / (1.0f + a2* unitResponse) : 0.f; - constraint->velMultiplier = -x * a;// * unitResponse; constraint->impulseMultiplier = isTGSSolver ? 1.f : 1.f - x; @@ -3256,7 +3338,6 @@ namespace Dy if (childCount) { - for (ArticulationBitField children = tendonJoint.children; children != 0; children &= (children - 1)) { //index of child of link h on path to link linkID @@ -3268,7 +3349,6 @@ namespace Dy } } - void FeatherstoneArticulation::setupInternalConstraints( ArticulationLink* links, const PxU32 linkCount, @@ -3289,7 +3369,6 @@ namespace Dy data.mInternalLimits.forceSize_Unsafe(0); data.mInternalLimits.reserve(data.getDofs()); - const PxReal maxForceScale = data.getArticulationFlags() & PxArticulationFlag::eDRIVE_LIMITS_ARE_FORCES ? dt : 1.f; const PxU32 numChildren = links[0].mNumChildren; @@ -3299,7 +3378,6 @@ namespace Dy const PxU32 child = offset + i; setupInternalConstraintsRecursive(links, linkCount, fixBase, data, Z, stepDt, dt, invDt, erp, isTGSSolver, child, maxForceScale); - } PxU32 totalNumAttachments = 0; @@ -3312,7 +3390,6 @@ namespace Dy data.mInternalSpatialTendonConstraints.forceSize_Unsafe(0); data.mInternalSpatialTendonConstraints.reserve(totalNumAttachments); - for (PxU32 i = 0; i < data.mNumSpatialTendons; ++i) { Dy::ArticulationSpatialTendon* tendon = data.mSpatialTendons[i]; @@ -3333,7 +3410,6 @@ namespace Dy const PxVec3 ra = pBody2World.q.rotate(pAttachment.relativeOffset); const PxVec3 pAttachPoint = pBody2World.p + ra; - for (ArticulationAttachmentBitField children = pAttachment.children; children != 0; children &= (children - 1)) { //index of child of link h on path to link linkID @@ -3354,7 +3430,6 @@ namespace Dy } } - PxU32 totalNumTendonJoints = 0; for (PxU32 i = 0; i < data.mNumFixedTendons; ++i) { @@ -3365,7 +3440,6 @@ namespace Dy data.mInternalFixedTendonConstraints.forceSize_Unsafe(0); data.mInternalFixedTendonConstraints.reserve(totalNumTendonJoints); - for (PxU32 i = 0; i < data.mNumFixedTendons; ++i) { ArticulationFixedTendon* tendon = data.mFixedTendons[i]; @@ -3378,7 +3452,6 @@ namespace Dy ArticulationLink& pLink = links[startLinkInd]; const PxTransform& pBody2World = pLink.bodyCore->body2World; - for (ArticulationAttachmentBitField children = pTendonJoint.children; children != 0; children &= (children - 1)) { //index of child of link h on path to link linkID @@ -3409,6 +3482,7 @@ namespace Dy } else { + // PT:: tag: scalar transform*transform const PxTransform cA2w = pBody2World.transform(joint->parentPose); const PxVec3 axis = data.mWorldMotionMatrix[jointDatum->jointOffset + dofIndex].bottom; const PxVec3 ang0 = (cA2w.p - pBody2World.p).cross(axis); @@ -3416,15 +3490,12 @@ namespace Dy raXn = ang0; } - setupInternalFixedTendonConstraintsRecursive(links, tendonJoints, fixBase, data, Z, stepDt, isTGSSolver, child, tendon->mStiffness, tendon->mDamping, tendon->mLimitStiffness, startLinkInd, startAxis, raXn); } } - } - PxU32 FeatherstoneArticulation::setupSolverConstraints( ArticulationLink* links, const PxU32 linkCount, @@ -3440,7 +3511,6 @@ namespace Dy return 0; } - PxU32 FeatherstoneArticulation::setupSolverConstraintsTGS(const ArticulationSolverDesc& articDesc, PxReal dt, PxReal invDt, @@ -3467,7 +3537,6 @@ namespace Dy void FeatherstoneArticulation::teleportLinks(ArticulationData& data) { - ArticulationLink* links = mArticulationData.getLinks(); ArticulationJointCoreData* jointData = mArticulationData.getJointData(); @@ -3579,7 +3648,6 @@ namespace Dy void FeatherstoneArticulation::computeLinkVelocities(ArticulationData& data) { - ArticulationLink* links = data.getLinks(); const PxU32 linkCount = data.getLinkCount(); @@ -3758,7 +3826,6 @@ namespace Dy } z = zTmp; - } } @@ -3916,23 +3983,19 @@ namespace Dy } } - - - void FeatherstoneArticulation::computeRelativeTransformC2P(ArticulationData& data) - { - const ArticulationLink* links = data.getLinks(); - const PxU32 linkCount = data.getLinkCount(); - - PxTransform* accumulatedPose = data.getAccumulatedPoses(); - - accumulatedPose[0] = links[0].bodyCore->body2World; + void FeatherstoneArticulation::computeRelativeTransformC2P( + const ArticulationLink* links, const PxU32 linkCount, const ArticulationJointCoreData* jointCoreDatas, + const Cm::UnAlignedSpatialVector* jonitDofMotionMatrices, + PxTransform* linkAccumulatedPoses, PxVec3* linkRws, Cm::UnAlignedSpatialVector* jointDofMotionMatricesW) + { + linkAccumulatedPoses[0] = links[0].bodyCore->body2World; for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { const ArticulationLink& link = links[linkID]; const PxsBodyCore& bodyCore = *link.bodyCore; - const PxU32 jointOffset = data.getJointData(linkID).jointOffset; - const PxU32 dofCount = data.getJointData(linkID).dof; + const PxU32 jointOffset = jointCoreDatas[linkID].jointOffset; + const PxU32 dofCount = jointCoreDatas[linkID].dof; const PxTransform& body2World = bodyCore.body2World; @@ -3942,19 +4005,18 @@ namespace Dy //const PxTransform tC2P = pBody2World.transformInv(body2World).getNormalized(); - data.mRw[linkID] =body2World.p - pBody2World.p; + linkRws[linkID] =body2World.p - pBody2World.p; - const Cm::UnAlignedSpatialVector* motionMatrix = &data.mMotionMatrix[jointOffset]; - Cm::UnAlignedSpatialVector* worldMotionMatrix = &data.mWorldMotionMatrix[jointOffset]; + const Cm::UnAlignedSpatialVector* motionMatrix = &jonitDofMotionMatrices[jointOffset]; + Cm::UnAlignedSpatialVector* worldMotionMatrix = &jointDofMotionMatricesW[jointOffset]; for (PxU32 i = 0; i < dofCount; ++i) { const Cm::UnAlignedSpatialVector worldRow = motionMatrix[i].rotate(body2World); - worldMotionMatrix[i] = worldRow; } - accumulatedPose[linkID] = body2World; + linkAccumulatedPoses[linkID] = body2World; #if FEATURESTONE_DEBUG { @@ -3993,7 +4055,6 @@ namespace Dy } } - void FeatherstoneArticulation::getDenseJacobian(PxArticulationCache& cache, PxU32 & nRows, PxU32 & nCols) { //make sure motionMatrix has been set @@ -4110,7 +4171,7 @@ namespace Dy mArticulationData.getJointData(parentLinkID).jointOffset + (fixBase ? 0 : 6) + mArticulationData.getJointData(parentLinkID).dof : 6; - // VR: With parentLinkID == 0 this experssion has two unsigned integer overflows, but the result is still correct. + // VR: With parentLinkID == 0 this expression has two unsigned integer overflows, but the result is still correct. const PxU32 parentsDestRow = (fixBase ? 0 : 6) + (parentLinkID - 1) * 6; for (PxU32 col = 0; col < parentsLastDestCol; col++) @@ -4232,15 +4293,15 @@ namespace Dy const PxF32 dt, const PxReal invLengthScale, const PxVec3& gravity, const bool fixBase, const PxU32 linkCount, - const PxTransform* accumulatedPoses, const Cm::SpatialVector* externalAccels, const PxVec3* rws, const Cm::UnAlignedSpatialVector* worldMotionMatrices, + const PxTransform* linkAccumulatedPosesW, const Cm::SpatialVector* linkExternalAccelsW, const PxVec3* linkRsW, const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, const Dy::ArticulationJointCoreData* jointCoreData, - Dy::ArticulationLinkData *linkData, Dy::ArticulationLink* links, Cm::SpatialVectorF* motionAccelerations, - Cm::SpatialVectorF* motionVelocities, - Cm::SpatialVectorF* spatialZAForces, Cm::SpatialVectorF* spatialZAInternal, Cm::SpatialVectorF* coriolisVectors, - PxMat33* worldIsolatedSpatialArticulatedInertias, PxF32* linkMasses, Dy::SpatialMatrix* worldSpatialArticulatedInertias, + Dy::ArticulationLinkData *linkData, Dy::ArticulationLink* links, + Cm::SpatialVectorF* jointDofMotionAccelerations, Cm::SpatialVectorF* jointDofMotionVelocities, + Cm::SpatialVectorF* linkZAExtForcesW, Cm::SpatialVectorF* linkZAIntForcesW, Cm::SpatialVectorF* linkCoriolisVectorsW, + PxMat33* linkIsolatedSpatialArticulatedInertiasW, PxF32* linkMasses, Dy::SpatialMatrix* linkSpatialArticulatedInertiasW, const PxU32 jointDofCount, - PxReal* jointVelocities, - Cm::SpatialVectorF& rootPreMotionVelocity, PxVec3& com, PxF32& invSumMass) + PxReal* jointDofVelocities, + Cm::SpatialVectorF& rootPreMotionVelocityW, PxVec3& comW, PxF32& invSumMass) { PX_UNUSED(jointDofCount); @@ -4252,21 +4313,21 @@ namespace Dy const Dy::ArticulationLink& baseLink = links[0]; const PxsBodyCore& core0 = *baseLink.bodyCore; rootLinkVel = fixBase ? Cm::SpatialVectorF::Zero() : Cm::SpatialVectorF(core0.angularVelocity, core0.linearVelocity); - motionVelocities[0] = rootLinkVel; - motionAccelerations[0] = fixBase ? Cm::SpatialVectorF::Zero() : motionAccelerations[0]; - coriolisVectors[0] = Cm::SpatialVectorF::Zero(); - rootPreMotionVelocity = rootLinkVel; + jointDofMotionVelocities[0] = rootLinkVel; + jointDofMotionAccelerations[0] = fixBase ? Cm::SpatialVectorF::Zero() : jointDofMotionAccelerations[0]; + linkCoriolisVectorsW[0] = Cm::SpatialVectorF::Zero(); + rootPreMotionVelocityW = rootLinkVel; } PxReal ratio = 1.f; - if (jointVelocities) + if (jointDofVelocities) { for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { const ArticulationLink& link = links[linkID]; const ArticulationJointCoreData& jointDatum = jointCoreData[linkID]; - PxReal* jVelocity = &jointVelocities[jointDatum.jointOffset]; + PxReal* jVelocity = &jointDofVelocities[jointDatum.jointOffset]; const PxReal maxJVelocity = link.inboundJoint->maxJointVelocity; for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) { @@ -4299,47 +4360,47 @@ namespace Dy PxMat33 Iw; //R * I * Rtranspose SpatialMatrix worldArticulatedInertia; { - PxMat33 rot(accumulatedPoses[linkID].q); + PxMat33 rot(linkAccumulatedPosesW[linkID].q); Cm::transformInertiaTensor(inertiaTensor, rot, Iw); - worldArticulatedInertia.topLeft = PxMat33(PxZero); - worldArticulatedInertia.topRight = PxMat33::createDiagonal(PxVec3(m)); + worldArticulatedInertia.topLeft = PxMat33(PxZero); + worldArticulatedInertia.topRight = PxMat33::createDiagonal(PxVec3(m)); worldArticulatedInertia.bottomLeft = Iw; } //Set the articulated inertia, inertia and mass of the link. - worldSpatialArticulatedInertias[linkID] = worldArticulatedInertia; - worldIsolatedSpatialArticulatedInertias[linkID] = Iw; + linkSpatialArticulatedInertiasW[linkID] = worldArticulatedInertia; + linkIsolatedSpatialArticulatedInertiasW[linkID] = Iw; linkMasses[linkID] = m; //Accumulate the centre of mass. sumMass += m; - COM += accumulatedPoses[linkID].p * m; + COM += linkAccumulatedPosesW[linkID].p * m; Cm::SpatialVectorF vel; if (linkID != 0) { - //Propagate spatial vector of link parent to link's spatial vector. - const Cm::SpatialVectorF pVel = motionVelocities[link.parent]; - vel = FeatherstoneArticulation::translateSpatialVector(-rws[linkID], pVel); + //Propagate spatial velocity of link parent to link's spatial velocity. + const Cm::SpatialVectorF pVel = jointDofMotionVelocities[link.parent]; + vel = FeatherstoneArticulation::translateSpatialVector(-linkRsW[linkID], pVel); //Propagate joint dof velocities to the link's spatial velocity vector. //Accumulate spatial forces that the joint applies to the link. - if (jointVelocities) + if (jointDofVelocities) { //The coriolis vector depends on the type of joint and the joint motion matrix. //However, some terms in the coriolis vector are common to all joint types. //Write down the term that is independent of the joint. - Cm::SpatialVectorF coriolisVector(PxVec3(PxZero), pVel.top.cross(pVel.top.cross(rws[linkID]))); + Cm::SpatialVectorF coriolisVector(PxVec3(PxZero), pVel.top.cross(pVel.top.cross(linkRsW[linkID]))); const ArticulationJointCoreData& jointDatum = jointCoreData[linkID]; if (jointDatum.dof) { //Compute the effect of the joint velocities on the link. - PxReal* jVelocity = &jointVelocities[jointDatum.jointOffset]; + PxReal* jVelocity = &jointDofVelocities[jointDatum.jointOffset]; Cm::UnAlignedSpatialVector deltaV = Cm::UnAlignedSpatialVector::Zero(); for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) { PxReal jVel = jVelocity[ind] * ratio; - deltaV += worldMotionMatrices[jointDatum.jointOffset + ind] * jVel; + deltaV += jointDofMotionMatricesW[jointDatum.jointOffset + ind] * jVel; jVelocity[ind] = jVel; } @@ -4360,12 +4421,12 @@ namespace Dy coriolisVector += Cm::SpatialVectorF(pVel.top.cross(deltaV.top), 2.0f*pVel.top.cross(deltaV.bottom) + deltaV.top.cross(deltaV.bottom)); } //TODOGY - if jointVelocities is null we do not appear to set coriolisVectors[linkId] but we do set coriolisVectors[0] - coriolisVectors[linkID] = coriolisVector; + linkCoriolisVectorsW[linkID] = coriolisVector; } //PX_ASSERT(vel.top.isFinite() && PxAbs(vel.top.x) < 10000.f && PxAbs(vel.top.y) < 10000.f && PxAbs(vel.top.z) < 10000.f); //PX_ASSERT(vel.bottom.isFinite() && PxAbs(vel.bottom.x) < 10000.f && PxAbs(vel.bottom.y) < 10000.f && PxAbs(vel.bottom.z) < 10000.f); - motionVelocities[linkID] = vel; + jointDofMotionVelocities[linkID] = vel; } else { @@ -4390,32 +4451,35 @@ namespace Dy Cm::SpatialVectorF zTmp; { const PxVec3 g = bodyCore.disableGravity ? PxVec3(PxZero) : gravity; - const PxVec3 exLinAccel = externalAccels ? externalAccels[linkID].linear : PxVec3(PxZero); + const PxVec3 extLinAccel = linkExternalAccelsW ? linkExternalAccelsW[linkID].linear : PxVec3(PxZero); const PxF32 lindamp = bodyCore.linearDamping > 0.f ? PxMin(bodyCore.linearDamping, invDt) : 0.0f; const PxF32 linscale = (vel.bottom.magnitudeSquared() > bodyCore.maxLinearVelocitySq) ? (1.0f - (PxSqrt(bodyCore.maxLinearVelocitySq)/PxSqrt(vel.bottom.magnitudeSquared()))): 0.0f; - zTmp.top = -(m*((g + exLinAccel)*(1.0f - lindamp*dt) - vel.bottom*(lindamp + linscale*invDt))); + zTmp.top = -(m*((g + extLinAccel)*(1.0f - lindamp*dt) - vel.bottom*(lindamp + linscale*invDt))); } { - const PxVec3 exAngAccel = externalAccels ? externalAccels[linkID].angular : PxVec3(PxZero); + const PxVec3 extAngAccel = linkExternalAccelsW ? linkExternalAccelsW[linkID].angular : PxVec3(PxZero); const PxF32 angdamp = bodyCore.angularDamping > 0.f ? PxMin(bodyCore.angularDamping, invDt) : 0.0f; const PxF32 angscale = (vel.top.magnitudeSquared() > bodyCore.maxAngularVelocitySq) ? (1.0f - (PxSqrt(bodyCore.maxAngularVelocitySq)/PxSqrt(vel.top.magnitudeSquared()))) : 0.0f; - zTmp.bottom = -(Iw*(exAngAccel*(1.0f - angdamp*dt) - vel.top*(angdamp + angscale*invDt))); - } - spatialZAForces[linkID] = zTmp; + zTmp.bottom = -(Iw*(extAngAccel*(1.0f - angdamp*dt) - vel.top*(angdamp + angscale*invDt))); + } + linkZAExtForcesW[linkID] = zTmp; //Account for forces arising from internal accelerations. //Note: Mirtich thesis introduces a single spatial zero acceleration force that contains an external [mass*gravity] term and the internal [omega X (Iw *omega)] term. + //In Mirtich it looks like this: + // [-m_i * g ] + // [omega_i * (I_i * omega_i) ] //We split the spatial zero acceleration force into external (above) and internal (below). + //The sum of the two (external and internal) correspoinds to Z_i^A in the Mirtich formulation. const Cm::SpatialVectorF zInternal(PxVec3(0.f), vel.top.cross(Iw*vel.top)); - spatialZAInternal[linkID] = zInternal; + linkZAIntForcesW[linkID] = zInternal; } PxReal invMass = 1.f / sumMass; - com = COM * invMass; + comW = COM * invMass; invSumMass = invMass; } - //compute all links velocities void FeatherstoneArticulation::computeLinkVelocities(ArticulationData& data, ScratchData& scratchData) @@ -4443,7 +4507,6 @@ namespace Dy { motionVelocities[0] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); motionAccelerations[0] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); - } else { @@ -4496,7 +4559,6 @@ namespace Dy PxVec3 force(0.f); if (jointDatum.dof) { - Cm::UnAlignedSpatialVector deltaV = Cm::UnAlignedSpatialVector::Zero(); for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) { @@ -4545,9 +4607,6 @@ namespace Dy Vec3V& linDelta0, Vec3V& linDelta1, Vec3V& angDelta0, Vec3V& angDelta1, Vec3V& linImpulse0, Vec3V& linImpulse1, Vec3V& angImpulse0, Vec3V& angImpulse1, bool doFriction, const PxReal minPenetration, const PxReal elapsedTimeF32); - - - void solveStaticConstraint(const PxSolverConstraintDesc& desc, Cm::SpatialVectorF& linkV, Cm::SpatialVectorF& impulse, Cm::SpatialVectorF& deltaV, const Cm::SpatialVectorF& motion, const PxQuat& rot, bool isTGS, PxReal elapsedTime, const PxReal minPenetration) @@ -4589,13 +4648,19 @@ namespace Dy if (*desc.constraint == DY_SC_TYPE_EXT_CONTACT) { - Dy::solveExtContactStep(desc, linVel0, linVel1, angVel0, angVel1, linMotion0, linMotion1, angMotion0, angMotion1, - li0, li1, ai0, ai1, true, minPenetration, elapsedTime); + Dy::solveExtContactStep(desc, + linVel0, linVel1, angVel0, angVel1, + linMotion0, linMotion1, angMotion0, angMotion1, + li0, li1, ai0, ai1, + true, minPenetration, elapsedTime); } else { - Dy::solveExt1D(desc, linVel0, linVel1, angVel0, angVel1, linMotion0, linMotion1, angMotion0, angMotion1, - rotA, rotB, elapsedTime, li0, li1, ai0, ai1); + Dy::solveExt1D(desc, + linVel0, linVel1, angVel0, angVel1, + linMotion0, linMotion1, angMotion0, angMotion1, + rotA, rotB, elapsedTime, + li0, li1, ai0, ai1); } } else @@ -4663,7 +4728,6 @@ namespace Dy SolverContext context; PxSolverBodyData data; - for (PxU32 i = 0; i < mStatic1DConstraints.size(); ++i) { PxSolverConstraintDesc& desc = mStatic1DConstraints[i]; @@ -4688,7 +4752,6 @@ namespace Dy if (isTGS) { writeBackContact(static_cast(desc), NULL); - } else { @@ -4705,7 +4768,6 @@ namespace Dy void conclude1DStep(const PxSolverConstraintDesc& desc); - void FeatherstoneArticulation::concludeInternalConstraints(bool isTGS) { SolverContext context; @@ -4741,6 +4803,7 @@ namespace Dy } } + //Takes jointV, returns deltaF static PxReal solveLimit(ArticulationInternalLimit& limit, PxReal& jointV, const PxReal jointPDelta, const PxReal response, const PxReal recipResponse, const InternalConstraintSolverData& data) @@ -4788,7 +4851,6 @@ namespace Dy limit.highImpulse = highImpulse + deltaF; } - if (!limited) { const PxReal forceLimit = -jointV*recipResponse; @@ -4809,7 +4871,6 @@ namespace Dy return deltaF; } - Cm::SpatialVectorF FeatherstoneArticulation::solveInternalJointConstraintRecursive(InternalConstraintSolverData& data, const PxU32 linkID, const Cm::SpatialVectorF& parentDeltaV) { //PxU32 linkID = stack[stackSize]; @@ -4874,8 +4935,6 @@ namespace Dy jointV += frictionDeltaF * constraint.response; - - PxReal unclampedForce = constraint.driveImpulseMultiplier * constraint.driveForce + jointV * constraint.driveVelMultiplier + constraint.driveTargetVel + constraint.driveInitialBias + errorDelta * constraint.driveBiasCoefficient; @@ -4927,9 +4986,9 @@ namespace Dy } } - - - + //Cache the impulse arising from internal constraints. + //We'll subtract this from the total impulse applied later in this function. + const Cm::SpatialVectorF i1Internal = i1; const Cm::SpatialVectorF& deltaMotion = mArticulationData.getDeltaMotionVector(linkID); const PxQuat& deltaQ = getDeltaQ(linkID); @@ -4970,12 +5029,31 @@ namespace Dy } } - - Cm::SpatialVectorF propagatedImpulse = propagateImpulseW(&mArticulationData.mIsInvDW[jointDatum.jointOffset], mArticulationData.getRw(linkID), &mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset], i1, jointDatum.dof, &mArticulationData.mDeferredQstZ[jointDatum.jointOffset]); - return Cm::SpatialVectorF(i0.top, i0.bottom) + propagatedImpulse; - } + Cm::SpatialVectorF propagatedImpulseAtParentW; + { + //const inputs + const PxVec3& r = mArticulationData.getRw(linkID); + const Cm::SpatialVectorF* jointDofISInvStISW = &mArticulationData.mISInvStIS[jointDatum.jointOffset]; + const Cm::UnAlignedSpatialVector* jointDofMotionMatrixW = &mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset]; + const PxU8 nbDofs = jointDatum.dof; + //output + PxReal* jointDofDeferredQstZ = &mArticulationData.mDeferredQstZ[jointDatum.jointOffset]; + propagatedImpulseAtParentW = propagateImpulseW( + r, + i1, + jointDofISInvStISW, jointDofMotionMatrixW, nbDofs, + jointDofDeferredQstZ); + } + + //Accumulate the propagated impulse at the link. + //Don't forget to subtract the impulse arising from internal constraints. + //This can be used to compute the link's incoming joint force. + mArticulationData.mSolverLinkSpatialImpulses[linkID] += (i1 - i1Internal); + + return Cm::SpatialVectorF(i0.top, i0.bottom) + propagatedImpulseAtParentW; + } void FeatherstoneArticulation::solveInternalJointConstraints(const PxReal dt, const PxReal invDt, Cm::SpatialVectorF* impulses, Cm::SpatialVectorF* DeltaV, bool velocityIteration, bool isTGS, @@ -5062,7 +5140,6 @@ namespace Dy /*im0.top = transforms[0].rotateInv(im0.top); im0.bottom = transforms[0].rotateInv(im0.bottom);*/ } - } InternalConstraintSolverData data(dt, invDt, elapsedTime, @@ -5088,27 +5165,20 @@ namespace Dy //Impulses and deltaVs are all now in world space rootLinkDeltaV += mArticulationData.getBaseInvSpatialArticulatedInertiaW() * (-imp); } - } mArticulationData.mRootDeferredZ += im0; mArticulationData.mJointDirty = true; - } } - - void FeatherstoneArticulation::solveInternalSpatialTendonConstraints(bool isTGS) { - if (mArticulationData.mInternalSpatialTendonConstraints.size() == 0) return; - if (isTGS) { - //Update the error terms in the tendons recursively... const PxU32 nbTendons = mArticulationData.mNumSpatialTendons; @@ -5120,7 +5190,6 @@ namespace Dy //const PxU32 childCount = attachment.childCount; - //PxReal scale = 1.f / PxReal(childCount); PxReal coefficient = attachment.coefficient; @@ -5137,7 +5206,6 @@ namespace Dy updateSpatialTendonConstraintsRecursive(attachments, mArticulationData, child, tendon->mOffset*coefficient, pAttachPoint); } - } } @@ -5156,7 +5224,6 @@ namespace Dy Cm::SpatialVectorV childVel = pxcFsGetVelocity(linkID); Cm::SpatialVectorV parentVel = pxcFsGetVelocity(parentID); - Cm::UnAlignedSpatialVector childV; V3StoreU(childVel.angular, childV.top); V3StoreU(childVel.linear, childV.bottom); @@ -5210,7 +5277,6 @@ namespace Dy Cm::SpatialVectorF childV = mArticulationData.mMotionVelocities[tendonJoint.linkInd] + deltaV; - PxU32 index = tendonJoint.mConstraintInd; ArticulationInternalTendonConstraint& constraint = mArticulationData.mInternalFixedTendonConstraints[index]; @@ -5242,7 +5308,6 @@ namespace Dy return jointVError; } - Cm::SpatialVectorF FeatherstoneArticulation::solveFixedTendonConstraintsRecursive(FixedTendonSolveData& solveData, const PxU32 tendonJointID) { @@ -5280,10 +5345,9 @@ namespace Dy constraint.limitAppliedForce = unclampedForce2; solveData.rootImp += deltaF; - - + Cm::SpatialVectorF impulse(constraint.row1.top * -deltaF, constraint.row1.bottom * -deltaF); - + const Cm::SpatialVectorF YInt = impulse; if (childCount) { for (ArticulationBitField children = tendonJoint.children; children != 0; children &= (children - 1)) @@ -5299,10 +5363,15 @@ namespace Dy } } - return propagateImpulseW(&mArticulationData.mIsInvDW[jointDatum.jointOffset], mArticulationData.mRw[tendonJoint.linkInd], - &mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset], impulse, jointDatum.dof, &mArticulationData.mDeferredQstZ[jointDatum.jointOffset]); - } + mArticulationData.mSolverLinkSpatialImpulses[tendonJoint.linkInd] += impulse - YInt; + + return propagateImpulseW( + mArticulationData.mRw[tendonJoint.linkInd], + impulse, + &mArticulationData.mISInvStIS[jointDatum.jointOffset], &mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset], jointDatum.dof, + &mArticulationData.mDeferredQstZ[jointDatum.jointOffset]); + } void FeatherstoneArticulation::solveInternalFixedTendonConstraints(bool isTGS) { @@ -5311,7 +5380,6 @@ namespace Dy return; { - //Update the error terms in the tendons recursively... const PxU32 nbTendons = mArticulationData.mNumFixedTendons; @@ -5338,7 +5406,6 @@ namespace Dy Cm::SpatialVectorF parentDeltaV = parentV - mArticulationData.mMotionVelocities[startLink]; - PxVec3 velError(0.f); for (ArticulationAttachmentBitField children = pTendonJoint.children; children != 0; children &= (children - 1)) @@ -5353,7 +5420,6 @@ namespace Dy solveData.error = tendon->mError; solveData.tendonJoints = tendonJoints; - velError += calculateFixedTendonVelocityAndPositionRecursive(solveData, parentV, parentDeltaV, child); } @@ -5396,21 +5462,21 @@ namespace Dy for (PxU32 linkID = pTendonJoint.linkInd; linkID; linkID = links[linkID].parent) { const PxU32 jointOffset = mArticulationData.getJointData(linkID).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(linkID).dof; + const PxU8 dofCount = mArticulationData.getJointData(linkID).dof; - Z = propagateImpulseW(&mArticulationData.mIsInvDW[jointOffset], mArticulationData.getRw(linkID), - &mArticulationData.mWorldMotionMatrix[jointOffset], Z, dofCount, &mArticulationData.mDeferredQstZ[jointOffset]); + Z = propagateImpulseW( + mArticulationData.getRw(linkID), + Z, + &mArticulationData.mISInvStIS[jointOffset], &mArticulationData.mWorldMotionMatrix[jointOffset], dofCount, + &mArticulationData.mDeferredQstZ[jointOffset]); } mArticulationData.mRootDeferredZ += Z; mArticulationData.mJointDirty = true; - } } - } - void FeatherstoneArticulation::solveInternalConstraints(const PxReal dt, const PxReal invDt, Cm::SpatialVectorF* impulses, Cm::SpatialVectorF* DeltaV, bool velocityIteration, bool isTGS, const PxReal elapsedTime, const PxReal biasCoefficient) @@ -5571,7 +5637,6 @@ namespace Dy } } - PxU8* FeatherstoneArticulation::allocateScratchSpatialData(PxcScratchAllocator* allocator, const PxU32 linkCount, ScratchData& scratchData, bool fallBackToHeap) { @@ -5615,6 +5680,5 @@ namespace Dy }*/ - }//namespace Dy } diff --git a/physx/source/lowleveldynamics/src/DyFeatherstoneForwardDynamic.cpp b/physx/source/lowleveldynamics/src/DyFeatherstoneForwardDynamic.cpp index 47424dca8..b332a038b 100644 --- a/physx/source/lowleveldynamics/src/DyFeatherstoneForwardDynamic.cpp +++ b/physx/source/lowleveldynamics/src/DyFeatherstoneForwardDynamic.cpp @@ -38,7 +38,6 @@ #include "DyArticulationPImpl.h" #include "DyFeatherstoneArticulationLink.h" #include "DyFeatherstoneArticulationJointData.h" -#include "PxsIslandSim.h" #include "common/PxProfileZone.h" #include @@ -53,45 +52,6 @@ namespace Dy { void PxcFsFlushVelocity(FeatherstoneArticulation& articulation, Cm::SpatialVectorF* deltaV, bool computeSpatialForces); - //initialize spatial articualted matrix and coriolis spatial force - void FeatherstoneArticulation::initLinks(ArticulationData& data, - const PxVec3& /*gravity*/, ScratchData& scratchData, Cm::SpatialVectorF* Z, - Cm::SpatialVectorF* DeltaV) - { - PX_UNUSED(Z); - PX_UNUSED(DeltaV); - //compute individual link's spatial inertia tensor - //[0, M] - //[I, 0] - //computeSpatialInertia(data); - - //compute individual zero acceleration force - //computeZD(data, gravity, scratchData); - //compute corolis and centrifugal force - //computeC(data, scratchData); - - if (data.mLinkCount > 1) - { - Cm::SpatialVectorF* za = mArticulationData.getTransmittedForces(); - //copy individual zero acceleration force to mTempData zaForce buffer - //PxMemCopy(za, mArticulationData.getSpatialZAVectors(), sizeof(Cm::SpatialVectorF) * mArticulationData.getLinkCount()); - for (PxU32 linkID = 0; linkID < mArticulationData.getLinkCount(); ++linkID) - { - za[linkID] = mArticulationData.mZAForces[linkID] + mArticulationData.mZAInternalForces[linkID]; - } - } - - computeArticulatedSpatialInertiaAndZ(data, scratchData); - //computeArticulatedSpatialInertia(data); - //computeArticulatedSpatialZ(data, scratchData); - - computeArticulatedResponseMatrix(data); - - /*computeJointSpaceJacobians(data); - - computeJointSpaceDeltaV2(data);*/ - } - #if (FEATHERSTONE_DEBUG && (PX_DEBUG || PX_CHECKED)) static bool isSpatialVectorEqual(Cm::SpatialVectorF& t0, Cm::SpatialVectorF& t1) { @@ -118,23 +78,6 @@ namespace Dy } #endif - //calculate Is - void FeatherstoneArticulation::computeIs(ArticulationJointCoreData& jointDatum, ArticulationJointTargetData& /*jointTarget*/, - const PxU32 linkID) - { - Cm::SpatialVectorF* IsW = &mArticulationData.mIsW[jointDatum.jointOffset]; - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) - { - //const Cm::UnAlignedSpatialVector spatialArmature = mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset + ind] * (1.f + jointTarget.armature[ind]); - //const Cm::UnAlignedSpatialVector tmp = mArticulationData.mWorldSpatialArticulatedInertia[linkID] * spatialArmature; - - const Cm::UnAlignedSpatialVector tmp = mArticulationData.mWorldSpatialArticulatedInertia[linkID] * mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset + ind]; - //const Cm::UnAlignedSpatialVector arm = mArticulationData.mWorldMotionMatrix[jointDatum.jointOffset + ind] * jointTarget.armature[ind]; - IsW[ind].top = tmp.top;// +arm.bottom; - IsW[ind].bottom = tmp.bottom;// +arm.top; - } - } - #if FEATHERSTONE_DEBUG static inline PxMat33 Outer(const PxVec3& a, const PxVec3& b) { @@ -142,20 +85,60 @@ namespace Dy } #endif - SpatialMatrix FeatherstoneArticulation::computePropagateSpatialInertia_ZA_ZIc(const PxU8 jointType, const ArticulationJointTargetData& jointTarget, const ArticulationJointCoreData& jointDatum, - const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, Cm::SpatialVectorF* isInvD, const Cm::UnAlignedSpatialVector* motionMatrix, - const PxReal* jF, const Cm::SpatialVectorF& Z, const Cm::SpatialVectorF& ZIntIc, Cm::SpatialVectorF& ZA, Cm::SpatialVectorF& ZAInt, PxReal* qstZ, - PxReal* qstZIntIc) + SpatialMatrix FeatherstoneArticulation::computePropagateSpatialInertia_ZA_ZIc + (const PxArticulationJointType::Enum jointType, const PxU8 nbJointDofs, + const Cm::UnAlignedSpatialVector* jointMotionMatricesW, const Cm::SpatialVectorF* jointISW, + const PxReal* jointTargetArmatures, const PxReal* jointExternalForces, + const SpatialMatrix& linkArticulatedInertiaW, + const Cm::SpatialVectorF& linkZExtW, const Cm::SpatialVectorF& linkZIntIcW, + InvStIs& linkInvStISW, Cm::SpatialVectorF* jointDofISInvStISW, + PxReal* jointDofMinusStZExtW, PxReal* jointDofQStZIntIcW, + Cm::SpatialVectorF& deltaZAExtParent, Cm::SpatialVectorF& deltaZAIntIcParent) { - SpatialMatrix spatialInertia; + deltaZAExtParent = linkZExtW; + deltaZAIntIcParent = linkZIntIcW; + + // The goal is to propagate the articulated z.a force of a child link to the articulated z.a. force of its parent link. + // We will compute a term that can be added to the articulated z.a. force of the parent link. + + // This function only references the child link. + // Mirtich uses the notation i for the child and i-1 for the parent. + // We have a more general configuration that allows a parent to have multiple children but in what follows "i" shall refer to the + // child and "i-1" to the parent. + + // Another goal is to propagate the articulated spatial inertia from the child link to the parent link. + // We will compute a term that can be added to the articulated spatial inertia of the parent link. + // The Mirtich equivalent is: + // I_i^A - [I_i^A * s_i^T *Inv(s_i^T *I_i^A * s_i) * s_i^T * I_i^A] + + //The term that is to be added to the parent link has the Mirtich formulation: + // Delta_Z_i-1 = (Z_i^A + I_i^A * c_i) + [I_i^A * s_i]*[Q_i - s_i^T * (Z_i^A + I_i^A * c_i)]/[s_i^T * I_i^A * s_i] + + //We do not have a single articulated z.a. force as outlined in Mirtich. + //Instead we have a term that accounts for external forces and a term that accounts for internal forces. + + //We can generalise the Mirtich formulate to account for internal and external terms: + // Delta_ZExt_i-1 = ZAExt_i + [I_i^A * s_i] * [-s_i^T * ZAExt_i]/[s_i^T * I_i^A * s_i] + // Delta_ZInt_i-1 = ZAInt_i + I_i^A * c_i + [I_i^A * s_i] * [Q_i - s_i^T * (ZAInt_i + I_i^A * c_i)]/[s_i^T * I_i^A * s_i] + // Delta_Z_i-1 = Delta_ZExt_i-1 + Delta_ZInt_i-1 + + //We have function input arguments ZExt and ZIntIc. + //In Mirtich terms these are ZAExt_i and ZAInt_i + I_i^A * c_i. + //Using the function arguments here we have: + // Delta_ZExt_i-1 = ZAExt + [I_i^A * s_i] * [-s_i^T * ZAExt]/[s_i^T * I_i^A * s_i] + // Delta_ZInt_i-1 = ZAIntIc + [I_i^A * s_i] * [Q_i - s_i^T * ZAIntIc]/[s_i^T * I_i^A * s_i] + + //Isn't it odd that we add Q_i to the internal term rather than the external term? + + SpatialMatrix spatialInertia; switch (jointType) { case PxArticulationJointType::ePRISMATIC: case PxArticulationJointType::eREVOLUTE: case PxArticulationJointType::eREVOLUTE_UNWRAPPED: { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[0]; + const Cm::UnAlignedSpatialVector& sa = jointMotionMatricesW[0]; #if FEATHERSTONE_DEBUG PxVec3 u = (jointType == PxArticulationJointType::ePRISMATIC) ? sa.bottom : sa.top; @@ -165,38 +148,43 @@ namespace Dy const PxReal armature = u.dot(armatureV * u); #endif - const Cm::SpatialVectorF& Is = linkIs[0]; - - const PxReal stIs = (sa.innerProduct(Is) + jointTarget.armature[0]); + const Cm::SpatialVectorF& Is = jointISW[0]; - const PxReal iStIs = ((stIs > 0.f) ? (1.f / stIs) : 0.f); - - invStIs.invStIs[0][0] = iStIs; - - Cm::SpatialVectorF isID = Is * iStIs; + //Mirtich equivalent: 1/[s_i^T * I_i^A * s_i] + PxReal invStIS; + { + const PxReal stIs = (sa.innerProduct(Is) + jointTargetArmatures[0]); + invStIS = ((stIs > 0.f) ? (1.f / stIs) : 0.f); + } + linkInvStISW.invStIs[0][0] = invStIS; - isInvD[0] = isID; + //Mirtich equivalent: [I_i^A * s_i]/[s_i^T * I_i^A * s_i] + Cm::SpatialVectorF isID = Is * invStIS; + jointDofISInvStISW[0] = isID; //(6x1)Is = [v0, v1]; (1x6)stI = [v1, v0] //Cm::SpatialVector stI1(Is1.angular, Is1.linear); Cm::SpatialVectorF stI(Is.bottom, Is.top); + //Mirtich equivalent: I_i^A * s_i^T *Inv(s_i^T *I_i^A * s_i) * s_i^T * I_i^A + //Note we will compute I_i^A - [I_i^A * s_i^T *Inv(s_i^T *I_i^A * s_i) * s_i^T * I_i^A] later in the function. spatialInertia = SpatialMatrix::constructSpatialMatrix(isID, stI); - const PxReal stZ = sa.innerProduct(Z); - const PxReal stZInt = sa.innerProduct(ZIntIc); - - //link.qstZIc[ind] = jF[ind] - stZ; - const PxReal qstZF32 = -stZ; - qstZ[0] = qstZF32; - - //Joint forces should be momentum preserving, so we add them to the biased system to maintain overall system momentum - const PxReal qstZF32Int = jF[0] - stZInt; - qstZIntIc[0] = qstZF32Int; - - ZA += isID * qstZF32; + //[I_i^A * s_i] * [-s_i^T * ZAExt]/[s_i^T * I_i^A * s_i] + { + const PxReal innerprod = sa.innerProduct(linkZExtW); + const PxReal diff = -innerprod; + jointDofMinusStZExtW[0] = diff; + deltaZAExtParent += isID * diff; + } - ZAInt += isID * qstZF32Int; + //[I_i^A * s_i] * [Q_i - s_i^T * ZAIntIc]/[s_i^T * I_i^A * s_i] + { + const PxReal innerprod = sa.innerProduct(linkZIntIcW); + const PxReal diff = jointExternalForces[0] - innerprod; + jointDofQStZIntIcW[0] = diff; + deltaZAIntIcParent += isID * diff; + } break; } @@ -220,7 +208,7 @@ namespace Dy } #endif PxMat33 D(PxIdentity); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { #if FEATHERSTONE_DEBUG @@ -230,9 +218,9 @@ namespace Dy PxVec3 armatureU = armatureV * u; #endif - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind2]; + const Cm::UnAlignedSpatialVector& sa = jointMotionMatricesW[ind2]; #if FEATHERSTONE_DEBUG const PxVec3 u1 = sa.top; @@ -240,19 +228,19 @@ namespace Dy const PxReal armature = u1.dot(armatureU); #endif - D[ind][ind2] = sa.innerProduct(linkIs[ind]); + D[ind][ind2] = sa.innerProduct(jointISW[ind]); } - D[ind][ind] += jointTarget.armature[ind]; + D[ind][ind] += jointTargetArmatures[ind]; } //PxMat33 invD = SpatialMatrix::invertSym33(D); PxMat33 invD = D.getInverse(); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { - invStIs.invStIs[ind][ind2] = invD[ind][ind2]; + linkInvStISW.invStIs[ind][ind2] = invD[ind][ind2]; } } @@ -268,35 +256,35 @@ namespace Dy columns[3] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); columns[4] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); columns[5] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { Cm::SpatialVectorF isID(PxVec3(0.f), PxVec3(0.f)); - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind]; + const Cm::UnAlignedSpatialVector& sa = jointMotionMatricesW[ind]; - const PxReal stZ = sa.innerProduct(Z); - const PxReal stZInt = sa.innerProduct(ZIntIc); + const PxReal stZ = sa.innerProduct(linkZExtW); + const PxReal stZInt = sa.innerProduct(linkZIntIcW); //link.qstZIc[ind] = jF[ind] - stZ; const PxReal localQstZ = - stZ; - const PxReal localQstZInt = jF[ind] -stZInt; - qstZ[ind] = localQstZ; - qstZIntIc[ind] = localQstZInt; + const PxReal localQstZInt = jointExternalForces[ind] -stZInt; + jointDofMinusStZExtW[ind] = localQstZ; + jointDofQStZIntIcW[ind] = localQstZInt; - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { - const Cm::SpatialVectorF& Is = linkIs[ind2]; + const Cm::SpatialVectorF& Is = jointISW[ind2]; isID += Is * invD[ind][ind2]; } - columns[0] += isID * linkIs[ind].bottom.x; - columns[1] += isID * linkIs[ind].bottom.y; - columns[2] += isID * linkIs[ind].bottom.z; - columns[3] += isID * linkIs[ind].top.x; - columns[4] += isID * linkIs[ind].top.y; - columns[5] += isID * linkIs[ind].top.z; - isInvD[ind] = isID; + columns[0] += isID * jointISW[ind].bottom.x; + columns[1] += isID * jointISW[ind].bottom.y; + columns[2] += isID * jointISW[ind].bottom.z; + columns[3] += isID * jointISW[ind].top.x; + columns[4] += isID * jointISW[ind].top.y; + columns[5] += isID * jointISW[ind].top.z; + jointDofISInvStISW[ind] = isID; - ZA += isID * localQstZ; - ZAInt += isID * localQstZInt; + deltaZAExtParent += isID * localQstZ; + deltaZAIntIcParent += isID * localQstZInt; #if FEATHERSTONE_DEBUG const bool equal = bigIsInvD.isColumnEqual(ind, isInvD.isInvD[ind]); @@ -316,20 +304,49 @@ namespace Dy break; } default: - return articulatedInertia; + return linkArticulatedInertiaW; } //(I - Is*Inv(sIs)*sI) - spatialInertia = articulatedInertia - spatialInertia; + spatialInertia = linkArticulatedInertiaW - spatialInertia; return spatialInertia; } - - SpatialMatrix FeatherstoneArticulation::computePropagateSpatialInertia_ZA_ZIc_NonSeparated(const PxU8 jointType, const ArticulationJointTargetData& jointTarget, const ArticulationJointCoreData& jointDatum, - const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, Cm::SpatialVectorF* isInvD, const Cm::UnAlignedSpatialVector* motionMatrix, - const PxReal* jF, const Cm::SpatialVectorF& Z, Cm::SpatialVectorF& ZA, PxReal* qstZIc) + SpatialMatrix FeatherstoneArticulation::computePropagateSpatialInertia_ZA_ZIc_NonSeparated + (const PxArticulationJointType::Enum jointType, const PxU8 nbJointDofs, + const Cm::UnAlignedSpatialVector* jointMotionMatrices, const Cm::SpatialVectorF* jointIs, + const PxReal* jointTargetArmatures, const PxReal* jointExternalForces, + const SpatialMatrix& articulatedInertia, + const Cm::SpatialVectorF& ZIc, + InvStIs& invStIs, Cm::SpatialVectorF* isInvD, + PxReal* qstZIc, + Cm::SpatialVectorF& deltaZParent) { + deltaZParent = ZIc; + + // The goal is to propagate the articulated z.a force of a child link to the articulated z.a. force of its parent link. + // We will compute a term that can be added to the articulated z.a. force of the parent link. + + // This function only references the child link. + // Mirtich uses the notation i for the child and i-1 for the parent. + // We have a more general configuration that allows a parent to have multiple children but in what follows "i" shall refer to the + // child and "i-1" to the parent. + + // Another goal is to propagate the articulated spatial inertia from the child link to the parent link. + // We will compute a term that can be added to the articulated spatial inertia of the parent link. + // The Mirtich equivalent is: + // I_i^A - [I_i^A * s_i^T *Inv(s_i^T *I_i^A * s_i) * s_i^T * I_i^A] + + //The term that is to be added to the parent link has the Mirtich formulation: + // Delta_Z_i-1 = (Z_i^A + I_i^A * c_i) + [I_i^A * s_i]*[Q_i - s_i^T * (Z_i^A + I_i^A * c_i)]/[s_i^T * I_i^A * s_i] + + //We have function input arguments ZIntIc. + //In Mirtich terms this is: Z_i + I_i^A * c_i. + + //Using the function arguments here we have: + // Delta_Z_i-1 = ZIc + [I_i^A * s_i] * [Q_i - s_i^T * ZIc]/[s_i^T * I_i^A * s_i] + SpatialMatrix spatialInertia; switch (jointType) @@ -338,7 +355,7 @@ namespace Dy case PxArticulationJointType::eREVOLUTE: case PxArticulationJointType::eREVOLUTE_UNWRAPPED: { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[0]; + const Cm::UnAlignedSpatialVector& sa = jointMotionMatrices[0]; #if FEATHERSTONE_DEBUG PxVec3 u = (jointType == PxArticulationJointType::ePRISMATIC) ? sa.bottom : sa.top; @@ -348,31 +365,35 @@ namespace Dy const PxReal armature = u.dot(armatureV * u); #endif - const Cm::SpatialVectorF& Is = linkIs[0]; - - const PxReal stIs = (sa.innerProduct(Is) + jointTarget.armature[0]); - - const PxReal iStIs = (stIs > 1e-10f) ? (1.f / stIs) : 0.f; + const Cm::SpatialVectorF& Is = jointIs[0]; + //Mirtich equivalent: 1/[s_i^T * I_i^A * s_i] + PxReal iStIs; + { + const PxReal stIs = (sa.innerProduct(Is) + jointTargetArmatures[0]); + iStIs = (stIs > 1e-10f) ? (1.f / stIs) : 0.f; + } invStIs.invStIs[0][0] = iStIs; + //Mirtich equivalent: [I_i^A * s_i]/[s_i^T * I_i^A * s_i] Cm::SpatialVectorF isID = Is * iStIs; - isInvD[0] = isID; //(6x1)Is = [v0, v1]; (1x6)stI = [v1, v0] //Cm::SpatialVector stI1(Is1.angular, Is1.linear); Cm::SpatialVectorF stI(Is.bottom, Is.top); + //Mirtich equivalent: I_i^A * s_i^T *[1/(s_i^T *I_i^A * s_i)] * s_i^T * I_i^A + //Note we will compute I_i^A - [I_i^A * s_i^T *[1/(s_i^T *I_i^A * s_i)] * s_i^T * I_i^A] later in the function. spatialInertia = SpatialMatrix::constructSpatialMatrix(isID, stI); - const PxReal stZ = sa.innerProduct(Z); - - //link.qstZIc[ind] = jF[ind] - stZ; - const PxReal qstZIcF32 = jF[0] - stZ; - qstZIc[0] = qstZIcF32; - - ZA += isID * qstZIcF32; + //Mirtich equivalent: [I_i^A * s_i] * [-s_i^T * Z_i^A]/[s_i^T * I_i^A * s_i] + { + const PxReal innerProd = sa.innerProduct(ZIc); + const PxReal diff = jointExternalForces[0] - innerProd; + qstZIc[0] = diff; + deltaZParent += isID * diff; + } break; } @@ -396,7 +417,7 @@ namespace Dy } #endif PxMat33 D(PxIdentity); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { #if FEATHERSTONE_DEBUG @@ -406,9 +427,9 @@ namespace Dy PxVec3 armatureU = armatureV * u; #endif - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind2]; + const Cm::UnAlignedSpatialVector& sa = jointMotionMatrices[ind2]; #if FEATHERSTONE_DEBUG const PxVec3 u1 = sa.top; @@ -416,16 +437,16 @@ namespace Dy const PxReal armature = u1.dot(armatureU); #endif - D[ind][ind2] = sa.innerProduct(linkIs[ind]); + D[ind][ind2] = sa.innerProduct(jointIs[ind]); } - D[ind][ind] += jointTarget.armature[ind]; + D[ind][ind] += jointTargetArmatures[ind]; //D[ind][ind] *= 10.f; } PxMat33 invD = SpatialMatrix::invertSym33(D); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { invStIs.invStIs[ind][ind2] = invD[ind][ind2]; @@ -444,31 +465,31 @@ namespace Dy columns[3] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); columns[4] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); columns[5] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { Cm::SpatialVectorF isID(PxVec3(0.f), PxVec3(0.f)); - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind]; + const Cm::UnAlignedSpatialVector& sa = jointMotionMatrices[ind]; - const PxReal stZ = sa.innerProduct(Z); + const PxReal stZ = sa.innerProduct(ZIc); //link.qstZIc[ind] = jF[ind] - stZ; - const PxReal localQstZ = jF[ind] - stZ; + const PxReal localQstZ = jointExternalForces[ind] - stZ; qstZIc[ind] = localQstZ; - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { - const Cm::SpatialVectorF& Is = linkIs[ind2]; + const Cm::SpatialVectorF& Is = jointIs[ind2]; isID += Is * invD[ind][ind2]; } - columns[0] += isID * linkIs[ind].bottom.x; - columns[1] += isID * linkIs[ind].bottom.y; - columns[2] += isID * linkIs[ind].bottom.z; - columns[3] += isID * linkIs[ind].top.x; - columns[4] += isID * linkIs[ind].top.y; - columns[5] += isID * linkIs[ind].top.z; + columns[0] += isID * jointIs[ind].bottom.x; + columns[1] += isID * jointIs[ind].bottom.y; + columns[2] += isID * jointIs[ind].bottom.z; + columns[3] += isID * jointIs[ind].top.x; + columns[4] += isID * jointIs[ind].top.y; + columns[5] += isID * jointIs[ind].top.z; isInvD[ind] = isID; - ZA += isID * localQstZ; + deltaZParent += isID * localQstZ; #if FEATHERSTONE_DEBUG const bool equal = bigIsInvD.isColumnEqual(ind, isInvD.isInvD[ind]); @@ -499,8 +520,11 @@ namespace Dy } - SpatialMatrix FeatherstoneArticulation::computePropagateSpatialInertia(const PxU8 jointType, ArticulationJointCoreData& jointDatum, - const SpatialMatrix& articulatedInertia, const Cm::SpatialVectorF* linkIs, InvStIs& invStIs, Cm::SpatialVectorF* isInvD, const Cm::UnAlignedSpatialVector* motionMatrix) + SpatialMatrix FeatherstoneArticulation::computePropagateSpatialInertia( + const PxArticulationJointType::Enum jointType, const PxU8 nbDofs, + const SpatialMatrix& articulatedInertia, const Cm::UnAlignedSpatialVector* motionMatrices, + const Cm::SpatialVectorF* linkIs, + InvStIs& invStIs, Cm::SpatialVectorF* isInvD) { SpatialMatrix spatialInertia; @@ -510,7 +534,7 @@ namespace Dy case PxArticulationJointType::eREVOLUTE: case PxArticulationJointType::eREVOLUTE_UNWRAPPED: { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[0]; + const Cm::UnAlignedSpatialVector& sa = motionMatrices[0]; const Cm::SpatialVectorF& Is = linkIs[0]; @@ -552,19 +576,19 @@ namespace Dy } #endif PxMat33 D(PxIdentity); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU8 ind = 0; ind < nbDofs; ++ind) { - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU8 ind2 = 0; ind2 < nbDofs; ++ind2) { - const Cm::UnAlignedSpatialVector& sa = motionMatrix[ind2]; + const Cm::UnAlignedSpatialVector& sa = motionMatrices[ind2]; D[ind][ind2] = sa.innerProduct(linkIs[ind]); } } PxMat33 invD = SpatialMatrix::invertSym33(D); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU8 ind = 0; ind < nbDofs; ++ind) { - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU8 ind2 = 0; ind2 < nbDofs; ++ind2) { invStIs.invStIs[ind][ind2] = invD[ind][ind2]; @@ -583,11 +607,11 @@ namespace Dy columns[3] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); columns[4] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); columns[5] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + for (PxU8 ind = 0; ind < nbDofs; ++ind) { Cm::SpatialVectorF isID(PxVec3(0.f), PxVec3(0.f)); - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU8 ind2 = 0; ind2 < nbDofs; ++ind2) { const Cm::SpatialVectorF& Is = linkIs[ind2]; isID += Is * invD[ind][ind2]; @@ -628,152 +652,209 @@ namespace Dy return spatialInertia; } - void FeatherstoneArticulation::computeArticulatedSpatialInertiaAndZ(ArticulationData& data, ScratchData& scratchData) + void FeatherstoneArticulation::computeArticulatedSpatialInertiaAndZ + (const ArticulationLink* links, const PxU32 linkCount, const PxVec3* linkRsW, + const ArticulationJointCoreData* jointData, const ArticulationJointTargetData* jointTargetData, + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const Cm::SpatialVectorF* linkCoriolisVectors, const PxReal* jointDofForces, + Cm::SpatialVectorF* jointDofISW, InvStIs* linkInvStISW, Cm::SpatialVectorF* jointDofISInvStISW, PxReal* jointDofMinusStZExtW, PxReal* jointDofQStZIntIcW, + Cm::SpatialVectorF* linkZAExtForcesW, Cm::SpatialVectorF* linkZAIntForcesW, SpatialMatrix* linkSpatialArticulatedInertiaW, + SpatialMatrix& baseInvSpatialArticulatedInertiaW) { - ArticulationLink* links = data.getLinks(); - ArticulationJointCoreData* jointData = data.getJointData(); - ArticulationJointTargetData* jointTargetData = data.getJointTranData(); - const PxU32 linkCount = data.getLinkCount(); const PxU32 startIndex = PxU32(linkCount - 1); - Cm::SpatialVectorF* coriolisVectors = scratchData.coriolisVectors; - Cm::SpatialVectorF* articulatedZA = scratchData.spatialZAVectors; - Cm::SpatialVectorF* articulatedZAInt = data.mZAInternalForces.begin(); - - PxReal* jointForces = scratchData.jointForces; - for (PxU32 linkID = startIndex; linkID > 0; --linkID) { - ArticulationLink& link = links[linkID]; - - ArticulationJointCoreData& jointDatum = jointData[linkID]; - ArticulationJointTargetData& jointTarget = jointTargetData[linkID]; - computeIs(jointDatum, jointTarget, linkID); - - //calculate spatial zero acceleration force, this can move out of the loop - Cm::SpatialVectorF Ic = data.mWorldSpatialArticulatedInertia[linkID] * coriolisVectors[linkID]; - Cm::SpatialVectorF Z = articulatedZA[linkID];// + Ic; - Cm::SpatialVectorF ZIntIc = articulatedZAInt[linkID] + Ic; - - const PxReal* jF = &jointForces[jointDatum.jointOffset]; - - Cm::SpatialVectorF ZA = Z; - Cm::SpatialVectorF ZAIntIc = ZIntIc; + const ArticulationLink& link = links[linkID]; + const ArticulationJointCoreData& jointDatum = jointData[linkID]; + const PxU32 jointOffset = jointDatum.jointOffset; + const PxU8 nbDofs = jointDatum.dof; - //(I - Is*Inv(sIs)*sI) - //KS - we also bury Articulated ZA force and ZIc force computation in here because that saves - //us some round-trips to memory! - SpatialMatrix spatialInertiaW = computePropagateSpatialInertia_ZA_ZIc(link.inboundJoint->jointType, jointTarget, - jointDatum, data.mWorldSpatialArticulatedInertia[linkID], &data.mIsW[jointDatum.jointOffset], data.mInvStIs[linkID], &data.mIsInvDW[jointDatum.jointOffset], - &data.mWorldMotionMatrix[jointDatum.jointOffset], jF, Z, ZIntIc, ZA, ZAIntIc, &data.qstZIc[jointDatum.jointOffset], &data.qstZIntIc[jointDatum.jointOffset]); + for (PxU8 ind = 0; ind < nbDofs; ++ind) + { + const Cm::UnAlignedSpatialVector tmp = linkSpatialArticulatedInertiaW[linkID] * jointDofMotionMatricesW[jointOffset + ind]; + jointDofISW[jointOffset + ind].top = tmp.top; + jointDofISW[jointOffset + ind].bottom = tmp.bottom; + } - //transform spatial inertia into parent space - FeatherstoneArticulation::translateInertia(constructSkewSymmetricMatrix(data.getRw(linkID)), spatialInertiaW); + //Compute the terms to accumulate on the parent's articulated z.a force and articulated spatial inertia. + Cm::SpatialVectorF deltaZAExtParent; + Cm::SpatialVectorF deltaZAIntParent; + SpatialMatrix spatialInertiaW; + { + //calculate spatial zero acceleration force, this can move out of the loop + const Cm::SpatialVectorF linkZW = linkZAExtForcesW[linkID]; + const Cm::SpatialVectorF linkIcW = linkSpatialArticulatedInertiaW[linkID] * linkCoriolisVectors[linkID]; + const Cm::SpatialVectorF linkZIntIcW = linkZAIntForcesW[linkID] + linkIcW; + + //(I - Is*Inv(sIs)*sI) + //KS - we also bury Articulated ZA force and ZIc force computation in here because that saves + //us some round-trips to memory! + spatialInertiaW = + computePropagateSpatialInertia_ZA_ZIc( + PxArticulationJointType::Enum(link.inboundJoint->jointType), jointDatum.dof, + &jointDofMotionMatricesW[jointOffset], &jointDofISW[jointOffset], + jointTargetData[linkID].armature, &jointDofForces[jointOffset], + linkSpatialArticulatedInertiaW[linkID], + linkZW, linkZIntIcW, + linkInvStISW[linkID], &jointDofISInvStISW[jointOffset], + &jointDofMinusStZExtW[jointOffset], &jointDofQStZIntIcW[jointOffset], + deltaZAExtParent, deltaZAIntParent); + } - const PxReal minPropagatedInertia = 0.f; + //Accumulate the spatial inertia on the parent link. + { + //transform spatial inertia into parent space + FeatherstoneArticulation::translateInertia(constructSkewSymmetricMatrix(linkRsW[linkID]), spatialInertiaW); - // Make sure we do not propagate up negative inertias around the principal inertial axes - // due to numerical rounding errors - spatialInertiaW.bottomLeft.column0.x = PxMax(minPropagatedInertia, spatialInertiaW.bottomLeft.column0.x); - spatialInertiaW.bottomLeft.column1.y = PxMax(minPropagatedInertia, spatialInertiaW.bottomLeft.column1.y); - spatialInertiaW.bottomLeft.column2.z = PxMax(minPropagatedInertia, spatialInertiaW.bottomLeft.column2.z); + // Make sure we do not propagate up negative inertias around the principal inertial axes + // due to numerical rounding errors + const PxReal minPropagatedInertia = 0.f; + spatialInertiaW.bottomLeft.column0.x = PxMax(minPropagatedInertia, spatialInertiaW.bottomLeft.column0.x); + spatialInertiaW.bottomLeft.column1.y = PxMax(minPropagatedInertia, spatialInertiaW.bottomLeft.column1.y); + spatialInertiaW.bottomLeft.column2.z = PxMax(minPropagatedInertia, spatialInertiaW.bottomLeft.column2.z); - data.mWorldSpatialArticulatedInertia[link.parent] += spatialInertiaW; + linkSpatialArticulatedInertiaW[link.parent] += spatialInertiaW; + } - Cm::SpatialVectorF translatedZA = FeatherstoneArticulation::translateSpatialVector(data.getRw(linkID), ZA); - Cm::SpatialVectorF translatedZAInt = FeatherstoneArticulation::translateSpatialVector(data.getRw(linkID), ZAIntIc); - articulatedZA[link.parent] += translatedZA; - articulatedZAInt[link.parent] += translatedZAInt; + //Accumulate the articulated z.a force on the parent link. + { + Cm::SpatialVectorF translatedZA = FeatherstoneArticulation::translateSpatialVector(linkRsW[linkID], deltaZAExtParent); + Cm::SpatialVectorF translatedZAInt = FeatherstoneArticulation::translateSpatialVector(linkRsW[linkID], deltaZAIntParent); + linkZAExtForcesW[link.parent] += translatedZA; + linkZAIntForcesW[link.parent] += translatedZAInt; + } } //cache base link inverse spatial inertia - data.mWorldSpatialArticulatedInertia[0].invertInertiaV(data.mBaseInvSpatialArticulatedInertiaW); + linkSpatialArticulatedInertiaW[0].invertInertiaV(baseInvSpatialArticulatedInertiaW); } void FeatherstoneArticulation::computeArticulatedSpatialInertiaAndZ_NonSeparated(ArticulationData& data, ScratchData& scratchData) { - ArticulationLink* links = data.getLinks(); + const ArticulationLink* links = data.getLinks(); ArticulationJointCoreData* jointData = data.getJointData(); ArticulationJointTargetData* jointTargetData = data.getJointTranData(); + SpatialMatrix* spatialArticulatedInertia = data.getWorldSpatialArticulatedInertia(); + const Cm::UnAlignedSpatialVector* motionMatrix = data.getWorldMotionMatrix(); + Cm::SpatialVectorF* Is = data.getIsW(); + + InvStIs* invStIs = data.getInvStIS(); + Cm::SpatialVectorF* IsInvDW = data.getISInvStIS(); + PxReal* qstZIc = data.getQstZIc(); + + SpatialMatrix& baseInvSpatialArticulatedInertia = data.getBaseInvSpatialArticulatedInertiaW(); + const PxU32 linkCount = data.getLinkCount(); const PxU32 startIndex = PxU32(linkCount - 1); Cm::SpatialVectorF* coriolisVectors = scratchData.coriolisVectors; Cm::SpatialVectorF* articulatedZA = scratchData.spatialZAVectors; - PxReal* jointForces = scratchData.jointForces; - for (PxU32 linkID = startIndex; linkID > 0; --linkID) { - ArticulationLink& link = links[linkID]; + const ArticulationLink& link = links[linkID]; ArticulationJointCoreData& jointDatum = jointData[linkID]; + const PxU32 jointOffset = jointDatum.jointOffset; + const PxU8 nbDofs = jointDatum.dof; ArticulationJointTargetData& jointTarget = jointTargetData[linkID]; - computeIs(jointDatum, jointTarget, linkID); - - //calculate spatial zero acceleration force, this can move out of the loop - Cm::SpatialVectorF Ic = data.mWorldSpatialArticulatedInertia[linkID] * coriolisVectors[linkID]; - Cm::SpatialVectorF Z = articulatedZA[linkID] + Ic; - - const PxReal* jF = &jointForces[jointDatum.jointOffset]; - Cm::SpatialVectorF ZA = Z; + for (PxU8 ind = 0; ind < nbDofs; ++ind) + { + const Cm::UnAlignedSpatialVector tmp = spatialArticulatedInertia[linkID] * motionMatrix[jointOffset + ind]; + Is[jointOffset + ind].top = tmp.top; + Is[jointOffset + ind].bottom = tmp.bottom; + } - //(I - Is*Inv(sIs)*sI) - //KS - we also bury Articulated ZA force and ZIc force computation in here because that saves - //us some round-trips to memory! - SpatialMatrix spatialInertiaW = computePropagateSpatialInertia_ZA_ZIc_NonSeparated(link.inboundJoint->jointType, jointTarget, - jointDatum, data.mWorldSpatialArticulatedInertia[linkID], &data.mIsW[jointDatum.jointOffset], data.mInvStIs[linkID], &data.mIsInvDW[jointDatum.jointOffset], - &data.mWorldMotionMatrix[jointDatum.jointOffset], jF, Z, ZA, &data.qstZIc[jointDatum.jointOffset]); + //calculate spatial zero acceleration force, this can move out of the loop + Cm::SpatialVectorF deltaZParent; + SpatialMatrix spatialInertiaW; + { + Cm::SpatialVectorF Ic = spatialArticulatedInertia[linkID] * coriolisVectors[linkID]; + Cm::SpatialVectorF Z = articulatedZA[linkID] + Ic; + + //(I - Is*Inv(sIs)*sI) + //KS - we also bury Articulated ZA force and ZIc force computation in here because that saves + //us some round-trips to memory! + spatialInertiaW = computePropagateSpatialInertia_ZA_ZIc_NonSeparated( + PxArticulationJointType::Enum(link.inboundJoint->jointType), jointDatum.dof, + &motionMatrix[jointDatum.jointOffset], &Is[jointDatum.jointOffset], + jointTarget.armature, &scratchData.jointForces[jointDatum.jointOffset], + spatialArticulatedInertia[linkID], + Z, + invStIs[linkID], &IsInvDW[jointDatum.jointOffset], + &qstZIc[jointDatum.jointOffset], + deltaZParent); + } //transform spatial inertia into parent space FeatherstoneArticulation::translateInertia(constructSkewSymmetricMatrix(data.getRw(linkID)), spatialInertiaW); + spatialArticulatedInertia[link.parent] += spatialInertiaW; - data.mWorldSpatialArticulatedInertia[link.parent] += spatialInertiaW; - - Cm::SpatialVectorF translatedZA = FeatherstoneArticulation::translateSpatialVector(data.getRw(linkID), ZA); + Cm::SpatialVectorF translatedZA = FeatherstoneArticulation::translateSpatialVector(data.getRw(linkID), deltaZParent); articulatedZA[link.parent] += translatedZA; } //cache base link inverse spatial inertia - data.mWorldSpatialArticulatedInertia[0].invertInertiaV(data.mBaseInvSpatialArticulatedInertiaW); + spatialArticulatedInertia[0].invertInertiaV(baseInvSpatialArticulatedInertia); } void FeatherstoneArticulation::computeArticulatedSpatialInertia(ArticulationData& data) { - ArticulationLink* links = data.getLinks(); - ArticulationJointCoreData* jointData = data.getJointData(); - ArticulationJointTargetData* jointTargetData = data.getJointTranData(); + const ArticulationLink* links = data.getLinks(); + const ArticulationJointCoreData* jointData = data.getJointData(); + SpatialMatrix* spatialArticulatedInertia = data.getWorldSpatialArticulatedInertia(); + const Cm::UnAlignedSpatialVector* motionMatrix = data.getWorldMotionMatrix(); + Cm::SpatialVectorF* Is = data.getIsW(); + InvStIs* invStIs = data.getInvStIS(); + Cm::SpatialVectorF* IsInvDW = data.getISInvStIS(); + SpatialMatrix& baseInvSpatialArticulatedInertia = data.getBaseInvSpatialArticulatedInertiaW(); + const PxU32 linkCount = data.getLinkCount(); const PxU32 startIndex = PxU32(linkCount - 1); for (PxU32 linkID = startIndex; linkID > 0; --linkID) { - ArticulationLink& link = links[linkID]; + const ArticulationLink& link = links[linkID]; + const ArticulationJointCoreData& jointDatum = jointData[linkID]; + const PxU32 jointOffset = jointDatum.jointOffset; + const PxU8 nbDofs = jointDatum.dof; - ArticulationJointCoreData& jointDatum = jointData[linkID]; - ArticulationJointTargetData& jointTarget = jointTargetData[linkID]; - computeIs(jointDatum, jointTarget, linkID); + for (PxU8 ind = 0; ind < nbDofs; ++ind) + { + const Cm::UnAlignedSpatialVector tmp = spatialArticulatedInertia[linkID] * motionMatrix[jointOffset + ind]; + Is[jointOffset + ind].top = tmp.top; + Is[jointOffset + ind].bottom = tmp.bottom; + } //(I - Is*Inv(sIs)*sI) //KS - we also bury Articulated ZA force and ZIc force computation in here because that saves //us some round-trips to memory! - SpatialMatrix spatialInertiaW = computePropagateSpatialInertia(link.inboundJoint->jointType, - jointDatum, data.mWorldSpatialArticulatedInertia[linkID], &data.mIsW[jointDatum.jointOffset], data.mInvStIs[linkID], &data.mIsInvDW[jointDatum.jointOffset], - &data.mWorldMotionMatrix[jointDatum.jointOffset]); + SpatialMatrix spatialInertiaW = computePropagateSpatialInertia( + PxArticulationJointType::Enum(link.inboundJoint->jointType), + jointDatum.dof, spatialArticulatedInertia[linkID], &motionMatrix[jointOffset], + &Is[jointOffset], + invStIs[linkID], &IsInvDW[jointOffset]); //transform spatial inertia into parent space FeatherstoneArticulation::translateInertia(constructSkewSymmetricMatrix(data.getRw(linkID)), spatialInertiaW); - data.mWorldSpatialArticulatedInertia[link.parent] += spatialInertiaW; + spatialArticulatedInertia[link.parent] += spatialInertiaW; } //cache base link inverse spatial inertia - data.mWorldSpatialArticulatedInertia[0].invertInertiaV(data.mBaseInvSpatialArticulatedInertiaW); + spatialArticulatedInertia[0].invertInertiaV(baseInvSpatialArticulatedInertia); } - void FeatherstoneArticulation::computeArticulatedResponseMatrix(ArticulationData& data) + void FeatherstoneArticulation::computeArticulatedResponseMatrix + (const PxArticulationFlags& articulationFlags, const PxU32 linkCount, + const ArticulationJointCoreData* jointData, + const SpatialMatrix& baseInvArticulatedInertiaW, + const PxVec3* linkRsW, const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const Cm::SpatialVectorF* jointDofISW, const InvStIs* linkInvStISW, const Cm::SpatialVectorF* jointDofIsInvDW, + ArticulationLink* links, SpatialImpulseResponseMatrix* linkResponsesW) { //PX_PROFILE_ZONE("ComputeResponseMatrix", 0); @@ -786,42 +867,32 @@ namespace Dy //The input expected is a local-space impulse and the output is a local-space impulse response vector - ArticulationLink* links = data.getLinks(); - const PxU32 linkCount = data.getLinkCount(); - - const bool fixBase = data.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; - - //(1) impulse response vector for root link - SpatialImpulseResponseMatrix* responsesW = data.getImpulseResponseMatrixWorld(); - - if (fixBase) + if (articulationFlags & PxArticulationFlag::eFIX_BASE) { //Fixed base, so response is zero - PxMemZero(responsesW, sizeof(SpatialImpulseResponseMatrix)); + PxMemZero(linkResponsesW, sizeof(SpatialImpulseResponseMatrix)); } else { //Compute impulse response matrix. Compute the impulse response of unit responses on all 6 axes... - const SpatialMatrix& inverseArticulatedInertiaW = data.mBaseInvSpatialArticulatedInertiaW; - - PxMat33 bottomRight = inverseArticulatedInertiaW.getBottomRight(); + PxMat33 bottomRight = baseInvArticulatedInertiaW.getBottomRight(); - responsesW[0].rows[0] = Cm::SpatialVectorF(inverseArticulatedInertiaW.topLeft.column0, inverseArticulatedInertiaW.bottomLeft.column0); - responsesW[0].rows[1] = Cm::SpatialVectorF(inverseArticulatedInertiaW.topLeft.column1, inverseArticulatedInertiaW.bottomLeft.column1); - responsesW[0].rows[2] = Cm::SpatialVectorF(inverseArticulatedInertiaW.topLeft.column2, inverseArticulatedInertiaW.bottomLeft.column2); - responsesW[0].rows[3] = Cm::SpatialVectorF(inverseArticulatedInertiaW.topRight.column0, bottomRight.column0); - responsesW[0].rows[4] = Cm::SpatialVectorF(inverseArticulatedInertiaW.topRight.column1, bottomRight.column1); - responsesW[0].rows[5] = Cm::SpatialVectorF(inverseArticulatedInertiaW.topRight.column2, bottomRight.column2); + linkResponsesW[0].rows[0] = Cm::SpatialVectorF(baseInvArticulatedInertiaW.topLeft.column0, baseInvArticulatedInertiaW.bottomLeft.column0); + linkResponsesW[0].rows[1] = Cm::SpatialVectorF(baseInvArticulatedInertiaW.topLeft.column1, baseInvArticulatedInertiaW.bottomLeft.column1); + linkResponsesW[0].rows[2] = Cm::SpatialVectorF(baseInvArticulatedInertiaW.topLeft.column2, baseInvArticulatedInertiaW.bottomLeft.column2); + linkResponsesW[0].rows[3] = Cm::SpatialVectorF(baseInvArticulatedInertiaW.topRight.column0, bottomRight.column0); + linkResponsesW[0].rows[4] = Cm::SpatialVectorF(baseInvArticulatedInertiaW.topRight.column1, bottomRight.column1); + linkResponsesW[0].rows[5] = Cm::SpatialVectorF(baseInvArticulatedInertiaW.topRight.column2, bottomRight.column2); - links[0].cfm *= PxMax(responsesW[0].rows[0].bottom.x, PxMax(responsesW[0].rows[1].bottom.y, responsesW[0].rows[2].bottom.z)); + links[0].cfm *= PxMax(linkResponsesW[0].rows[0].bottom.x, PxMax(linkResponsesW[0].rows[1].bottom.y, linkResponsesW[0].rows[2].bottom.z)); } for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { - PxVec3 offset = data.getRw(linkID); - const PxU32 jointOffset = data.getJointData(linkID).jointOffset; - const PxU32 dofCount = data.getJointData(linkID).dof; + PxVec3 offset = linkRsW[linkID]; + const PxU32 jointOffset = jointData[linkID].jointOffset; + const PxU8 dofCount = jointData[linkID].dof; for (PxU32 i = 0; i < 6; ++i) { @@ -834,18 +905,23 @@ namespace Dy ArticulationLink& tLink = links[linkID]; //(1) Propagate impulse to parent PxReal qstZ[3] = { 0.f, 0.f, 0.f }; - Cm::SpatialVectorF Zp = FeatherstoneArticulation::propagateImpulseW(&data.mIsInvDW[jointOffset], offset, - &data.mWorldMotionMatrix[jointOffset], temp, dofCount, qstZ); //(2) Get deltaV response for parent - Cm::SpatialVectorF zR = -responsesW[tLink.parent].getResponse(Zp); - - const Cm::SpatialVectorF deltaV = propagateAccelerationW(offset, data.mInvStIs[linkID], - &data.mWorldMotionMatrix[jointOffset], zR, dofCount, &data.mIsW[jointOffset], qstZ); + Cm::SpatialVectorF Zp = FeatherstoneArticulation::propagateImpulseW( + offset, + temp, + &jointDofIsInvDW[jointOffset], + &jointDofMotionMatricesW[jointOffset], dofCount, + qstZ); //(2) Get deltaV response for parent + Cm::SpatialVectorF zR = -linkResponsesW[tLink.parent].getResponse(Zp); + + const Cm::SpatialVectorF deltaV = + propagateAccelerationW(offset, linkInvStISW[linkID], + &jointDofMotionMatricesW[jointOffset], zR, dofCount, &jointDofISW[jointOffset], qstZ); //Store in local space (required for propagation - responsesW[linkID].rows[i] = deltaV; + linkResponsesW[linkID].rows[i] = deltaV; } - links[linkID].cfm *= PxMax(responsesW[linkID].rows[0].bottom.x, PxMax(responsesW[linkID].rows[1].bottom.y, responsesW[linkID].rows[2].bottom.z)); + links[linkID].cfm *= PxMax(linkResponsesW[linkID].rows[0].bottom.x, PxMax(linkResponsesW[linkID].rows[1].bottom.y, linkResponsesW[linkID].rows[2].bottom.z)); } } @@ -885,7 +961,7 @@ namespace Dy data.qstZIc[jointDatum.jointOffset + ind] = qstZic; PX_ASSERT(PxIsFinite(qstZic)); - ZA += data.mIsInvDW[jointDatum.jointOffset + ind] * qstZic; + ZA += data.mISInvStIS[jointDatum.jointOffset + ind] * qstZic; } //accumulate childen's articulated zero acceleration force to parent's articulated zero acceleration articulatedZA[link.parent] += FeatherstoneArticulation::translateSpatialVector(data.getRw(linkID), ZA); @@ -958,52 +1034,51 @@ namespace Dy } - void FeatherstoneArticulation::computeJointAccelerationW(ArticulationJointCoreData& jointDatum, - const Cm::SpatialVectorF& pMotionAcceleration, PxReal* jointAcceleration, const Cm::SpatialVectorF* IsW, const PxU32 linkID, - const PxReal* qstZIc) + void FeatherstoneArticulation::computeJointAccelerationW(const PxU8 nbJointDofs, + const Cm::SpatialVectorF& parentMotionAcceleration, const Cm::SpatialVectorF* jointDofISW, const InvStIs& linkInvStISW, + const PxReal* jointDofQStZIcW, + PxReal* jointAcceleration) { PxReal tJAccel[6]; - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + //Mirtich equivalent: Q_i - (s_i^T * I_i^A * a_i-1) - s_i^T * (Z_i^A + I_i^A * c_i) + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { //stI * pAcceleration - const PxReal temp = IsW[ind].innerProduct(pMotionAcceleration); - - tJAccel[ind] = (qstZIc[ind] - temp); + const PxReal temp = jointDofISW[ind].innerProduct(parentMotionAcceleration); + tJAccel[ind] = (jointDofQStZIcW[ind] - temp); } //calculate jointAcceleration - - const InvStIs& invStIs = mArticulationData.mInvStIs[linkID]; - - for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) + //Mirtich equivalent: [Q_i - (s_i^T * I_i^A * a_i-1) - s_i^T * (Z_i^A + I_i^A * c_i)]/[s_i^T * I_i^A * s_i] + for (PxU32 ind = 0; ind < nbJointDofs; ++ind) { jointAcceleration[ind] = 0.f; - for (PxU32 ind2 = 0; ind2 < jointDatum.dof; ++ind2) + for (PxU32 ind2 = 0; ind2 < nbJointDofs; ++ind2) { - jointAcceleration[ind] += invStIs.invStIs[ind2][ind] * tJAccel[ind2]; + jointAcceleration[ind] += linkInvStISW.invStIs[ind2][ind] * tJAccel[ind2]; } //PX_ASSERT(PxAbs(jointAcceleration[ind]) < 5000); } } - - void FeatherstoneArticulation::computeLinkAcceleration(ArticulationData& data, ScratchData& scratchData, bool doIC) + + void FeatherstoneArticulation::computeLinkAcceleration + (const bool doIC, const PxReal dt, + const bool fixBase, + const ArticulationLink* links, const PxU32 linkCount, const ArticulationJointCoreData* jointDatas, + const Cm::SpatialVectorF* linkSpatialZAForces, const Cm::SpatialVectorF* linkCoriolisForces, const PxVec3* linkRws, + const Cm::UnAlignedSpatialVector* jointDofMotionMatrices, + const SpatialMatrix& baseInvSpatialArticulatedInertiaW, + const InvStIs* linkInvStIs, + const Cm::SpatialVectorF* jointDofIsWs, const PxReal* jointDofQstZics, + Cm::SpatialVectorF* linkMotionAccelerations, Cm::SpatialVectorF* linkMotionVelocities, + PxReal* jointDofAccelerations, PxReal* jointDofVelocities, PxReal* jointDofNewVelocities) { - const PxU32 linkCount = data.getLinkCount(); - const PxReal dt = data.getDt(); - const bool fixBase = data.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; //we have initialized motionVelocity and motionAcceleration to be zero in the root link if //fix based flag is raised - Cm::SpatialVectorF* motionVelocities = scratchData.motionVelocities; - Cm::SpatialVectorF* motionAccelerations = scratchData.motionAccelerations; - Cm::SpatialVectorF* spatialZAForces = scratchData.spatialZAVectors; - Cm::SpatialVectorF* coriolis = scratchData.coriolisVectors; - - PxMemZero(data.mSolverSpatialForces.begin(), data.mSolverSpatialForces.size() * sizeof(Cm::SpatialVectorF)); - + if (!fixBase) { //ArticulationLinkData& baseLinkDatum = data.getLinkData(0); - SpatialMatrix invInertia = data.mBaseInvSpatialArticulatedInertiaW;//baseLinkDatum.spatialArticulatedInertia.invertInertia(); #if FEATHERSTONE_DEBUG SpatialMatrix result = invInertia * baseLinkDatum.spatialArticulatedInertia; @@ -1015,10 +1090,10 @@ namespace Dy #endif //ArticulationLink& baseLink = data.getLink(0); //const PxTransform& body2World = baseLink.bodyCore->body2World; - Cm::SpatialVectorF accel = -(invInertia * spatialZAForces[0]); - motionAccelerations[0] = accel; + Cm::SpatialVectorF accel = -(baseInvSpatialArticulatedInertiaW * linkSpatialZAForces[0]); + linkMotionAccelerations[0] = accel; Cm::SpatialVectorF deltaV = accel * dt; - motionVelocities[0] += deltaV; + linkMotionVelocities[0] += deltaV; } #if FEATHERSTONE_DEBUG else @@ -1032,35 +1107,34 @@ namespace Dy PxReal* jointVelocities = data.getJointVelocities(); PxReal* jointPositions = data.getJointPositions();*/ - PxReal* jointAccelerations = scratchData.jointAccelerations; - PxReal* jointVelocities = scratchData.jointVelocities; - PxReal* jointNewVelocities = mArticulationData.mJointNewVelocity.begin(); + //printf("===========================\n"); //calculate acceleration for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { - ArticulationLink& link = data.getLink(linkID); + const ArticulationLink& link = links[linkID]; ArticulationJointCore& joint = *link.inboundJoint; PX_UNUSED(joint); - Cm::SpatialVectorF pMotionAcceleration = FeatherstoneArticulation::translateSpatialVector(-data.getRw(linkID), motionAccelerations[link.parent]); + Cm::SpatialVectorF pMotionAcceleration = FeatherstoneArticulation::translateSpatialVector(-linkRws[linkID], linkMotionAccelerations[link.parent]); - ArticulationJointCoreData& jointDatum = data.getJointData(linkID); + const ArticulationJointCoreData& jointDatum = jointDatas[linkID]; //calculate jointAcceleration - PxReal* jA = &jointAccelerations[jointDatum.jointOffset]; - computeJointAccelerationW(jointDatum, pMotionAcceleration, jA, &data.mIsW[jointDatum.jointOffset], linkID, - &data.qstZIc[jointDatum.jointOffset]); + PxReal* jA = &jointDofAccelerations[jointDatum.jointOffset]; + const InvStIs& invStIs = linkInvStIs[linkID]; + computeJointAccelerationW(jointDatum.dof, pMotionAcceleration, &jointDofIsWs[jointDatum.jointOffset], invStIs, + &jointDofQstZics[jointDatum.jointOffset], jA); //printf("jA %f\n", jA[0]); Cm::SpatialVectorF motionAcceleration = pMotionAcceleration; if (doIC) - motionAcceleration += coriolis[linkID]; - PxReal* jointVelocity = &jointVelocities[jointDatum.jointOffset]; - PxReal* jointNewVelocity = &jointNewVelocities[jointDatum.jointOffset]; + motionAcceleration += linkCoriolisForces[linkID]; + PxReal* jointVelocity = &jointDofVelocities[jointDatum.jointOffset]; + PxReal* jointNewVelocity = &jointDofNewVelocities[jointDatum.jointOffset]; for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) { @@ -1068,14 +1142,14 @@ namespace Dy PxReal jVel = jointVelocity[ind] + accel * dt; jointVelocity[ind] = jVel; jointNewVelocity[ind] = jVel; - motionAcceleration.top += data.mWorldMotionMatrix[jointDatum.jointOffset + ind].top * accel; - motionAcceleration.bottom += data.mWorldMotionMatrix[jointDatum.jointOffset + ind].bottom * accel; + motionAcceleration.top += jointDofMotionMatrices[jointDatum.jointOffset + ind].top * accel; + motionAcceleration.bottom += jointDofMotionMatrices[jointDatum.jointOffset + ind].bottom * accel; } //KS - can we just work out velocities by projecting out the joint velocities instead of accumulating all this? - motionAccelerations[linkID] = motionAcceleration; - PX_ASSERT(motionAccelerations[linkID].isFinite()); - motionVelocities[linkID] += motionAcceleration * dt; + linkMotionAccelerations[linkID] = motionAcceleration; + PX_ASSERT(linkMotionAccelerations[linkID].isFinite()); + linkMotionVelocities[linkID] += motionAcceleration * dt; /*Cm::SpatialVectorF spatialForce = mArticulationData.mWorldSpatialArticulatedInertia[linkID] * motionAcceleration; @@ -1086,50 +1160,47 @@ namespace Dy } } - - void FeatherstoneArticulation::computeLinkInternalAcceleration(ArticulationData& data, ScratchData& scratchData) + void FeatherstoneArticulation::computeLinkInternalAcceleration + ( const PxReal dt, + const bool fixBase, + const PxVec3& com, const PxReal invSumMass, const PxReal maxLinearVelocity, const PxReal maxAngularVelocity, const PxMat33* linkIsolatedSpatialArticulatedInertiasW, + const SpatialMatrix& baseInvSpatialArticulatedInertiaW, + const ArticulationLink* links, const PxU32 linkCount, + const PxReal* linkMasses, const PxVec3* linkRsW, const PxTransform* linkAccumulatedPosesW, + const Cm::SpatialVectorF* linkSpatialZAIntForcesW, const Cm::SpatialVectorF* linkCoriolisVectorsW, + const ArticulationJointCoreData* jointDatas, const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW, + const InvStIs* linkInvStISW, const Cm::SpatialVectorF* jointDofISW, const PxReal* jointDofQStZIntIcW, + Cm::SpatialVectorF* linkMotionAccelerationsW, Cm::SpatialVectorF* linkMotionIntAccelerationsW, Cm::SpatialVectorF* linkMotionVelocitiesW, + PxReal* jointDofAccelerations, PxReal* jointDofInternalAccelerations, PxReal* jointDofVelocities, PxReal* jointDofNewVelocities) { - - const PxU32 linkCount = data.getLinkCount(); - const PxReal dt = data.getDt(); - const bool fixBase = data.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; //we have initialized motionVelocity and motionAcceleration to be zero in the root link if //fix based flag is raised - Cm::SpatialVectorF* motionVelocities = scratchData.motionVelocities; - Cm::SpatialVectorF* motionAccelerations = scratchData.motionAccelerations; - Cm::SpatialVectorF* spatialZAInternalForces = data.mZAInternalForces.begin(); - Cm::SpatialVectorF* coriolisVectors = scratchData.coriolisVectors; - - Cm::SpatialVectorF* motionAccelerationInt = data.mMotionAccelerationsInternal.begin(); - - Cm::SpatialVectorF momentum0(PxVec3(0.f), PxVec3(0.f)); - - PxVec3 COM = data.mCOM; - - for (PxU32 linkID = 0; linkID < linkCount; ++linkID) + Cm::SpatialVectorF momentum0(PxVec3(0,0,0), PxVec3(0,0,0)); + PxVec3 rootVel(PxZero); { - const Cm::SpatialVectorF& vel = motionVelocities[linkID]; - PxReal mass = data.mMasses[linkID]; - momentum0.top += vel.bottom*mass; - } + for (PxU32 linkID = 0; linkID < linkCount; ++linkID) + { + const Cm::SpatialVectorF& vel = linkMotionVelocitiesW[linkID]; + const PxReal mass = linkMasses[linkID]; + momentum0.top += vel.bottom*mass; + } - PxVec3 rootVel = momentum0.top * data.mInvSumMass; - for (PxU32 linkID = 0; linkID < linkCount; ++linkID) - { - PxReal mass = data.mMasses[linkID]; - const Cm::SpatialVectorF& vel = motionVelocities[linkID]; - const PxVec3 offsetMass = (data.getAccumulatedPoses()[linkID].p - COM)*mass; + rootVel = momentum0.top * invSumMass; + for (PxU32 linkID = 0; linkID < linkCount; ++linkID) + { + const PxReal mass = linkMasses[linkID]; + const Cm::SpatialVectorF& vel = linkMotionVelocitiesW[linkID]; + const PxVec3 offsetMass = (linkAccumulatedPosesW[linkID].p - com)*mass; - const PxVec3 angMom = data.mWorldIsolatedSpatialArticulatedInertia[linkID] * vel.top + offsetMass.cross(motionVelocities[linkID].bottom - rootVel); - momentum0.bottom += angMom; + const PxVec3 angMom = linkIsolatedSpatialArticulatedInertiasW[linkID] * vel.top + offsetMass.cross(linkMotionVelocitiesW[linkID].bottom - rootVel); + momentum0.bottom += angMom; + } } - PxReal sumInvMass = data.mInvSumMass; - + if (!fixBase) { //ArticulationLinkData& baseLinkDatum = data.getLinkData(0); - SpatialMatrix invInertia = data.mBaseInvSpatialArticulatedInertiaW;//baseLinkDatum.spatialArticulatedInertia.invertInertia(); #if FEATHERSTONE_DEBUG SpatialMatrix result = invInertia * baseLinkDatum.spatialArticulatedInertia; @@ -1141,72 +1212,61 @@ namespace Dy #endif //ArticulationLink& baseLink = data.getLink(0); //const PxTransform& body2World = baseLink.bodyCore->body2World; - Cm::SpatialVectorF accel = -(invInertia * spatialZAInternalForces[0]); - motionAccelerationInt[0] = accel; - motionAccelerations[0] += accel; - Cm::SpatialVectorF deltaV = accel * dt; - - motionVelocities[0] += deltaV; + const Cm::SpatialVectorF accel = -(baseInvSpatialArticulatedInertiaW * linkSpatialZAIntForcesW[0]); + linkMotionIntAccelerationsW[0] = accel; + linkMotionAccelerationsW[0] += accel; + const Cm::SpatialVectorF deltaV = accel * dt; + linkMotionVelocitiesW[0] += deltaV; } else { - motionAccelerationInt[0] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); + linkMotionIntAccelerationsW[0] = Cm::SpatialVectorF(PxVec3(0.f), PxVec3(0.f)); } - PxReal* jointAccelerations = scratchData.jointAccelerations; - PxReal* jointInternalAccelerations = mArticulationData.mJointInternalAcceleration.begin(); - PxReal* jointVelocities = scratchData.jointVelocities; - PxReal* jointNewVelocities = mArticulationData.mJointNewVelocity.begin(); //printf("===========================\n"); //calculate acceleration for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { - ArticulationLink& link = data.getLink(linkID); + const ArticulationLink& link = links[linkID]; ArticulationJointCore& joint = *link.inboundJoint; PX_UNUSED(joint); - Cm::SpatialVectorF pMotionAcceleration = FeatherstoneArticulation::translateSpatialVector(-data.getRw(linkID), motionAccelerationInt[link.parent]); + const Cm::SpatialVectorF pMotionAcceleration = FeatherstoneArticulation::translateSpatialVector(-linkRsW[linkID], linkMotionIntAccelerationsW[link.parent]); - ArticulationJointCoreData& jointDatum = data.getJointData(linkID); + const ArticulationJointCoreData& jointDatum = jointDatas[linkID]; //calculate jointAcceleration - PxReal* jA = &jointAccelerations[jointDatum.jointOffset]; - PxReal* jIntAccel = &jointInternalAccelerations[jointDatum.jointOffset]; - computeJointAccelerationW(jointDatum, pMotionAcceleration, jIntAccel, &data.mIsW[jointDatum.jointOffset], linkID, - &data.qstZIntIc[jointDatum.jointOffset]); + PxReal* jIntAccel = &jointDofInternalAccelerations[jointDatum.jointOffset]; + computeJointAccelerationW(jointDatum.dof, pMotionAcceleration, &jointDofISW[jointDatum.jointOffset], linkInvStISW[linkID], + &jointDofQStZIntIcW[jointDatum.jointOffset], jIntAccel); //printf("jA %f\n", jA[0]); //KS - TODO - separate integration of coriolis vectors! - Cm::SpatialVectorF motionAcceleration = pMotionAcceleration + coriolisVectors[linkID]; - PxReal* jointVelocity = &jointVelocities[jointDatum.jointOffset]; - PxReal* jointNewVelocity = &jointNewVelocities[jointDatum.jointOffset]; - - Cm::SpatialVectorF mVel = FeatherstoneArticulation::translateSpatialVector(-data.getRw(linkID), motionVelocities[link.parent]); + Cm::SpatialVectorF motionAcceleration = pMotionAcceleration + linkCoriolisVectorsW[linkID]; + PxReal* jointVelocity = &jointDofVelocities[jointDatum.jointOffset]; + PxReal* jointNewVelocity = &jointDofNewVelocities[jointDatum.jointOffset]; + PxReal* jA = &jointDofAccelerations[jointDatum.jointOffset]; for (PxU32 ind = 0; ind < jointDatum.dof; ++ind) { const PxReal accel = jIntAccel[ind]; PxReal jVel = jointVelocity[ind] + accel * dt; jointVelocity[ind] = jVel; jointNewVelocity[ind] = jVel; - motionAcceleration.top += data.mWorldMotionMatrix[jointDatum.jointOffset + ind].top * accel; - motionAcceleration.bottom += data.mWorldMotionMatrix[jointDatum.jointOffset + ind].bottom * accel; - - mVel.top += data.mWorldMotionMatrix[jointDatum.jointOffset + ind].top * jVel; - mVel.bottom += data.mWorldMotionMatrix[jointDatum.jointOffset + ind].bottom * jVel; - + motionAcceleration.top += jointDofMotionMatricesW[jointDatum.jointOffset + ind].top * accel; + motionAcceleration.bottom += jointDofMotionMatricesW[jointDatum.jointOffset + ind].bottom * accel; jA[ind] += accel; } //KS - can we just work out velocities by projecting out the joint velocities instead of accumulating all this? - motionAccelerationInt[linkID] = motionAcceleration; - motionAccelerations[linkID] += motionAcceleration; - PX_ASSERT(motionAccelerations[linkID].isFinite()); + linkMotionIntAccelerationsW[linkID] = motionAcceleration; + linkMotionAccelerationsW[linkID] += motionAcceleration; + PX_ASSERT(linkMotionAccelerationsW[linkID].isFinite()); Cm::SpatialVectorF velDelta = (motionAcceleration)* dt; - motionVelocities[linkID] += velDelta; + linkMotionVelocitiesW[linkID] += velDelta; } @@ -1221,20 +1281,20 @@ namespace Dy for (PxU32 linkID = 0; linkID < linkCount; ++linkID) { - PxReal mass = data.mMasses[linkID]; - sumLinMomentum += motionVelocities[linkID].bottom * mass; + PxReal mass = linkMasses[linkID]; + sumLinMomentum += linkMotionVelocitiesW[linkID].bottom * mass; } - rootVel = sumLinMomentum * sumInvMass; + rootVel = sumLinMomentum * invSumMass; for (PxU32 linkID = 0; linkID < linkCount; ++linkID) { - PxReal mass = data.mMasses[linkID]; - const PxVec3 offset = data.getAccumulatedPoses()[linkID].p - COM; - inertia += translateInertia(data.mWorldIsolatedSpatialArticulatedInertia[linkID], mass, offset); + PxReal mass = linkMasses[linkID]; + const PxVec3 offset = linkAccumulatedPosesW[linkID].p - com; + inertia += translateInertia(linkIsolatedSpatialArticulatedInertiasW[linkID], mass, offset); - angMomentum1 += data.mWorldIsolatedSpatialArticulatedInertia[linkID] * motionVelocities[linkID].top - + offset.cross(motionVelocities[linkID].bottom - rootVel) * mass; + angMomentum1 += linkIsolatedSpatialArticulatedInertiasW[linkID] * linkMotionVelocitiesW[linkID].top + + offset.cross(linkMotionVelocitiesW[linkID].bottom - rootVel) * mass; } PxMat33 invCompoundInertia = inertia.getInverse(); @@ -1247,9 +1307,9 @@ namespace Dy PxVec3 deltaAng = invCompoundInertia * deltaAngMom; - if (mSolverDesc.core) + if (maxAngularVelocity > 0.0f) { - const PxReal maxAng = mSolverDesc.core->maxAngularVelocity; + const PxReal maxAng = maxAngularVelocity; const PxReal maxAngSq = maxAng * maxAng; PxVec3 ang = (invCompoundInertia * angMomentum1) + deltaAng; if (ang.magnitudeSquared() > maxAngSq) @@ -1263,10 +1323,10 @@ namespace Dy #if 1 for (PxU32 linkID = 0; linkID < linkCount; ++linkID) { - const PxVec3 offset = (data.getAccumulatedPoses()[linkID].p - COM); + const PxVec3 offset = (linkAccumulatedPosesW[linkID].p - com); Cm::SpatialVectorF velChange(deltaAng, -offset.cross(deltaAng)); - motionVelocities[linkID] += velChange; - PxReal mass = data.mMasses[linkID]; + linkMotionVelocitiesW[linkID] += velChange; + const PxReal mass = linkMasses[linkID]; sumLinMomentum += velChange.bottom * mass; } #else @@ -1295,13 +1355,13 @@ namespace Dy #else PxVec3 deltaLinMom = momentum0.top - sumLinMomentum; #endif - PxVec3 deltaLin = deltaLinMom * sumInvMass; + PxVec3 deltaLin = deltaLinMom * invSumMass; - if (mSolverDesc.core) + if (maxLinearVelocity >= 0.0f) { - const PxReal maxLin = mSolverDesc.core->maxLinearVelocity; + const PxReal maxLin = maxLinearVelocity; const PxReal maxLinSq = maxLin * maxLin; - PxVec3 lin = (sumLinMomentum * sumInvMass) + deltaLin; + PxVec3 lin = (sumLinMomentum * invSumMass) + deltaLin; if (lin.magnitudeSquared() > maxLinSq) { PxReal ratio = maxLin / lin.magnitude(); @@ -1311,7 +1371,7 @@ namespace Dy for (PxU32 linkID = 0; linkID < linkCount; ++linkID) { - motionVelocities[linkID].bottom += deltaLin; + linkMotionVelocitiesW[linkID].bottom += deltaLin; } #if PX_DEBUG && 0 @@ -1351,6 +1411,20 @@ namespace Dy } + void FeatherstoneArticulation::computeLinkIncomingJointForce( + const PxU32 linkCount, + const Cm::SpatialVectorF* linkZAForcesExtW, const Cm::SpatialVectorF* linkZAForcesIntW, + const Cm::SpatialVectorF* linkMotionAccelerationsW, const SpatialMatrix* linkSpatialInertiasW, + Cm::SpatialVectorF* linkIncomingJointForces) + { + linkIncomingJointForces[0] = Cm::SpatialVectorF(PxVec3(0,0,0), PxVec3(0,0,0)); + for(PxU32 i = 1; i < linkCount; i++) + { + linkIncomingJointForces[i] = linkSpatialInertiasW[i]*linkMotionAccelerationsW[i] + (linkZAForcesExtW[i] + linkZAForcesIntW[i]); + } + } + + void FeatherstoneArticulation::computeJointTransmittedFrictionForce( ArticulationData& data, ScratchData& scratchData, Cm::SpatialVectorF* /*Z*/, Cm::SpatialVectorF* /*DeltaV*/) { @@ -1543,57 +1617,238 @@ namespace Dy // } //} - void FeatherstoneArticulation::updateArticulation(ScratchData& scratchData, - const PxVec3& gravity, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV, const PxReal invLengthScale) + void FeatherstoneArticulation::updateArticulation(const PxVec3& gravity, const PxReal invLengthScale) { - computeRelativeTransformC2P(mArticulationData); + //Copy the link poses into a handy array. + //Update the link separation vectors with the latest link poses. + //Compute the motion matrices in the world frame uisng the latest link poses. + { + //constants + const ArticulationLink* links = mArticulationData.getLinks(); + const PxU32 linkCount = mArticulationData.getLinkCount(); + const ArticulationJointCoreData* jointCoreDatas = mArticulationData.getJointData(); + const Cm::UnAlignedSpatialVector* jointDofMotionMatrices = mArticulationData.getMotionMatrix(); + + //outputs + PxTransform* linkAccumulatedPosesW = mArticulationData.getAccumulatedPoses(); + PxVec3* linkRsW = mArticulationData.getRw(); + Cm::UnAlignedSpatialVector* jointDofMotionMatricesW = mArticulationData.getWorldMotionMatrix(); + + computeRelativeTransformC2P( + links, linkCount, jointCoreDatas, jointDofMotionMatrices, + linkAccumulatedPosesW, linkRsW, jointDofMotionMatricesW); + } + + //computeLinkVelocities(mArticulationData, scratchData); + { + //constants + const PxReal dt = mArticulationData.mDt; + const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; + const PxU32 nbLinks = mArticulationData.mLinkCount; + const PxU32 nbJointDofs = mArticulationData.mJointVelocity.size(); + const PxTransform* linkAccumulatedPosesW = mArticulationData.mAccumulatedPoses.begin(); + const Cm::SpatialVector* linkExternalAccelsW = mArticulationData.mExternalAcceleration; + const PxVec3* linkRsW = mArticulationData.mRw.begin(); + + //outputs + Cm::UnAlignedSpatialVector* jointDofMotionMatricesW = mArticulationData.mWorldMotionMatrix.begin(); + const ArticulationJointCoreData* jointCoreData = mArticulationData.mJointData; + ArticulationLinkData* linkData = mArticulationData.mLinksData; + ArticulationLink* links = mArticulationData.mLinks; + Cm::SpatialVectorF* linkMotionVelocitiesW = mArticulationData.mMotionVelocities.begin(); + Cm::SpatialVectorF* linkMotionAccelerationsW = mArticulationData.mMotionAccelerations.begin(); + Cm::SpatialVectorF* linkCoriolisVectorsW = mArticulationData.mCorioliseVectors.begin(); + Cm::SpatialVectorF* linkZAExtForcesW = mArticulationData.mZAForces.begin(); + Cm::SpatialVectorF* linkZAIntForcesW = mArticulationData.mZAInternalForces.begin(); + Dy::SpatialMatrix* linkSpatialArticulatedInertiasW = mArticulationData.mWorldSpatialArticulatedInertia.begin(); + PxMat33* linkIsolatedSpatialArticulatedInertiasW = mArticulationData.mWorldIsolatedSpatialArticulatedInertia.begin(); + PxReal* linkMasses = mArticulationData.mMasses.begin(); + PxReal* jointDofVelocities = mArticulationData.mJointVelocity.begin(); + Cm::SpatialVectorF& rootPreMotionVelocityW = mArticulationData.mRootPreMotionVelocity; + PxVec3& comW = mArticulationData.mCOM; + PxReal& invMass = mArticulationData.mInvSumMass; + + computeLinkStates( + dt, invLengthScale, gravity, fixBase, + nbLinks, + linkAccumulatedPosesW, linkExternalAccelsW, linkRsW, jointDofMotionMatricesW, jointCoreData, + linkData, links, linkMotionAccelerationsW, linkMotionVelocitiesW, linkZAExtForcesW, linkZAIntForcesW, linkCoriolisVectorsW, + linkIsolatedSpatialArticulatedInertiasW, linkMasses, linkSpatialArticulatedInertiasW, + nbJointDofs, + jointDofVelocities, + rootPreMotionVelocityW, comW, invMass); + } + + { + const PxU32 linkCount = mArticulationData.getLinkCount(); + if (linkCount > 1) + { + const Cm::SpatialVectorF* ZAForcesExtW = mArticulationData.getSpatialZAVectors(); + const Cm::SpatialVectorF* ZAForcesIntW = mArticulationData.mZAInternalForces.begin(); + Cm::SpatialVectorF* ZAForcesTransmittedW = mArticulationData.getTransmittedForces(); + for (PxU32 linkID = 0; linkID < linkCount; ++linkID) + { + ZAForcesTransmittedW[linkID] = ZAForcesExtW[linkID] + ZAForcesIntW[linkID]; + } + } + } + + { + //Constant inputs. + const ArticulationLink* links = mArticulationData.getLinks(); + const PxU32 linkCount = mArticulationData.getLinkCount(); + const PxVec3* linkRsW = mArticulationData.getRw(); + const ArticulationJointCoreData* jointData = mArticulationData.getJointData(); + const ArticulationJointTargetData* jointTargetData = mArticulationData.getJointTranData(); + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW = mArticulationData.getWorldMotionMatrix(); + const Cm::SpatialVectorF* linkCoriolisVectorsW = mArticulationData.getCorioliseVectors(); + const PxReal* jointDofForces = mArticulationData.getJointForces(); + + //Values that we need now and will cache for later use. + Cm::SpatialVectorF* jointDofISW = mArticulationData.getIsW(); + InvStIs* linkInvStISW = mArticulationData.getInvStIS(); + Cm::SpatialVectorF* jointDofISInvStIS = mArticulationData.getISInvStIS(); //[(I * s)/(s^T * I * s) + PxReal* jointDofMinusStZExtW = mArticulationData.getMinusStZExt(); //[-s^t * ZExt] + PxReal* jointDofQStZIntIcW = mArticulationData.getQStZIntIc(); //[Q - s^T*(ZInt + I*c)] + + //We need to compute these. + Cm::SpatialVectorF* linkZAForcesExtW = mArticulationData.getSpatialZAVectors(); + Cm::SpatialVectorF* linkZAForcesIntW = mArticulationData.mZAInternalForces.begin(); + SpatialMatrix* linkSpatialInertiasW = mArticulationData.getWorldSpatialArticulatedInertia(); + SpatialMatrix& baseInvSpatialArticulatedInertiaW = mArticulationData.getBaseInvSpatialArticulatedInertiaW(); + + computeArticulatedSpatialInertiaAndZ( + links, linkCount, linkRsW, //constants + jointData, jointTargetData, //constants + jointDofMotionMatricesW, linkCoriolisVectorsW, jointDofForces, //constants + jointDofISW, linkInvStISW, jointDofISInvStIS, //compute and cache for later use + jointDofMinusStZExtW, jointDofQStZIntIcW, //compute and cache for later use + linkZAForcesExtW, linkZAForcesIntW, //outputs + linkSpatialInertiasW, baseInvSpatialArticulatedInertiaW); //outputs + } + { + //Constants + const PxArticulationFlags& flags = mArticulationData.getArticulationFlags(); + ArticulationLink* links = mArticulationData.getLinks(); + const PxU32 linkCount = mArticulationData.getLinkCount(); + const ArticulationJointCoreData* jointData = mArticulationData.getJointData(); + const SpatialMatrix& baseInvSpatialArticulatedInertiaW = mArticulationData.getBaseInvSpatialArticulatedInertiaW(); + const PxVec3* linkRsW = mArticulationData.getRw(); + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW = mArticulationData.getWorldMotionMatrix(); + const Cm::SpatialVectorF* jointDofISW = mArticulationData.getIsW(); + const InvStIs* linkInvStIsW = mArticulationData.getInvStIS(); + const Cm::SpatialVectorF* jointDofISInvDW = mArticulationData.getISInvStIS(); + + //outputs + SpatialImpulseResponseMatrix* linkImpulseResponseMatricesW = mArticulationData.getImpulseResponseMatrixWorld(); + + computeArticulatedResponseMatrix( + flags, linkCount, //constants + jointData, baseInvSpatialArticulatedInertiaW, //constants + linkRsW, jointDofMotionMatricesW, //constants + jointDofISW, linkInvStIsW, jointDofISInvDW, //constants + links, linkImpulseResponseMatricesW); //outputs + } - //articulation constants - const PxReal dt = mArticulationData.mDt; - const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; - //articulation links - const PxU32 nbLinks = mArticulationData.mLinkCount; - const PxTransform* accumulatedPoses = mArticulationData.mAccumulatedPoses.begin(); - const Cm::SpatialVector* externalAccels = mArticulationData.mExternalAcceleration; - const PxVec3* rws = mArticulationData.mRw.begin(); - Cm::UnAlignedSpatialVector* worldMotionMatrices = mArticulationData.mWorldMotionMatrix.begin(); - ArticulationLinkData* linkData = mArticulationData.mLinksData; - ArticulationLink* links = mArticulationData.mLinks; - ArticulationJointCoreData* jointCoreData = mArticulationData.mJointData; - Cm::SpatialVectorF* motionVelocities = mArticulationData.mMotionVelocities.begin(); - Cm::SpatialVectorF* motionAccelerations = mArticulationData.mMotionAccelerations.begin(); - Cm::SpatialVectorF* coriolisVectors = mArticulationData.mCorioliseVectors.begin(); - Cm::SpatialVectorF* spatialZAForces = mArticulationData.mZAForces.begin(); - Cm::SpatialVectorF* spatialZAInternal = mArticulationData.mZAInternalForces.begin(); - Dy::SpatialMatrix* worldSpatialArticulatedInertias = mArticulationData.mWorldSpatialArticulatedInertia.begin(); - PxMat33* worldIsolatedSpatialArticulatedInertias = mArticulationData.mWorldIsolatedSpatialArticulatedInertia.begin(); - PxReal* linkMasses = mArticulationData.mMasses.begin(); - //articulation joint dofs - const PxU32 nbJointDofs = mArticulationData.mJointVelocity.size(); - PxReal* jointVelocities = mArticulationData.mJointVelocity.begin(); - //articulation state - Cm::SpatialVectorF& rootPreMotionVelocity = mArticulationData.mRootPreMotionVelocity; - PxVec3& com = mArticulationData.mCOM; - PxReal& invMass = mArticulationData.mInvSumMass; - computeLinkStates( - dt, invLengthScale, gravity, fixBase, - nbLinks, - accumulatedPoses, externalAccels, rws, worldMotionMatrices, jointCoreData, - linkData, links, motionAccelerations, - motionVelocities, spatialZAForces, spatialZAInternal, coriolisVectors, - worldIsolatedSpatialArticulatedInertias, linkMasses, worldSpatialArticulatedInertias, - nbJointDofs, - jointVelocities, - rootPreMotionVelocity, com, invMass); - - initLinks(mArticulationData, gravity, scratchData, Z, DeltaV); - computeLinkAcceleration(mArticulationData, scratchData, false); - computeLinkInternalAcceleration(mArticulationData, scratchData); + { + //Constant terms. + const bool doIC = false; + const PxReal dt = mArticulationData.getDt(); + const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; + const ArticulationLink* links = mArticulationData.getLinks(); + const PxU32 linkCount = mArticulationData.getLinkCount(); + const ArticulationJointCoreData* jointDatas = mArticulationData.getJointData(); + const Cm::SpatialVectorF* linkSpatialZAForcesExtW = mArticulationData.getSpatialZAVectors(); + const Cm::SpatialVectorF* linkCoriolisForcesW = mArticulationData.getCorioliseVectors(); + const PxVec3* linkRsW = mArticulationData.getRw(); + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW = mArticulationData.getWorldMotionMatrix(); + const SpatialMatrix& baseInvSpatialArticulatedInertiaW = mArticulationData.getBaseInvSpatialArticulatedInertiaW(); + + //Cached constant terms. + const InvStIs* linkInvStISW = mArticulationData.getInvStIS(); + const Cm::SpatialVectorF* jointDofISW = mArticulationData.getIsW(); + const PxReal* jointDofMinusStZExtW = mArticulationData.getMinusStZExt(); + + //Output + Cm::SpatialVectorF* linkMotionVelocitiesW = mArticulationData.getMotionVelocities(); + Cm::SpatialVectorF* linkMotionAccelerationsW = mArticulationData.getMotionAccelerations(); + PxReal* jointDofAccelerations = mArticulationData.getJointAccelerations(); + PxReal* jointDofVelocities = mArticulationData.getJointVelocities(); + PxReal* jointDofNewVelocities = mArticulationData.getJointNewVelocities(); + + computeLinkAcceleration( + doIC, dt, + fixBase, + links, linkCount, jointDatas, + linkSpatialZAForcesExtW, linkCoriolisForcesW, linkRsW, + jointDofMotionMatricesW, baseInvSpatialArticulatedInertiaW, + linkInvStISW, jointDofISW, jointDofMinusStZExtW, + linkMotionAccelerationsW,linkMotionVelocitiesW, + jointDofAccelerations, jointDofVelocities, jointDofNewVelocities); + } + + { + //constants + const PxReal dt = mArticulationData.getDt(); + const PxVec3& comW = mArticulationData.mCOM; + const PxReal invSumMass = mArticulationData.mInvSumMass; + const SpatialMatrix& baseInvSpatialArticulatedInertiaW = mArticulationData.mBaseInvSpatialArticulatedInertiaW; + const PxReal linkMaxLinearVelocity = mSolverDesc.core ? mSolverDesc.core->maxLinearVelocity : -1.0f; + const PxReal linkMaxAngularVelocity = mSolverDesc.core ? mSolverDesc.core->maxAngularVelocity : -1.0f; + const ArticulationLink* links = mArticulationData.getLinks(); + const PxU32 linkCount = mArticulationData.getLinkCount(); + const ArticulationJointCoreData* jointDatas = mArticulationData.getJointData(); + const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; + const Cm::SpatialVectorF* linkSpatialZAIntForcesW = mArticulationData.getSpatialZAInternalVectors(); + const Cm::SpatialVectorF* linkCoriolisVectorsW = mArticulationData.getCorioliseVectors(); + const PxReal* linkMasses = mArticulationData.mMasses.begin(); + const PxVec3* linkRsW = mArticulationData.getRw(); + const PxTransform* linkAccumulatedPosesW = mArticulationData.getAccumulatedPoses(); + const PxMat33* linkIsolatedSpatialArticulatedInertiasW = mArticulationData.mWorldIsolatedSpatialArticulatedInertia.begin(); + const Cm::UnAlignedSpatialVector* jointDofMotionMatricesW = mArticulationData.getWorldMotionMatrix(); + //cached data. + const InvStIs* linkInvStISW = mArticulationData.getInvStIS(); + const Cm::SpatialVectorF* jointDofISW = mArticulationData.getIsW(); + const PxReal* jointDofQStZIntIcW = mArticulationData.getQStZIntIc(); + //output + Cm::SpatialVectorF* linkMotionVelocitiesW = mArticulationData.getMotionVelocities(); + Cm::SpatialVectorF* linkMotionAccelerationsW = mArticulationData.getMotionAccelerations(); + Cm::SpatialVectorF* linkMotionAccelerationIntW = mArticulationData.mMotionAccelerationsInternal.begin(); + PxReal* jointDofAccelerations = mArticulationData.getJointAccelerations(); + PxReal* jointDofInternalAccelerations = mArticulationData.mJointInternalAcceleration.begin(); + PxReal* jointVelocities = mArticulationData.getJointVelocities(); + PxReal* jointNewVelocities = mArticulationData.mJointNewVelocity.begin(); + + computeLinkInternalAcceleration( + dt, fixBase, comW, invSumMass, linkMaxLinearVelocity, linkMaxAngularVelocity, linkIsolatedSpatialArticulatedInertiasW, + baseInvSpatialArticulatedInertiaW, + links, linkCount, + linkMasses, linkRsW, linkAccumulatedPosesW, + linkSpatialZAIntForcesW, linkCoriolisVectorsW, + jointDatas, jointDofMotionMatricesW, + linkInvStISW, jointDofISW, jointDofQStZIntIcW, + linkMotionAccelerationsW, linkMotionAccelerationIntW, linkMotionVelocitiesW, + jointDofAccelerations, jointDofInternalAccelerations, jointVelocities, jointNewVelocities); + } + + { + const PxU32 linkCount = mArticulationData.getLinkCount(); + + Cm::SpatialVectorF* solverLinkSpatialDeltaVels = mArticulationData.mSolverLinkSpatialDeltaVels.begin(); + PxMemZero(solverLinkSpatialDeltaVels, sizeof(Cm::SpatialVectorF) * linkCount); + + Cm::SpatialVectorF* solverLinkSpatialImpulses = mArticulationData.mSolverLinkSpatialImpulses.begin(); + PxMemZero(solverLinkSpatialImpulses, sizeof(Cm::SpatialVectorF) * linkCount); + + Cm::SpatialVectorF* solverLinkSpatialForcesW = mArticulationData.mSolverLinkSpatialForces.begin(); + PxMemZero(solverLinkSpatialForcesW, linkCount * sizeof(Cm::SpatialVectorF)); + } } + void FeatherstoneArticulation::computeUnconstrainedVelocitiesInternal( const PxVec3& gravity, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* DeltaV, const PxReal invLengthScale) @@ -1610,6 +1865,8 @@ namespace Dy mArticulationData.init(); + updateArticulation(gravity, invLengthScale); + ScratchData scratchData; scratchData.motionVelocities = mArticulationData.getMotionVelocities(); scratchData.motionAccelerations = mArticulationData.getMotionAccelerations(); @@ -1620,9 +1877,6 @@ namespace Dy scratchData.jointPositions = mArticulationData.getJointPositions(); scratchData.jointForces = mArticulationData.getJointForces(); scratchData.externalAccels = mArticulationData.getExternalAccelerations(); - - updateArticulation(scratchData, gravity, Z, DeltaV, invLengthScale); - if (mArticulationData.mLinkCount > 1) { @@ -1777,107 +2031,6 @@ namespace Dy } } - void FeatherstoneArticulation::recomputeAccelerations(const PxReal dt) - { - ArticulationJointCoreData* jointData = mArticulationData.getJointData(); - - ArticulationLink* links = mArticulationData.getLinks(); - const PxU32 linkCount = mArticulationData.getLinkCount(); - - Cm::SpatialVectorF* motionAccels = mArticulationData.getMotionAccelerations(); - - PxReal* jAccelerations = mArticulationData.getJointAccelerations(); - - const PxReal invDt = 1.f / dt; - - const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; - - //compute root link accelerations - if (fixBase) - { - motionAccels[0] = Cm::SpatialVectorF::Zero(); - } - else - { - Cm::SpatialVectorF tAccel = (mArticulationData.getMotionVelocity(0) - mArticulationData.mRootPreMotionVelocity) * invDt; - motionAccels[0].top = tAccel.top; - motionAccels[0].bottom = tAccel.bottom; - - } - - for (PxU32 linkID = 1; linkID < linkCount; ++linkID) - { - const ArticulationJointCoreData& jointDatum = jointData[linkID]; - - PxReal* jAccel = &jAccelerations[jointDatum.jointOffset]; - - ArticulationLink& link = links[linkID]; - - const PxTransform& body2World = link.bodyCore->body2World; - - for (PxU32 i = 0; i < jointDatum.dof; ++i) - { - const PxReal accel = jAccel[i]; - const PxVec3 localAngAccel = mArticulationData.mMotionMatrix[jointDatum.jointOffset + i].top * accel; - const PxVec3 localLinAccel = mArticulationData.mMotionMatrix[jointDatum.jointOffset + i].bottom * accel; - - motionAccels[linkID].top = body2World.rotate(localAngAccel); - motionAccels[linkID].bottom = body2World.rotate(localLinAccel); - } - } - } - - Cm::SpatialVector FeatherstoneArticulation::recomputeAcceleration(const PxU32 linkId, const PxReal dt) const - { - ArticulationLink* links = mArticulationData.getLinks(); - Cm::SpatialVectorF tMotionAccel; - const PxReal invDt = 1.f / dt; - if (linkId == 0) - { - const bool fixBase = mArticulationData.getArticulationFlags() & PxArticulationFlag::eFIX_BASE; - if (fixBase) - { - tMotionAccel = Cm::SpatialVectorF::Zero(); - } - else - { - Cm::SpatialVectorF tAccel = (mArticulationData.getMotionVelocity(0) - mArticulationData.mRootPreMotionVelocity) * invDt; - tMotionAccel.top = tAccel.top; - tMotionAccel.bottom = tAccel.bottom; - } - } - else - { - - ArticulationJointCoreData* jointData = mArticulationData.getJointData(); - - const PxReal* jAccelerations = mArticulationData.getJointAccelerations(); - - ArticulationLink& link = links[linkId]; - - const PxTransform& body2World = link.bodyCore->body2World; - - const ArticulationJointCoreData& jointDatum = jointData[linkId]; - - const PxReal* jAccel = &jAccelerations[jointDatum.jointOffset]; - - for (PxU32 i = 0; i < jointDatum.dof; ++i) - { - const PxReal accel = jAccel[i]; - - tMotionAccel.top = mArticulationData.mMotionMatrix[jointDatum.jointOffset + i].top * accel; - tMotionAccel.bottom = mArticulationData.mMotionMatrix[jointDatum.jointOffset + i].bottom * accel; - - tMotionAccel.top = body2World.rotate(tMotionAccel.top); - tMotionAccel.bottom = body2World.rotate(tMotionAccel.bottom); - } - } - - return Cm::SpatialVector(tMotionAccel.bottom, tMotionAccel.top); - - } - - void FeatherstoneArticulation::propagateLinksDown(ArticulationData& data, PxReal* jointVelocities, PxReal* jointPositions, Cm::SpatialVectorF* motionVelocities) { @@ -2131,6 +2284,7 @@ namespace Dy break; } default: + PX_ASSERT(false); break; } @@ -2423,10 +2577,10 @@ namespace Dy if (doForces) { - data.mSolverSpatialForces[0] *= invDt; + data.mSolverLinkSpatialForces[0] *= invDt; for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { - data.mSolverSpatialForces[linkID] = (data.mWorldSpatialArticulatedInertia[linkID] * data.mSolverSpatialForces[linkID]) * invDt; + data.mSolverLinkSpatialForces[linkID] = (data.mWorldSpatialArticulatedInertia[linkID] * data.mSolverLinkSpatialForces[linkID]) * invDt; } @@ -2436,7 +2590,7 @@ namespace Dy PxReal* constraintForces = data.getJointConstraintForces(); for (PxU32 linkID = 1; linkID < linkCount; ++linkID) { - const Cm::SpatialVectorF spatialForce = data.mSolverSpatialForces[linkID] - (data.mZAForces[linkID] + data.mZAInternalForces[linkID]); + const Cm::SpatialVectorF spatialForce = data.mSolverLinkSpatialForces[linkID] - (data.mZAForces[linkID] + data.mZAInternalForces[linkID]); ArticulationJointCoreData& jointDatum = data.mJointData[linkID]; const PxU32 offset = jointDatum.jointOffset; @@ -2464,7 +2618,7 @@ namespace Dy Cm::SpatialVectorF spatialForce(PxVec3(0.f), PxVec3(0.f)); if (sensor->mFlags & PxArticulationSensorFlag::eCONSTRAINT_SOLVER_FORCES) - spatialForce += data.mSolverSpatialForces[linkID]; + spatialForce += data.mSolverLinkSpatialForces[linkID]; if (sensor->mFlags & PxArticulationSensorFlag::eFORWARD_DYNAMICS_FORCES) spatialForce -= (data.mZAForces[linkID] + data.mZAInternalForces[linkID]); @@ -2582,8 +2736,9 @@ namespace Dy ArticulationJointCoreData& jointDatum = mArticulationData.getJointData(linkID); //calculate jointAcceleration PxReal* jA = &jointAccelerations[jointDatum.jointOffset]; - computeJointAccelerationW(jointDatum, pMotionAcceleration, jA, &mArticulationData.mIsW[jointDatum.jointOffset], linkID, - &mArticulationData.qstZIc[jointDatum.jointOffset]); + const InvStIs& invStIs = mArticulationData.mInvStIs[linkID]; + computeJointAccelerationW(jointDatum.dof, pMotionAcceleration, &mArticulationData.mIsW[jointDatum.jointOffset], invStIs, + &mArticulationData.qstZIc[jointDatum.jointOffset], jA); Cm::SpatialVectorF motionAcceleration(PxVec3(0.f), PxVec3(0.f)); diff --git a/physx/source/lowleveldynamics/src/DyFeatherstoneInverseDynamic.cpp b/physx/source/lowleveldynamics/src/DyFeatherstoneInverseDynamic.cpp index 335151652..cd8030648 100644 --- a/physx/source/lowleveldynamics/src/DyFeatherstoneInverseDynamic.cpp +++ b/physx/source/lowleveldynamics/src/DyFeatherstoneInverseDynamic.cpp @@ -306,9 +306,9 @@ namespace Dy if (flag & PxArticulationCacheFlag::eROOT_TRANSFORM) { ArticulationLink& rLink = mArticulationData.getLink(0); + // PT:: tag: scalar transform*transform rLink.bodyCore->body2World = cache.rootLinkData->transform * rLink.bodyCore->getBody2Actor(); mGPUDirtyFlags |= ArticulationDirtyFlag::eDIRTY_ROOT_TRANSFORM; - } if(flag & PxArticulationCacheFlag::eROOT_VELOCITIES) @@ -420,7 +420,23 @@ namespace Dy void FeatherstoneArticulation::initializeCommonData() { jcalc(mArticulationData); - computeRelativeTransformC2P(mArticulationData); + + { + //constants + const ArticulationLink* links = mArticulationData.getLinks(); + const PxU32 linkCount = mArticulationData.getLinkCount(); + const ArticulationJointCoreData* jointCoreDatas = mArticulationData.getJointData(); + const Cm::UnAlignedSpatialVector* motionMatrices = mArticulationData.getMotionMatrix(); + + //outputs + PxTransform* accumulatedPoses = mArticulationData.getAccumulatedPoses(); + PxVec3* rws = mArticulationData.getRw(); + Cm::UnAlignedSpatialVector* motionMatricesW = mArticulationData.getWorldMotionMatrix(); + + computeRelativeTransformC2P( + links, linkCount, jointCoreDatas, motionMatrices, + accumulatedPoses, rws, motionMatricesW); + } computeRelativeTransformC2B(mArticulationData); @@ -1052,8 +1068,11 @@ namespace Dy for (i0 = 0; linkID0 != common; linkID0 = links[linkID0].parent) { const PxU32 jointOffset = mArticulationData.getJointData(linkID0).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(linkID0).dof; - Z0 = FeatherstoneArticulation::propagateImpulseW(&data.getWorldIsInvD(jointOffset), data.getRw(linkID0), &data.getWorldMotionMatrix(jointOffset), Z0, dofCount); + const PxU8 dofCount = mArticulationData.getJointData(linkID0).dof; + Z0 = FeatherstoneArticulation::propagateImpulseW( + data.getRw(linkID0), + Z0, + &data.getWorldIsInvD(jointOffset), &data.getWorldMotionMatrix(jointOffset),dofCount); Z[links[linkID0].parent] = Z0; stack[i0++] = linkID0; } @@ -1061,8 +1080,11 @@ namespace Dy for (i1 = i0; linkID1 != common; linkID1 = links[linkID1].parent) { const PxU32 jointOffset = mArticulationData.getJointData(linkID1).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(linkID1).dof; - Z1 = FeatherstoneArticulation::propagateImpulseW(&data.getWorldIsInvD(jointOffset), data.getRw(linkID1), &data.getWorldMotionMatrix(jointOffset), Z1, dofCount); + const PxU8 dofCount = mArticulationData.getJointData(linkID1).dof; + Z1 = FeatherstoneArticulation::propagateImpulseW( + data.getRw(linkID1), + Z1, + &data.getWorldIsInvD(jointOffset), &data.getWorldMotionMatrix(jointOffset), dofCount); Z[links[linkID1].parent] = Z1; stack[i1++] = linkID1; } @@ -1074,8 +1096,11 @@ namespace Dy for (ic = i1; common; common = links[common].parent) { const PxU32 jointOffset = mArticulationData.getJointData(common).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(common).dof; - Z[links[common].parent] = FeatherstoneArticulation::propagateImpulseW(&data.getWorldIsInvD(jointOffset), data.getRw(common), &data.getMotionMatrix(jointOffset), Z[common], dofCount); + const PxU8 dofCount = mArticulationData.getJointData(common).dof; + Z[links[common].parent] = FeatherstoneArticulation::propagateImpulseW( + data.getRw(common), + Z[common], + &data.getWorldIsInvD(jointOffset), &data.getMotionMatrix(jointOffset), dofCount); stack[ic++] = common; } @@ -1155,12 +1180,15 @@ namespace Dy PX_ASSERT(linkID0 == link.parent); const PxU32 jointOffset = mArticulationData.getJointData(linkID1).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(linkID1).dof; + const PxU8 dofCount = mArticulationData.getJointData(linkID1).dof; //initialize child link spatial zero acceleration impulse Cm::SpatialVectorF Z1(-imp1.linear, -imp1.angular); //this calculate parent link spatial zero acceleration impulse - Cm::SpatialVectorF Z0 = FeatherstoneArticulation::propagateImpulseW(&mArticulationData.mIsInvDW[jointOffset], mArticulationData.getRw(linkID1), &mArticulationData.mWorldMotionMatrix[jointOffset], Z1, dofCount); + Cm::SpatialVectorF Z0 = FeatherstoneArticulation::propagateImpulseW( + mArticulationData.getRw(linkID1), + Z1, + &mArticulationData.mISInvStIS[jointOffset], &mArticulationData.mWorldMotionMatrix[jointOffset], dofCount); //in parent space const Cm::SpatialVectorF impulseDif = pImpulse - Z0; @@ -1215,10 +1243,12 @@ namespace Dy { ArticulationLink& tLink = links[i]; const PxU32 jointOffset = mArticulationData.getJointData(i).jointOffset; - const PxU32 dofCount = mArticulationData.getJointData(i).dof; + const PxU8 dofCount = mArticulationData.getJointData(i).dof; //ArticulationLinkData& tLinkDatum = linkData[i]; - Z[tLink.parent] = propagateImpulseW(&mArticulationData.mIsInvDW[jointOffset], mArticulationData.getRw(i), - &mArticulationData.mWorldMotionMatrix[jointOffset], Z[i], dofCount); + Z[tLink.parent] = propagateImpulseW( + mArticulationData.getRw(i), + Z[i], + &mArticulationData.mISInvStIS[jointOffset], &mArticulationData.mWorldMotionMatrix[jointOffset], dofCount); } //set velocity change of the root link to be zero @@ -1752,11 +1782,46 @@ namespace Dy computeLinkVelocities(mArticulationData, scratchData); computeZ(mArticulationData, gravity, scratchData); computeArticulatedSpatialZ(mArticulationData, scratchData); - computeLinkAcceleration(mArticulationData, scratchData, true); - + + { + //Constant terms. + const bool doIC = true; + const PxArticulationFlags articulationFlags = mArticulationData.getArticulationFlags(); + const ArticulationLink* links = mArticulationData.getLinks(); + const ArticulationJointCoreData* jointDatas = mArticulationData.getJointData(); + const Cm::SpatialVectorF* linkSpatialZAExtForces = scratchData.spatialZAVectors; + const Cm::SpatialVectorF* linkCoriolisForces = scratchData.coriolisVectors; + const PxVec3* linkRws = mArticulationData.getRw(); + const Cm::UnAlignedSpatialVector* jointDofMotionMatrices = mArticulationData.getWorldMotionMatrix(); + const SpatialMatrix& baseInvSpatialArticulatedInertiaW = mArticulationData.getBaseInvSpatialArticulatedInertiaW(); + + //Cached constant terms. + const InvStIs* linkInvStIs = mArticulationData.getInvStIS(); + const Cm::SpatialVectorF* jointDofIsWs = mArticulationData.getIsW(); + const PxReal* jointDofQstZics = mArticulationData.getQstZIc(); + + //Output + Cm::SpatialVectorF* linkMotionVelocities = scratchData.motionVelocities; + Cm::SpatialVectorF* linkMotionAccelerations = scratchData.motionAccelerations; + PxReal* jointAccelerations = scratchData.jointAccelerations; + PxReal* jointVelocities = scratchData.jointVelocities; + PxReal* jointNewVelocities = mArticulationData.getJointNewVelocities(); + + computeLinkAcceleration( + doIC, dt, + articulationFlags, + links, linkCount, jointDatas, + linkSpatialZAExtForces, linkCoriolisForces, linkRws, + jointDofMotionMatrices, baseInvSpatialArticulatedInertiaW, + linkInvStIs, jointDofIsWs, jointDofQstZics, + linkMotionAccelerations, linkMotionVelocities, + jointAccelerations, jointVelocities, jointNewVelocities); + } + //zero zero acceleration vector in the articulation data so that we can use this buffer to accumulated //impulse for the contacts/constraints in the PGS/TGS solvers PxMemZero(mArticulationData.getSpatialZAVectors(), sizeof(Cm::SpatialVectorF) * linkCount); + PxMemZero(mArticulationData.getSolverSpatialForces(), sizeof(Cm::SpatialVectorF) * linkCount); } allocator->free(constraintDescs); diff --git a/physx/source/lowleveldynamics/src/DyFrictionCorrelation.cpp b/physx/source/lowleveldynamics/src/DyFrictionCorrelation.cpp index 1adee2910..90ca7d07a 100644 --- a/physx/source/lowleveldynamics/src/DyFrictionCorrelation.cpp +++ b/physx/source/lowleveldynamics/src/DyFrictionCorrelation.cpp @@ -31,18 +31,17 @@ #include "PxsMaterialManager.h" #include "foundation/PxUtilities.h" #include "foundation/PxBounds3.h" +#include "foundation/PxVecMath.h" +#include "GuBounds.h" using namespace physx; +using namespace aos; namespace physx { - namespace Dy { - -namespace -{ -PX_FORCE_INLINE void initContactPatch(CorrelationBuffer::ContactPatchData& patch, PxU16 index, PxReal restitution, PxReal staticFriction, PxReal dynamicFriction, +static PX_FORCE_INLINE void initContactPatch(CorrelationBuffer::ContactPatchData& patch, PxU16 index, PxReal restitution, PxReal staticFriction, PxReal dynamicFriction, PxU8 flags) { patch.start = index; @@ -54,22 +53,6 @@ PX_FORCE_INLINE void initContactPatch(CorrelationBuffer::ContactPatchData& patch patch.dynamicFriction = dynamicFriction; } -PX_FORCE_INLINE void initFrictionPatch(FrictionPatch& p, const PxVec3& worldNormal, const PxTransform& body0Pose, const PxTransform& body1Pose, - PxReal restitution, PxReal staticFriction, PxReal dynamicFriction, PxU8 materialFlags) -{ - p.body0Normal = body0Pose.rotateInv(worldNormal); - p.body1Normal = body1Pose.rotateInv(worldNormal); - p.relativeQuat = body0Pose.q.getConjugate() * body1Pose.q; - p.anchorCount = 0; - p.broken = 0; - p.staticFriction = staticFriction; - p.dynamicFriction = dynamicFriction; - p.restitution = restitution; - p.materialFlags = materialFlags; -} -} - - bool createContactPatches(CorrelationBuffer& fb, const PxContactPoint* cb, PxU32 contactCount, PxReal normalTolerance) { // PT: this rewritten version below doesn't have LHS @@ -79,17 +62,17 @@ bool createContactPatches(CorrelationBuffer& fb, const PxContactPoint* cb, PxU32 return false; if(contactCount>0) { - CorrelationBuffer::ContactPatchData* currentPatchData = fb.contactPatches + contactPatchCount; + CorrelationBuffer::ContactPatchData* PX_RESTRICT currentPatchData = fb.contactPatches + contactPatchCount; const PxContactPoint* PX_RESTRICT contacts = cb; - PxU8 count=1; - initContactPatch(fb.contactPatches[contactPatchCount++], PxTo16(0), contacts[0].restitution, contacts[0].staticFriction, contacts[0].dynamicFriction, PxU8(contacts[0].materialFlags)); - PxBounds3 bounds(contacts[0].point, contacts[0].point); + Vec4V minV = V4LoadA(&contacts[0].point.x); + Vec4V maxV = minV; PxU32 patchIndex = 0; + PxU8 count = 1; for (PxU32 i = 1; i=normalTolerance) { - bounds.include(curContact.point); + const Vec4V ptV = V4LoadA(&curContact.point.x); + minV = V4Min(minV, ptV); + maxV = V4Max(maxV, ptV); + count++; } else @@ -111,24 +97,39 @@ bool createContactPatches(CorrelationBuffer& fb, const PxContactPoint* cb, PxU32 patchIndex = i; currentPatchData->count = count; count = 1; - currentPatchData->patchBounds = bounds; + StoreBounds(currentPatchData->patchBounds, minV, maxV); currentPatchData = fb.contactPatches + contactPatchCount; initContactPatch(fb.contactPatches[contactPatchCount++], PxTo16(i), curContact.restitution, curContact.staticFriction, curContact.dynamicFriction, PxU8(curContact.materialFlags)); - bounds = PxBounds3(curContact.point, curContact.point); + minV = V4LoadA(&curContact.point.x); + maxV = minV; } } if(count!=1) currentPatchData->count = count; - currentPatchData->patchBounds = bounds; + StoreBounds(currentPatchData->patchBounds, minV, maxV); } fb.contactPatchCount = contactPatchCount; return true; } +static PX_FORCE_INLINE void initFrictionPatch(FrictionPatch& p, const PxVec3& worldNormal, const PxTransform& body0Pose, const PxTransform& body1Pose, + PxReal restitution, PxReal staticFriction, PxReal dynamicFriction, PxU8 materialFlags) +{ + p.body0Normal = body0Pose.rotateInv(worldNormal); + p.body1Normal = body1Pose.rotateInv(worldNormal); + p.relativeQuat = body0Pose.q.getConjugate() * body1Pose.q; + p.anchorCount = 0; + p.broken = 0; + p.staticFriction = staticFriction; + p.dynamicFriction = dynamicFriction; + p.restitution = restitution; + p.materialFlags = materialFlags; +} + bool correlatePatches(CorrelationBuffer& fb, const PxContactPoint* cb, const PxTransform& bodyFrame0, @@ -230,7 +231,6 @@ void growPatches(CorrelationBuffer& fb, if(cb[cp.start+j].separation < frictionOffsetThreshold) { - switch(anchorCount) { case 0: diff --git a/physx/source/geomutils/src/distance/GuDistanceSegmentTriangleSIMD.h b/physx/source/lowleveldynamics/src/DyPGS.h similarity index 68% rename from physx/source/geomutils/src/distance/GuDistanceSegmentTriangleSIMD.h rename to physx/source/lowleveldynamics/src/DyPGS.h index 94b2a9502..f77492c39 100644 --- a/physx/source/geomutils/src/distance/GuDistanceSegmentTriangleSIMD.h +++ b/physx/source/lowleveldynamics/src/DyPGS.h @@ -26,28 +26,30 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef GU_DISTANCE_SEGMENT_TRIANGLE_SIMD_H -#define GU_DISTANCE_SEGMENT_TRIANGLE_SIMD_H +#ifndef DY_PGS_H +#define DY_PGS_H -#include "common/PxPhysXCommonConfig.h" -#include "foundation/PxVecMath.h" +#include "foundation/PxPreprocessor.h" +#include "foundation/PxSimpleTypes.h" namespace physx { -namespace Gu -{ + struct PxSolverConstraintDesc; + + namespace Dy + { + struct SolverContext; - /* - closest0 is the closest point on segment pq - closest1 is the closest point on triangle abc - */ - PX_PHYSX_COMMON_API aos::FloatV distanceSegmentTriangleSquared( - const aos::Vec3VArg p, const aos::Vec3VArg q, - const aos::Vec3VArg a, const aos::Vec3VArg b, const aos::Vec3VArg c, - aos::Vec3V& closest0, aos::Vec3V& closest1); + // PT: using defines like we did in Gu (GU_OVERLAP_FUNC_PARAMS, etc). Additionally this gives a + // convenient way to find the PGS solver methods, which are scattered in different files and use + // the same function names as other functions (with a different signature). -} // namespace Gu + #define DY_PGS_SOLVE_METHOD_PARAMS const PxSolverConstraintDesc* desc, PxU32 constraintCount, SolverContext& cache + typedef void (*SolveBlockMethod) (DY_PGS_SOLVE_METHOD_PARAMS); + typedef void (*SolveWriteBackBlockMethod) (DY_PGS_SOLVE_METHOD_PARAMS); + typedef void (*WriteBackBlockMethod) (DY_PGS_SOLVE_METHOD_PARAMS); + } } #endif diff --git a/physx/source/lowleveldynamics/src/DyRigidBodyToSolverBody.cpp b/physx/source/lowleveldynamics/src/DyRigidBodyToSolverBody.cpp index 67d260904..3217431c5 100644 --- a/physx/source/lowleveldynamics/src/DyRigidBodyToSolverBody.cpp +++ b/physx/source/lowleveldynamics/src/DyRigidBodyToSolverBody.cpp @@ -35,9 +35,9 @@ using namespace physx; // PT: TODO: SIMDify all this... -void Dy::copyToSolverBodyData(const PxVec3& linearVelocity, const PxVec3& angularVelocity, const PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, - const PxReal maxDepenetrationVelocity, const PxReal maxContactImpulse, const PxU32 nodeIndex, const PxReal reportThreshold, PxSolverBodyData& data, PxU32 lockFlags, - const PxReal dt, bool gyroscopicForces) +void Dy::copyToSolverBodyData(const PxVec3& linearVelocity, const PxVec3& angularVelocity, PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, + PxReal maxDepenetrationVelocity, PxReal maxContactImpulse, PxU32 nodeIndex, PxReal reportThreshold, PxSolverBodyData& data, PxU32 lockFlags, + PxReal dt, bool gyroscopicForces) { data.nodeIndex = nodeIndex; @@ -69,7 +69,6 @@ void Dy::copyToSolverBodyData(const PxVec3& linearVelocity, const PxVec3& angula ang += newDeltaAngVel; } - if (lockFlags) { if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_X) diff --git a/physx/source/lowleveldynamics/src/DySleep.cpp b/physx/source/lowleveldynamics/src/DySleep.cpp new file mode 100644 index 000000000..abac8be37 --- /dev/null +++ b/physx/source/lowleveldynamics/src/DySleep.cpp @@ -0,0 +1,236 @@ +// 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. + +#include "DySleep.h" + +using namespace physx; + +// PT: TODO: refactor this, parts of the two codepaths are very similar + +static PX_FORCE_INLINE PxReal updateWakeCounter(PxsRigidBody* originalBody, PxReal dt, bool enableStabilization, const Cm::SpatialVector& motionVelocity, bool hasStaticTouch) +{ + PxsBodyCore& bodyCore = originalBody->getCore(); + + // update the body's sleep state and + const PxReal wakeCounterResetTime = 20.0f*0.02f; + + PxReal wc = bodyCore.wakeCounter; + + if (enableStabilization) + { + const PxTransform& body2World = bodyCore.body2World; + + // calculate normalized energy: kinetic energy divided by mass + + const PxVec3& t = bodyCore.inverseInertia; + const PxVec3 inertia( t.x > 0.0f ? 1.0f / t.x : 1.0f, + t.y > 0.0f ? 1.0f / t.y : 1.0f, + t.z > 0.0f ? 1.0f / t.z : 1.0f); + + const PxVec3& sleepLinVelAcc = motionVelocity.linear; + const PxVec3 sleepAngVelAcc = body2World.q.rotateInv(motionVelocity.angular); + + // scale threshold by cluster factor (more contacts => higher sleep threshold) + //const PxReal clusterFactor = PxReal(1u + getNumUniqueInteractions()); + + PxReal invMass = bodyCore.inverseMass; + if (invMass == 0.0f) + invMass = 1.0f; + + const PxReal angular = sleepAngVelAcc.multiply(sleepAngVelAcc).dot(inertia) * invMass; + const PxReal linear = sleepLinVelAcc.magnitudeSquared(); + const PxReal frameNormalizedEnergy = 0.5f * (angular + linear); + + const PxReal cf = hasStaticTouch ? PxReal(PxMin(10u, bodyCore.numCountedInteractions)) : 0.0f; + const PxReal freezeThresh = cf*bodyCore.freezeThreshold; + + originalBody->freezeCount = PxMax(originalBody->freezeCount - dt, 0.0f); + bool settled = true; + + PxReal accelScale = PxMin(1.0f, originalBody->accelScale + dt); + + if (frameNormalizedEnergy >= freezeThresh) + { + settled = false; + originalBody->freezeCount = PXD_FREEZE_INTERVAL; + } + + if (!hasStaticTouch) + { + accelScale = 1.0f; + settled = false; + } + + bool freeze = false; + if (settled) + { + //Dampen bodies that are just about to go to sleep + if (cf > 1.0f) + { + const PxReal sleepDamping = PXD_SLEEP_DAMPING; + const PxReal sleepDampingTimesDT = sleepDamping*dt; + const PxReal d = 1.0f - sleepDampingTimesDT; + bodyCore.linearVelocity = bodyCore.linearVelocity * d; + bodyCore.angularVelocity = bodyCore.angularVelocity * d; + accelScale = accelScale * 0.75f + 0.25f*PXD_FREEZE_SCALE; + } + freeze = originalBody->freezeCount == 0.0f && frameNormalizedEnergy < (bodyCore.freezeThreshold * PXD_FREEZE_TOLERANCE); + } + + originalBody->accelScale = accelScale; + + const PxU32 wasFrozen = originalBody->mInternalFlags & PxsRigidBody::eFROZEN; + PxU16 flags; + if(freeze) + { + //current flag isn't frozen but freeze flag raise so we need to raise the frozen flag in this frame + flags = PxU16(PxsRigidBody::eFROZEN); + if(!wasFrozen) + flags |= PxsRigidBody::eFREEZE_THIS_FRAME; + bodyCore.body2World = originalBody->getLastCCDTransform(); + } + else + { + flags = 0; + if(wasFrozen) + flags |= PxsRigidBody::eUNFREEZE_THIS_FRAME; + } + originalBody->mInternalFlags = flags; + + /*KS: New algorithm for sleeping when using stabilization: + * Energy *this frame* must be higher than sleep threshold and accumulated energy over previous frames + * must be higher than clusterFactor*energyThreshold. + */ + if (wc < wakeCounterResetTime * 0.5f || wc < dt) + { + //Accumulate energy + originalBody->sleepLinVelAcc += sleepLinVelAcc; + originalBody->sleepAngVelAcc += sleepAngVelAcc; + + //If energy this frame is high + if (frameNormalizedEnergy >= bodyCore.sleepThreshold) + { + //Compute energy over sleep preparation time + const PxReal sleepAngular = originalBody->sleepAngVelAcc.multiply(originalBody->sleepAngVelAcc).dot(inertia) * invMass; + const PxReal sleepLinear = originalBody->sleepLinVelAcc.magnitudeSquared(); + const PxReal normalizedEnergy = 0.5f * (sleepAngular + sleepLinear); + const PxReal sleepClusterFactor = PxReal(1u + bodyCore.numCountedInteractions); + // scale threshold by cluster factor (more contacts => higher sleep threshold) + const PxReal threshold = sleepClusterFactor*bodyCore.sleepThreshold; + + //If energy over sleep preparation time is high + if (normalizedEnergy >= threshold) + { + //Wake up + //PX_ASSERT(isActive()); + originalBody->resetSleepFilter(); + + const float factor = bodyCore.sleepThreshold == 0.0f ? 2.0f : PxMin(normalizedEnergy / threshold, 2.0f); + PxReal oldWc = wc; + wc = factor * 0.5f * wakeCounterResetTime + dt * (sleepClusterFactor - 1.0f); + bodyCore.solverWakeCounter = wc; + //if (oldWc == 0.0f) // for the case where a sleeping body got activated by the system (not the user) AND got processed by the solver as well + // notifyNotReadyForSleeping(bodyCore.nodeIndex); + + if (oldWc == 0.0f) + originalBody->mInternalFlags |= PxsRigidBody::eACTIVATE_THIS_FRAME; + + return wc; + } + } + } + } + else + { + if (wc < wakeCounterResetTime * 0.5f || wc < dt) + { + const PxTransform& body2World = bodyCore.body2World; + + // calculate normalized energy: kinetic energy divided by mass + const PxVec3& t = bodyCore.inverseInertia; + const PxVec3 inertia( t.x > 0.0f ? 1.0f / t.x : 1.0f, + t.y > 0.0f ? 1.0f / t.y : 1.0f, + t.z > 0.0f ? 1.0f / t.z : 1.0f); + + const PxVec3& sleepLinVelAcc = motionVelocity.linear; + const PxVec3 sleepAngVelAcc = body2World.q.rotateInv(motionVelocity.angular); + + originalBody->sleepLinVelAcc += sleepLinVelAcc; + originalBody->sleepAngVelAcc += sleepAngVelAcc; + + PxReal invMass = bodyCore.inverseMass; + if (invMass == 0.0f) + invMass = 1.0f; + + const PxReal angular = originalBody->sleepAngVelAcc.multiply(originalBody->sleepAngVelAcc).dot(inertia) * invMass; + const PxReal linear = originalBody->sleepLinVelAcc.magnitudeSquared(); + const PxReal normalizedEnergy = 0.5f * (angular + linear); + + // scale threshold by cluster factor (more contacts => higher sleep threshold) + const PxReal clusterFactor = PxReal(1 + bodyCore.numCountedInteractions); + const PxReal threshold = clusterFactor*bodyCore.sleepThreshold; + + if (normalizedEnergy >= threshold) + { + //PX_ASSERT(isActive()); + originalBody->resetSleepFilter(); + + const float factor = threshold == 0.0f ? 2.0f : PxMin(normalizedEnergy / threshold, 2.0f); + PxReal oldWc = wc; + wc = factor * 0.5f * wakeCounterResetTime + dt * (clusterFactor - 1.0f); + bodyCore.solverWakeCounter = wc; + PxU16 flags = 0; + if (oldWc == 0.0f) // for the case where a sleeping body got activated by the system (not the user) AND got processed by the solver as well + { + flags |= PxsRigidBody::eACTIVATE_THIS_FRAME; + //notifyNotReadyForSleeping(bodyCore.nodeIndex); + } + + originalBody->mInternalFlags = flags; + + return wc; + } + } + } + + wc = PxMax(wc - dt, 0.0f); + bodyCore.solverWakeCounter = wc; + return wc; +} + +void Dy::sleepCheck(PxsRigidBody* originalBody, PxReal dt, bool enableStabilization, const Cm::SpatialVector& motionVelocity, bool hasStaticTouch) +{ + const PxReal wc = updateWakeCounter(originalBody, dt, enableStabilization, motionVelocity, hasStaticTouch); + if(wc == 0.0f) + { + //PxsBodyCore& bodyCore = originalBody->getCore(); + originalBody->mInternalFlags |= PxsRigidBody::eDEACTIVATE_THIS_FRAME; + // notifyReadyForSleeping(bodyCore.nodeIndex); + originalBody->resetSleepFilter(); + } +} diff --git a/physx/source/lowlevel/software/include/PxsIncrementalConstraintPartitioning.h b/physx/source/lowleveldynamics/src/DySleep.h similarity index 85% rename from physx/source/lowlevel/software/include/PxsIncrementalConstraintPartitioning.h rename to physx/source/lowleveldynamics/src/DySleep.h index 66fd3f5bd..3e1ce9b7f 100644 --- a/physx/source/lowlevel/software/include/PxsIncrementalConstraintPartitioning.h +++ b/physx/source/lowleveldynamics/src/DySleep.h @@ -26,14 +26,19 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXS_INCREMENTAL_CONSTRAINT_PARTITIONING_H -#define PXS_INCREMENTAL_CONSTRAINT_PARTITIONING_H +#ifndef DY_SLEEP_H +#define DY_SLEEP_H -#include "PxsSimpleIslandManager.h" +#include "PxvDynamics.h" +#include "PxsRigidBody.h" +#include "DySleepingConfigulation.h" namespace physx { - +namespace Dy +{ + void sleepCheck(PxsRigidBody* originalBody, PxReal dt, bool enableStabilization, const Cm::SpatialVector& motionVelocity, bool hasStaticTouch); +} } -#endif \ No newline at end of file +#endif diff --git a/physx/source/lowleveldynamics/src/DySolverBody.h b/physx/source/lowleveldynamics/src/DySolverBody.h index c6065c42d..39e03ac1c 100644 --- a/physx/source/lowleveldynamics/src/DySolverBody.h +++ b/physx/source/lowleveldynamics/src/DySolverBody.h @@ -52,9 +52,9 @@ PX_FORCE_INLINE PxVec3 computeSafeSqrtInertia(const PxVec3& v) v.z == 0.0f ? 0.0f : PxSqrt(v.z)); } -void copyToSolverBodyData(const PxVec3& linearVelocity, const PxVec3& angularVelocity, const PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, - const PxReal maxDepenetrationVelocity, const PxReal maxContactImpulse, const PxU32 nodeIndex, const PxReal reportThreshold, PxSolverBodyData& solverBodyData, PxU32 lockFlags, - const PxReal dt, bool gyroscopicForces); +void copyToSolverBodyData(const PxVec3& linearVelocity, const PxVec3& angularVelocity, PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, + PxReal maxDepenetrationVelocity, PxReal maxContactImpulse, PxU32 nodeIndex, PxReal reportThreshold, PxSolverBodyData& solverBodyData, PxU32 lockFlags, + PxReal dt, bool gyroscopicForces); // PT: TODO: using PxsBodyCore in the interface makes us write less data to the stack for passing arguments, and we can take advantage of the class layout // (we know what is aligned or not, we know if it is safe to V4Load vectors, etc). Note that this is what we previously had, which is why PxsBodyCore was still diff --git a/physx/source/lowleveldynamics/src/DySolverConstraintDesc.h b/physx/source/lowleveldynamics/src/DySolverConstraintDesc.h index 9c055d362..2dcb8bf36 100644 --- a/physx/source/lowleveldynamics/src/DySolverConstraintDesc.h +++ b/physx/source/lowleveldynamics/src/DySolverConstraintDesc.h @@ -40,18 +40,9 @@ namespace physx struct PxcNpWorkUnit; struct PxsContactManagerOutput; -namespace Cm -{ - class SpatialVector; -} - -struct PxSolverBody; -struct PxSolverBodyData; - namespace Dy { class FeatherstoneArticulation; -struct FsData; // dsequeira: moved this articulation stuff here to sever a build dep on Articulation.h through DyThreadContext.h and onward diff --git a/physx/source/lowleveldynamics/src/DySolverConstraintTypes.h b/physx/source/lowleveldynamics/src/DySolverConstraintTypes.h index 3b14ebd85..38603982b 100644 --- a/physx/source/lowleveldynamics/src/DySolverConstraintTypes.h +++ b/physx/source/lowleveldynamics/src/DySolverConstraintTypes.h @@ -38,21 +38,24 @@ namespace physx enum SolverConstraintType { DY_SC_TYPE_NONE = 0, - DY_SC_TYPE_RB_CONTACT, // RB-only contact - DY_SC_TYPE_RB_1D, // RB-only 1D constraint - DY_SC_TYPE_EXT_CONTACT, // contact involving articulations - DY_SC_TYPE_EXT_1D, // 1D constraint involving articulations - DY_SC_TYPE_STATIC_CONTACT, // RB-only contact where body b is static - DY_SC_TYPE_NOFRICTION_RB_CONTACT, //RB-only contact with no friction patch + + DY_SC_TYPE_RB_CONTACT, // RB-only contact + DY_SC_TYPE_RB_1D, // RB-only 1D constraint + DY_SC_TYPE_EXT_CONTACT, // contact involving articulations + DY_SC_TYPE_EXT_1D, // 1D constraint involving articulations + DY_SC_TYPE_STATIC_CONTACT, // RB-only contact where body b is static + DY_SC_TYPE_NOFRICTION_RB_CONTACT, //RB-only contact with no friction patch DY_SC_TYPE_BLOCK_RB_CONTACT, DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT, DY_SC_TYPE_BLOCK_1D, + // PT: the following types are only used in the PGS PF solver DY_SC_TYPE_FRICTION, DY_SC_TYPE_STATIC_FRICTION, DY_SC_TYPE_EXT_FRICTION, DY_SC_TYPE_BLOCK_FRICTION, DY_SC_TYPE_BLOCK_STATIC_FRICTION, - DY_SC_CONSTRAINT_TYPE_COUNT //Count of the number of different constraint types in the solver + + DY_SC_CONSTRAINT_TYPE_COUNT //Count of the number of different constraint types in the solver }; enum SolverConstraintFlags diff --git a/physx/source/lowleveldynamics/src/DySolverConstraints.cpp b/physx/source/lowleveldynamics/src/DySolverConstraints.cpp index f59b41fbe..4ba418bcf 100644 --- a/physx/source/lowleveldynamics/src/DySolverConstraints.cpp +++ b/physx/source/lowleveldynamics/src/DySolverConstraints.cpp @@ -26,7 +26,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "foundation/PxPreprocessor.h" #include "foundation/PxVecMath.h" @@ -41,17 +40,14 @@ #include "foundation/PxAtomic.h" #include "DySolverConstraintsShared.h" #include "DyFeatherstoneArticulation.h" +#include "DyPGS.h" -namespace physx -{ - -namespace Dy -{ +using namespace physx; +using namespace Dy; //Port of scalar implementation to SIMD maths with some interleaving of instructions -void solve1D(const PxSolverConstraintDesc& desc, SolverContext& cache) +static void solve1D(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { - PX_UNUSED(cache); PxSolverBody& b0 = *desc.bodyA; PxSolverBody& b1 = *desc.bodyB; @@ -60,7 +56,7 @@ void solve1D(const PxSolverConstraintDesc& desc, SolverContext& cache) return; //PxU32 length = desc.constraintLength; - const SolverConstraint1DHeader* PX_RESTRICT header = reinterpret_cast(bPtr); + const SolverConstraint1DHeader* PX_RESTRICT header = reinterpret_cast(bPtr); SolverConstraint1D* PX_RESTRICT base = reinterpret_cast(bPtr + sizeof(SolverConstraint1DHeader)); Vec3V linVel0 = V3LoadA(b0.linearVelocity); @@ -73,8 +69,8 @@ void solve1D(const PxSolverConstraintDesc& desc, SolverContext& cache) const FloatV invInertiaScale0 = FLoad(header->angularInvMassScale0); const FloatV invInertiaScale1 = FLoad(header->angularInvMassScale1); - - for(PxU32 i=0; icount;++i, base++) + const PxU32 count = header->count; + for(PxU32 i=0; i(desc.constraint); if (header == NULL) return; PxU8* base = desc.constraint + sizeof(SolverConstraint1DHeader); - PxU32 stride = header->type == DY_SC_TYPE_EXT_1D ? sizeof(SolverConstraint1DExt) : sizeof(SolverConstraint1D); + const PxU32 stride = header->type == DY_SC_TYPE_EXT_1D ? sizeof(SolverConstraint1DExt) : sizeof(SolverConstraint1D); - for(PxU32 i=0; icount; i++) + const PxU32 count = header->count; + for(PxU32 i=0; i(base); @@ -144,7 +144,7 @@ void conclude1D(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) // ============================================================== -void solveContact(const PxSolverConstraintDesc& desc, SolverContext& cache) +static void solveContact(const PxSolverConstraintDesc& desc, SolverContext& cache) { PxSolverBody& b0 = *desc.bodyA; PxSolverBody& b1 = *desc.bodyB; @@ -206,7 +206,6 @@ void solveContact(const PxSolverConstraintDesc& desc, SolverContext& cache) SolverContactFriction& f = frictions[i]; PxPrefetchLine(&frictions[i],128); - const Vec4V normalXYZ_appliedForceW = f.normalXYZ_appliedForceW; const Vec4V raXnXYZ_velMultiplierW = f.raXnXYZ_velMultiplierW; const Vec4V rbXnXYZ_biasW = f.rbXnXYZ_biasW; @@ -228,10 +227,8 @@ void solveContact(const PxSolverConstraintDesc& desc, SolverContext& cache) const Vec3V v1 = V3MulAdd(linVel1, normal, V3Mul(angState1, rbXn)); const FloatV normalVel = V3SumElems(V3Sub(v0, v1)); - - // appliedForce -bias * velMultiplier - a hoisted part of the total impulse computation - const FloatV tmp1 = FNegScaleSub(FSub(bias, targetVel),velMultiplier,appliedForce); + const FloatV tmp1 = FNegScaleSub(FSub(bias, targetVel), velMultiplier, appliedForce); // Algorithm: // if abs(appliedForce + deltaF) > maxFrictionImpulse @@ -266,12 +263,9 @@ void solveContact(const PxSolverConstraintDesc& desc, SolverContext& cache) angState1 = V3NegScaleSub(rbXn, FMul(deltaF, angDom1), angState1); f.setAppliedForce(newAppliedForce); - - } Store_From_BoolV(broken, &hdr->broken); } - } PX_ASSERT(b0.linearVelocity.isFinite()); @@ -293,7 +287,7 @@ void solveContact(const PxSolverConstraintDesc& desc, SolverContext& cache) PX_ASSERT(currPtr == last); } -void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cache) +static void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cache) { PxSolverBody& b0 = *desc.bodyA; //PxSolverBody& b1 = *desc.bodyB; @@ -324,14 +318,11 @@ void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cac SolverContactFriction* PX_RESTRICT frictions = reinterpret_cast(currPtr); currPtr += numFrictionConstr * sizeof(SolverContactFriction); - - const FloatV invMassA = FLoad(hdr->invMass0); const Vec3V contactNormal = Vec3V_From_Vec4V_WUndefined(hdr->normal_minAppliedImpulseForFrictionW); const FloatV angDom0 = FLoad(hdr->angDom0); - const FloatV accumulatedNormalImpulse = solveStaticContacts(contacts, numNormalConstr, contactNormal, invMassA, angDom0, linVel0, angState0, forceBuffer); @@ -348,7 +339,6 @@ void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cac { SolverContactFriction& f = frictions[i]; PxPrefetchLine(&frictions[i],128); - const Vec4V normalXYZ_appliedForceW = f.normalXYZ_appliedForceW; const Vec4V raXnXYZ_velMultiplierW = f.raXnXYZ_velMultiplierW; @@ -371,7 +361,6 @@ void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cac const Vec3V v0 = V3MulAdd(linVel0, normal, V3Mul(angState0, raXn)); const FloatV normalVel = V3SumElems(v0); - // appliedForce -bias * velMultiplier - a hoisted part of the total impulse computation const FloatV tmp1 = FNegScaleSub(FSub(bias, targetVel),velMultiplier,appliedForce); @@ -406,11 +395,9 @@ void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cac angState0 = V3ScaleAdd(raXn, FMul(deltaF, angDom0), angState0); f.setAppliedForce(newAppliedForce); - } Store_From_BoolV(broken, &hdr->broken); } - } PX_ASSERT(b0.linearVelocity.isFinite()); @@ -426,7 +413,6 @@ void solveContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cac PX_ASSERT(currPtr == last); } - void concludeContact(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { PxU8* PX_RESTRICT cPtr = desc.constraint; @@ -475,7 +461,6 @@ void concludeContact(const PxSolverConstraintDesc& desc, SolverContext& /*cache* void writeBackContact(const PxSolverConstraintDesc& desc, SolverContext& cache, PxSolverBodyData& bd0, PxSolverBodyData& bd1) { - PxReal normalForce = 0; PxU8* PX_RESTRICT cPtr = desc.constraint; @@ -499,7 +484,6 @@ void writeBackContact(const PxSolverConstraintDesc& desc, SolverContext& cache, const PxU32 pointStride = hdr->type == DY_SC_TYPE_EXT_CONTACT ? sizeof(SolverContactPointExt) : sizeof(SolverContactPoint); - cPtr += pointStride * numNormalConstr; PxF32* forceBuffer = reinterpret_cast(cPtr); cPtr += sizeof(PxF32) * ((numNormalConstr + 3) & (~3)); @@ -523,12 +507,9 @@ void writeBackContact(const PxSolverConstraintDesc& desc, SolverContext& cache, } cPtr += frictionStride * numFrictionConstr; - } PX_ASSERT(cPtr == last); - - if(forceThreshold && desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY && desc.linkIndexB == PxSolverConstraintDesc::RIGID_BODY && normalForce !=0 && (bd0.reportThreshold < PX_MAX_REAL || bd1.reportThreshold < PX_MAX_REAL)) { @@ -554,10 +535,11 @@ void writeBack1D(const PxSolverConstraintDesc& desc, SolverContext&, PxSolverBod { SolverConstraint1DHeader* header = reinterpret_cast(desc.constraint); PxU8* base = desc.constraint + sizeof(SolverConstraint1DHeader); - PxU32 stride = header->type == DY_SC_TYPE_EXT_1D ? sizeof(SolverConstraint1DExt) : sizeof(SolverConstraint1D); + const PxU32 stride = header->type == DY_SC_TYPE_EXT_1D ? sizeof(SolverConstraint1DExt) : sizeof(SolverConstraint1D); PxVec3 lin(0), ang(0); - for(PxU32 i=0; icount; i++) + const PxU32 count = header->count; + for(PxU32 i=0; i(base); if(c->flags & DY_SC_FLAG_OUTPUT_FORCE) @@ -578,8 +560,7 @@ void writeBack1D(const PxSolverConstraintDesc& desc, SolverContext&, PxSolverBod } } - -void solve1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solve1DBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -591,7 +572,7 @@ void solve1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 c solve1D(desc[constraintCount-1], cache); } -void solve1DConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solve1DConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -605,7 +586,7 @@ void solve1DConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const conclude1D(desc[constraintCount-1], cache); } -void solve1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solve1DBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -623,7 +604,7 @@ void solve1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, cons writeBack1D(desc[constraintCount-1], cache, bd0, bd1); } -void writeBack1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void writeBack1DBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -639,7 +620,7 @@ void writeBack1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU writeBack1D(desc[constraintCount-1], cache, bd0, bd1); } -void solveContactBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -651,7 +632,7 @@ void solveContactBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU solveContact(desc[constraintCount-1], cache); } -void solveContactConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -665,7 +646,7 @@ void solveContactConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, c concludeContact(desc[constraintCount-1], cache); } -void solveContactBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -694,7 +675,7 @@ void solveContactBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, } } -void solveContact_BStaticBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContact_BStaticBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -706,7 +687,7 @@ void solveContact_BStaticBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, c solveContact_BStatic(desc[constraintCount-1], cache); } -void solveContact_BStaticConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContact_BStaticConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -720,7 +701,7 @@ void solveContact_BStaticConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT concludeContact(desc[constraintCount-1], cache); } -void solveContact_BStaticBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContact_BStaticBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 1; a < constraintCount; ++a) { @@ -756,7 +737,8 @@ void clearExt1D(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) const SolverConstraint1DHeader* PX_RESTRICT header = reinterpret_cast(bPtr); SolverConstraint1DExt* PX_RESTRICT base = reinterpret_cast(bPtr + sizeof(SolverConstraint1DHeader)); - for (PxU32 i = 0; i < header->count; ++i, base++) + const PxU32 count = header->count; + for (PxU32 i=0; iappliedForce = 0.f; } @@ -766,12 +748,11 @@ void solveExt1D(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& linVe Vec3V& li0, Vec3V& li1, Vec3V& ai0, Vec3V& ai1) { PxU8* PX_RESTRICT bPtr = desc.constraint; - const SolverConstraint1DHeader* PX_RESTRICT header = reinterpret_cast(bPtr); + const SolverConstraint1DHeader* PX_RESTRICT header = reinterpret_cast(bPtr); SolverConstraint1DExt* PX_RESTRICT base = reinterpret_cast(bPtr + sizeof(SolverConstraint1DHeader)); - - - for (PxU32 i = 0; icount; ++i, base++) + const PxU32 count = header->count; + for (PxU32 i=0; ilinearInvMassScale0)); @@ -827,7 +807,6 @@ void solveExt1D(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& linVe //Port of scalar implementation to SIMD maths with some interleaving of instructions void solveExt1D(const PxSolverConstraintDesc& desc, SolverContext& cache) { - //PxU32 length = desc.constraintLength; Vec3V linVel0, angVel0, linVel1, angVel1; @@ -908,7 +887,6 @@ FloatV solveExtContacts(SolverContactPointExt* contacts, const PxU32 nbContactPo Vec3V& li1, Vec3V& ai1, PxF32* PX_RESTRICT appliedForceBuffer) { - FloatV accumulatedNormalImpulse = FZero(); for (PxU32 i = 0; i(currPtr); @@ -998,7 +972,6 @@ void solveExtContact(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& SolverContactFrictionExt* PX_RESTRICT frictions = reinterpret_cast(currPtr); currPtr += numFrictionConstr * sizeof(SolverContactFrictionExt); - Vec3V li0 = V3Zero(), li1 = V3Zero(), ai0 = V3Zero(), ai1 = V3Zero(); const Vec3V contactNormal = Vec3V_From_Vec4V(hdr->normal_minAppliedImpulseForFrictionW); @@ -1007,7 +980,6 @@ void solveExtContact(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& const FloatV accumulatedNormalImpulse = FMax(solveExtContacts(contacts, numNormalConstr, contactNormal, linVel0, angVel0, linVel1, angVel1, li0, ai0, li1, ai1, appliedForceBuffer), minNorImpulse); - if (doFriction && numFrictionConstr) { PxPrefetchLine(frictions); @@ -1092,7 +1064,6 @@ void solveExtContact(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& PX_ASSERT(av0.magnitude() < 30.f); PX_ASSERT(av1.magnitude() < 30.f); #endif - f.setAppliedForce(newAppliedForce); } Store_From_BoolV(broken, &hdr->broken); @@ -1110,8 +1081,7 @@ void solveExtContact(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& } } - -void solveExtContact(const PxSolverConstraintDesc& desc, SolverContext& cache) +static void solveExtContact(const PxSolverConstraintDesc& desc, SolverContext& cache) { Vec3V linVel0, angVel0, linVel1, angVel1; @@ -1188,16 +1158,13 @@ void solveExtContact(const PxSolverConstraintDesc& desc, SolverContext& cache) } } - -void solveExtContactBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtContactBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveExtContact(desc[a], cache); - } } -void solveExtContactConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtContactConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -1206,7 +1173,7 @@ void solveExtContactConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc } } -void solveExtContactBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtContactBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -1229,15 +1196,13 @@ void solveExtContactBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT des } } -void solveExt1DBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExt1DBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveExt1D(desc[a], cache); - } } -void solveExt1DConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExt1DConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -1246,7 +1211,7 @@ void solveExt1DConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, con } } -void solveExt1DBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExt1DBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -1257,7 +1222,9 @@ void solveExt1DBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, co } } -void ext1DBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +// PT: not sure what happened but the following ones weren't actually used + +/*void ext1DBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -1267,39 +1234,34 @@ void ext1DBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const P } } -void solveConcludeExtContact (const PxSolverConstraintDesc& desc, SolverContext& cache) +void solveConcludeExtContact(const PxSolverConstraintDesc& desc, SolverContext& cache) { solveExtContact(desc, cache); concludeContact(desc, cache); } -void solveConcludeExt1D (const PxSolverConstraintDesc& desc, SolverContext& cache) +void solveConcludeExt1D(const PxSolverConstraintDesc& desc, SolverContext& cache) { solveExt1D(desc, cache); conclude1D(desc, cache); } - void solveConclude1D(const PxSolverConstraintDesc& desc, SolverContext& cache) { solve1D(desc, cache); conclude1D(desc, cache); } -void solveConcludeContact (const PxSolverConstraintDesc& desc, SolverContext& cache) +void solveConcludeContact(const PxSolverConstraintDesc& desc, SolverContext& cache) { solveContact(desc, cache); concludeContact(desc, cache); } -void solveConcludeContact_BStatic (const PxSolverConstraintDesc& desc, SolverContext& cache) +void solveConcludeContact_BStatic(const PxSolverConstraintDesc& desc, SolverContext& cache) { solveContact_BStatic(desc, cache); concludeContact(desc, cache); +}*/ } - - } - -} - diff --git a/physx/source/lowleveldynamics/src/DySolverConstraintsBlock.cpp b/physx/source/lowleveldynamics/src/DySolverConstraintsBlock.cpp index dc1e3a8fd..c92079c25 100644 --- a/physx/source/lowleveldynamics/src/DySolverConstraintsBlock.cpp +++ b/physx/source/lowleveldynamics/src/DySolverConstraintsBlock.cpp @@ -26,7 +26,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "foundation/PxPreprocessor.h" #include "foundation/PxVecMath.h" #include "foundation/PxFPU.h" @@ -42,10 +41,10 @@ #include "foundation/PxAtomic.h" #include "DySolverContact4.h" #include "DySolverConstraint1D4.h" +#include "DyPGS.h" namespace physx { - namespace Dy { @@ -83,19 +82,16 @@ static void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Vec4V angState30 = V4LoadA(&b30.angularState.x); Vec4V angState31 = V4LoadA(&b31.angularState.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V linVel1T0, linVel1T1, linVel1T2, linVel1T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; Vec4V angState1T0, angState1T1, angState1T2, angState1T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2, linVel1T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); PX_TRANSPOSE_44(angState01, angState11, angState21, angState31, angState1T0, angState1T1, angState1T2, angState1T3); - const PxU8* PX_RESTRICT last = desc[0].constraint + getConstraintLength(desc[0]); //hopefully pointer aliasing doesn't bite. @@ -112,10 +108,8 @@ static void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const Vec4V sumInvMass = V4Add(invMassA, invMassB); - while(currPtr < last) { - hdr = reinterpret_cast(currPtr); PX_ASSERT(hdr->type == DY_SC_TYPE_BLOCK_RB_CONTACT); @@ -145,8 +139,7 @@ static void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, { maxImpulses = &vMax; } - - + SolverFrictionSharedData4* PX_RESTRICT fd = reinterpret_cast(currPtr); if(numFrictionConstr) currPtr += sizeof(SolverFrictionSharedData4); @@ -238,7 +231,6 @@ static void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, linVel0T2 = V4MulAdd(_normalT2, accumDeltaF_IM0, linVel0T2); linVel1T2 = V4NegMulSub(_normalT2, accumDeltaF_IM1, linVel1T2); - if(cache.doFriction && numFrictionConstr) { const Vec4V staticFric = hdr->staticFriction; @@ -257,7 +249,6 @@ static void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, PxPrefetchLine(fd->frictionBrokenWritebackByte[2]); } - for(PxU32 i=0;i(currPtr); currPtr += numFrictionConstr * sizeof(SolverContactFrictionBase4); - - + Vec4V accumulatedNormalImpulse = vZero; const Vec4V angD0 = hdr->angDom0; @@ -507,7 +495,6 @@ static void solveContact4_StaticBlock(const PxSolverConstraintDesc* PX_RESTRICT Vec4V accumDeltaF = vZero; - for(PxU32 i=0;ibroken = broken; @@ -716,7 +702,7 @@ static void concludeContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT des } } -void writeBackContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& cache, +static void writeBackContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& cache, const PxSolverBodyData** PX_RESTRICT bd0, const PxSolverBodyData** PX_RESTRICT bd1) { const PxU8* PX_RESTRICT last = desc[0].constraint + getConstraintLength(desc[0]); @@ -732,10 +718,8 @@ void writeBackContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Sol const PxU32 contactSize = type == DY_SC_TYPE_BLOCK_RB_CONTACT ? sizeof(SolverContactBatchPointDynamic4) : sizeof(SolverContactBatchPointBase4); const PxU32 frictionSize = type == DY_SC_TYPE_BLOCK_RB_CONTACT ? sizeof(SolverContactFrictionDynamic4) : sizeof(SolverContactFrictionBase4); - Vec4V normalForce = V4Zero(); - //We'll need this. //const Vec4V vZero = V4Zero(); @@ -775,7 +759,6 @@ void writeBackContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Sol writeBackThresholds[2] = hdr->flags[2] & SolverContactHeader::eHAS_FORCE_THRESHOLDS; writeBackThresholds[3] = hdr->flags[3] & SolverContactHeader::eHAS_FORCE_THRESHOLDS; - for(PxU32 i=0;iangD0; const Vec4V angD1 = header->angD1; - PxU32 maxConstraints = header->count; + const PxU32 maxConstraints = header->count; for(PxU32 a = 0; a < maxConstraints; ++a) { @@ -962,7 +942,6 @@ static void solve1D4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Solve PX_TRANSPOSE_44(angState0T0, angState0T1, angState0T2, angState0T3, angState00, angState10, angState20, angState30); PX_TRANSPOSE_44(angState1T0, angState1T1, angState1T2, angState1T3, angState01, angState11, angState21, angState31); - // Write back V4StoreA(linVel00, &b00.linearVelocity.x); V4StoreA(linVel10, &b10.linearVelocity.x); @@ -983,16 +962,16 @@ static void solve1D4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Solve V4StoreA(angState11, &b11.angularState.x); V4StoreA(angState21, &b21.angularState.x); V4StoreA(angState31, &b31.angularState.x); - } static void conclude1D4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& /*cache*/) { SolverConstraint1DHeader4* header = reinterpret_cast(desc[0].constraint); PxU8* base = desc[0].constraint + sizeof(SolverConstraint1DHeader4); - PxU32 stride = header->type == DY_SC_TYPE_BLOCK_1D ? sizeof(SolverConstraint1DDynamic4) : sizeof(SolverConstraint1DBase4); + const PxU32 stride = header->type == DY_SC_TYPE_BLOCK_1D ? sizeof(SolverConstraint1DDynamic4) : sizeof(SolverConstraint1DBase4); - for(PxU32 i=0; icount; i++) + const PxU32 count = header->count; + for(PxU32 i=0; i(base); c.constant = c.unbiasedConstant; @@ -1001,7 +980,7 @@ static void conclude1D4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, So PX_ASSERT(desc[0].constraint + getConstraintLength(desc[0]) == base); } -void writeBack1D4(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& /*cache*/, +static void writeBack1D4(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& /*cache*/, const PxSolverBodyData** PX_RESTRICT /*bd0*/, const PxSolverBodyData** PX_RESTRICT /*bd1*/) { ConstraintWriteback* writeback0 = reinterpret_cast(desc[0].writeBack); @@ -1019,7 +998,8 @@ void writeBack1D4(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& Vec4V linX(zero), linY(zero), linZ(zero); Vec4V angX(zero), angY(zero), angZ(zero); - for(PxU32 i=0; icount; i++) + const PxU32 count = header->count; + for(PxU32 i=0; i(base); @@ -1096,31 +1076,35 @@ void writeBack1D4(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& } } - -void solveContactPreBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactPreBlock(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContact4_Block(desc, cache); } -void solveContactPreBlock_Static(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactPreBlock_Static(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContact4_StaticBlock(desc, cache); } -void solveContactPreBlock_Conclude(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactPreBlock_Conclude(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContact4_Block(desc, cache); concludeContact4_Block(desc, cache, sizeof(SolverContactBatchPointDynamic4), sizeof(SolverContactFrictionDynamic4)); } -void solveContactPreBlock_ConcludeStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactPreBlock_ConcludeStatic(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContact4_StaticBlock(desc, cache); concludeContact4_Block(desc, cache, sizeof(SolverContactBatchPointBase4), sizeof(SolverContactFrictionBase4)); } -void solveContactPreBlock_WriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactPreBlock_WriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContact4_Block(desc, cache); const PxSolverBodyData* bd0[4] = { &cache.solverBodyArray[desc[0].bodyADataIndex], @@ -1147,8 +1131,9 @@ void solveContactPreBlock_WriteBack(const PxSolverConstraintDesc* PX_RESTRICT de } } -void solveContactPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactPreBlock_WriteBackStatic(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContact4_StaticBlock(desc, cache); const PxSolverBodyData* bd0[4] = { &cache.solverBodyArray[desc[0].bodyADataIndex], &cache.solverBodyArray[desc[1].bodyADataIndex], @@ -1174,21 +1159,22 @@ void solveContactPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTR } } -void solve1D4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solve1D4_Block(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solve1D4_Block(desc, cache); } - -void solve1D4Block_Conclude(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solve1D4Block_Conclude(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solve1D4_Block(desc, cache); conclude1D4_Block(desc, cache); } - -void solve1D4Block_WriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solve1D4Block_WriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solve1D4_Block(desc, cache); const PxSolverBodyData* bd0[4] = { &cache.solverBodyArray[desc[0].bodyADataIndex], @@ -1204,7 +1190,7 @@ void solve1D4Block_WriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, con writeBack1D4(desc, cache, bd0, bd1); } -void writeBack1D4Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void writeBack1D4Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) { const PxSolverBodyData* bd0[4] = { &cache.solverBodyArray[desc[0].bodyADataIndex], &cache.solverBodyArray[desc[1].bodyADataIndex], diff --git a/physx/source/lowleveldynamics/src/DySolverContact.h b/physx/source/lowleveldynamics/src/DySolverContact.h index 266a44bc9..3aa10cfbb 100644 --- a/physx/source/lowleveldynamics/src/DySolverContact.h +++ b/physx/source/lowleveldynamics/src/DySolverContact.h @@ -73,35 +73,33 @@ struct SolverContactHeader //resolves the normal constraint on all links Vec4V normal_minAppliedImpulseForFrictionW; //48 - PxReal invMass1; //52 - PxU32 broken; //56 - PxU8* frictionBrokenWritebackByte; //60 64 + PxU32 broken; //56 + PxU8* frictionBrokenWritebackByte; //60 64 Sc::ShapeInteraction* shapeInteraction; //64 72 #if PX_P64_FAMILY PxU32 pad[2]; //64 80 #endif // PX_X64 - - PX_FORCE_INLINE void setStaticFriction(const FloatV f) {staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W=V4SetX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W,f);} - PX_FORCE_INLINE void setDynamicFriction(const FloatV f) {staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W=V4SetY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W,f);} - PX_FORCE_INLINE void setDominance0(const FloatV f) {staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W=V4SetZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W,f);} - PX_FORCE_INLINE void setDominance1(const FloatV f) {staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W=V4SetW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W,f);} - - PX_FORCE_INLINE FloatV getStaticFriction() const {return V4GetX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - PX_FORCE_INLINE FloatV getDynamicFriction() const {return V4GetY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - PX_FORCE_INLINE FloatV getDominance0() const {return V4GetZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - PX_FORCE_INLINE FloatV getDominance1() const {return V4GetW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - - PX_FORCE_INLINE void setStaticFriction(PxF32 f) {V4WriteX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f);} - PX_FORCE_INLINE void setDynamicFriction(PxF32 f) {V4WriteY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f);} - PX_FORCE_INLINE void setDominance0(PxF32 f) {V4WriteZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f);} - PX_FORCE_INLINE void setDominance1(PxF32 f) {V4WriteW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f);} - - PX_FORCE_INLINE PxF32 getStaticFrictionPxF32() const {return V4ReadX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - PX_FORCE_INLINE PxF32 getDynamicFrictionPxF32() const {return V4ReadY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - PX_FORCE_INLINE PxF32 getDominance0PxF32() const {return V4ReadZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} - PX_FORCE_INLINE PxF32 getDominance1PxF32() const {return V4ReadW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W);} + PX_FORCE_INLINE void setStaticFriction(const FloatV f) { staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W = V4SetX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + PX_FORCE_INLINE void setDynamicFriction(const FloatV f) { staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W = V4SetY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + PX_FORCE_INLINE void setDominance0(const FloatV f) { staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W = V4SetZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + PX_FORCE_INLINE void setDominance1(const FloatV f) { staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W = V4SetW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + + PX_FORCE_INLINE FloatV getStaticFriction() const { return V4GetX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + PX_FORCE_INLINE FloatV getDynamicFriction() const { return V4GetY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + PX_FORCE_INLINE FloatV getDominance0() const { return V4GetZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + PX_FORCE_INLINE FloatV getDominance1() const { return V4GetW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + + PX_FORCE_INLINE void setStaticFriction(PxF32 f) { V4WriteX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + PX_FORCE_INLINE void setDynamicFriction(PxF32 f) { V4WriteY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + PX_FORCE_INLINE void setDominance0(PxF32 f) { V4WriteZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + PX_FORCE_INLINE void setDominance1(PxF32 f) { V4WriteW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W, f); } + + PX_FORCE_INLINE PxF32 getStaticFrictionPxF32() const { return V4ReadX(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + PX_FORCE_INLINE PxF32 getDynamicFrictionPxF32() const { return V4ReadY(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + PX_FORCE_INLINE PxF32 getDominance0PxF32() const { return V4ReadZ(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } + PX_FORCE_INLINE PxF32 getDominance1PxF32() const { return V4ReadW(staticFrictionX_dynamicFrictionY_dominance0Z_dominance1W); } }; #if !PX_P64_FAMILY @@ -123,14 +121,14 @@ struct SolverContactPoint PxF32 impulseMultiplier; PxU32 pad; - PX_FORCE_INLINE FloatV getVelMultiplier() const {return V4GetW(raXn_velMultiplierW);} - PX_FORCE_INLINE FloatV getImpulseMultiplier() const { return FLoad(impulseMultiplier); } + PX_FORCE_INLINE FloatV getVelMultiplier() const { return V4GetW(raXn_velMultiplierW); } + PX_FORCE_INLINE FloatV getImpulseMultiplier() const { return FLoad(impulseMultiplier); } - PX_FORCE_INLINE FloatV getBiasedErr() const {return FLoad(biasedErr);} - PX_FORCE_INLINE FloatV getMaxImpulse() const {return V4GetW(rbXn_maxImpulseW);} + PX_FORCE_INLINE FloatV getBiasedErr() const { return FLoad(biasedErr); } + PX_FORCE_INLINE FloatV getMaxImpulse() const { return V4GetW(rbXn_maxImpulseW); } - PX_FORCE_INLINE Vec3V getRaXn() const {return Vec3V_From_Vec4V(raXn_velMultiplierW);} - PX_FORCE_INLINE Vec3V getRbXn() const {return Vec3V_From_Vec4V(rbXn_maxImpulseW);} + PX_FORCE_INLINE Vec3V getRaXn() const { return Vec3V_From_Vec4V(raXn_velMultiplierW); } + PX_FORCE_INLINE Vec3V getRbXn() const { return Vec3V_From_Vec4V(rbXn_maxImpulseW); } /*PX_FORCE_INLINE void setRaXn(const PxVec3& v) {V4WriteXYZ(raXn_velMultiplierW, v);} PX_FORCE_INLINE void setRbXn(const PxVec3& v) {V4WriteXYZ(rbXn_maxImpulseW, v);} @@ -200,7 +198,6 @@ struct SolverContactFriction PX_FORCE_INLINE PxF32 getAppliedForcePxF32() const {return V4ReadW(normalXYZ_appliedForceW);} PX_FORCE_INLINE PxF32 getVelMultiplierPxF32() const {return V4ReadW(raXnXYZ_velMultiplierW);} PX_FORCE_INLINE PxF32 getBiasPxF32() const {return V4ReadW(rbXnXYZ_biasW);} - }; PX_COMPILE_TIME_ASSERT(sizeof(SolverContactFriction) == 64); diff --git a/physx/source/lowleveldynamics/src/DySolverContact4.h b/physx/source/lowleveldynamics/src/DySolverContact4.h index ad5a7474f..1c79f8ecc 100644 --- a/physx/source/lowleveldynamics/src/DySolverContact4.h +++ b/physx/source/lowleveldynamics/src/DySolverContact4.h @@ -38,11 +38,6 @@ namespace physx { -struct PxcNpWorkUnit; -struct PxSolverBody; -struct PxSolverBodyData; -struct PxSolverConstraintDesc; - namespace Sc { class ShapeInteraction; @@ -51,9 +46,6 @@ namespace Sc namespace Dy { - - - /** \brief Batched SOA contact data. Note, we don't support batching with extended contacts for the simple reason that handling multiple articulations would be complex. */ @@ -89,9 +81,9 @@ struct SolverContactHeader4 Vec4V angDom0; Vec4V angDom1; //Normal is shared between all contacts in the batch. This will save some memory! - Vec4V normalX; - Vec4V normalY; - Vec4V normalZ; + Vec4V normalX; + Vec4V normalY; + Vec4V normalZ; Sc::ShapeInteraction* shapeInteraction[4]; //192 or 208 }; @@ -145,7 +137,6 @@ struct SolverFrictionSharedData4 PX_COMPILE_TIME_ASSERT(sizeof(SolverFrictionSharedData4) == 128); #endif - /** \brief This represents a batch of 4 friction constraints with static rolled into a single structure */ diff --git a/physx/source/lowleveldynamics/src/DySolverControl.cpp b/physx/source/lowleveldynamics/src/DySolverControl.cpp index 58d055ddc..3e00f9726 100644 --- a/physx/source/lowleveldynamics/src/DySolverControl.cpp +++ b/physx/source/lowleveldynamics/src/DySolverControl.cpp @@ -31,8 +31,6 @@ #include "foundation/PxAllocator.h" #include "foundation/PxAtomic.h" #include "foundation/PxIntrinsics.h" -#include -#include #include "DySolverBody.h" #include "DySolverConstraint1D.h" #include "DySolverContact.h" @@ -44,49 +42,44 @@ #include "DySolverContext.h" #include "DyFeatherstoneArticulation.h" - namespace physx { - namespace Dy { - -//----------------------------------- - -void solve1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtContactBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExt1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContact_BStaticBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactPreBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactPreBlock_Static (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solve1D4_Block (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - - -void solve1DConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtContactConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExt1DConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContact_BStaticConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactPreBlock_Conclude (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactPreBlock_ConcludeStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solve1D4Block_Conclude (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - -void solve1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtContactBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExt1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContact_BStaticBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactPreBlock_WriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solve1D4Block_WriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - -void writeBack1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void contactBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void extContactBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void ext1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void contactPreBlock_WriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void writeBack1D4Block (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); +void solve1DBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtContactBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExt1DBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContact_BStaticBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactPreBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactPreBlock_Static (DY_PGS_SOLVE_METHOD_PARAMS); +void solve1D4_Block (DY_PGS_SOLVE_METHOD_PARAMS); + +void solve1DConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtContactConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExt1DConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContact_BStaticConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactPreBlock_Conclude (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactPreBlock_ConcludeStatic(DY_PGS_SOLVE_METHOD_PARAMS); +void solve1D4Block_Conclude (DY_PGS_SOLVE_METHOD_PARAMS); + +void solve1DBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtContactBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExt1DBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContact_BStaticBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactPreBlock_WriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactPreBlock_WriteBackStatic(DY_PGS_SOLVE_METHOD_PARAMS); +void solve1D4Block_WriteBack (DY_PGS_SOLVE_METHOD_PARAMS); + +// PT: not sure what happened, these ones were declared but not actually used +//void writeBack1DBlock (DY_PGS_SOLVE_METHOD_PARAMS); +//void contactBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +//void extContactBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +//void ext1DBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +//void contactPreBlock_WriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +//void writeBack1D4Block (DY_PGS_SOLVE_METHOD_PARAMS); // could move this to PxPreprocessor.h but // no implementation available for MSVC @@ -95,62 +88,49 @@ void writeBack1D4Block (const PxSolverConstraintDesc* PX_RESTRICT desc, const #else #define PX_UNUSED_ATTRIBUTE #endif - -#define DYNAMIC_ARTICULATION_REGISTRATION(x) 0 static SolveBlockMethod gVTableSolveBlock[] PX_UNUSED_ATTRIBUTE = { 0, - solveContactBlock, // DY_SC_TYPE_RB_CONTACT - solve1DBlock, // DY_SC_TYPE_RB_1D - DYNAMIC_ARTICULATION_REGISTRATION(solveExtContactBlock), // DY_SC_TYPE_EXT_CONTACT - DYNAMIC_ARTICULATION_REGISTRATION(solveExt1DBlock), // DY_SC_TYPE_EXT_1D - solveContact_BStaticBlock, // DY_SC_TYPE_STATIC_CONTACT - solveContactBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContactPreBlock, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContactPreBlock_Static, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4_Block, // DY_SC_TYPE_BLOCK_1D, + solveContactBlock, // DY_SC_TYPE_RB_CONTACT + solve1DBlock, // DY_SC_TYPE_RB_1D + solveExtContactBlock, // DY_SC_TYPE_EXT_CONTACT + solveExt1DBlock, // DY_SC_TYPE_EXT_1D + solveContact_BStaticBlock, // DY_SC_TYPE_STATIC_CONTACT + solveContactBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContactPreBlock, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContactPreBlock_Static, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4_Block, // DY_SC_TYPE_BLOCK_1D, }; static SolveWriteBackBlockMethod gVTableSolveWriteBackBlock[] PX_UNUSED_ATTRIBUTE = { 0, - solveContactBlockWriteBack, // DY_SC_TYPE_RB_CONTACT - solve1DBlockWriteBack, // DY_SC_TYPE_RB_1D - DYNAMIC_ARTICULATION_REGISTRATION(solveExtContactBlockWriteBack), // DY_SC_TYPE_EXT_CONTACT - DYNAMIC_ARTICULATION_REGISTRATION(solveExt1DBlockWriteBack), // DY_SC_TYPE_EXT_1D - solveContact_BStaticBlockWriteBack, // DY_SC_TYPE_STATIC_CONTACT - solveContactBlockWriteBack, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContactPreBlock_WriteBack, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContactPreBlock_WriteBackStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4Block_WriteBack, // DY_SC_TYPE_BLOCK_1D, + solveContactBlockWriteBack, // DY_SC_TYPE_RB_CONTACT + solve1DBlockWriteBack, // DY_SC_TYPE_RB_1D + solveExtContactBlockWriteBack, // DY_SC_TYPE_EXT_CONTACT + solveExt1DBlockWriteBack, // DY_SC_TYPE_EXT_1D + solveContact_BStaticBlockWriteBack, // DY_SC_TYPE_STATIC_CONTACT + solveContactBlockWriteBack, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContactPreBlock_WriteBack, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContactPreBlock_WriteBackStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4Block_WriteBack, // DY_SC_TYPE_BLOCK_1D, }; static SolveBlockMethod gVTableSolveConcludeBlock[] PX_UNUSED_ATTRIBUTE = { 0, - solveContactConcludeBlock, // DY_SC_TYPE_RB_CONTACT - solve1DConcludeBlock, // DY_SC_TYPE_RB_1D - DYNAMIC_ARTICULATION_REGISTRATION(solveExtContactConcludeBlock), // DY_SC_TYPE_EXT_CONTACT - DYNAMIC_ARTICULATION_REGISTRATION(solveExt1DConcludeBlock), // DY_SC_TYPE_EXT_1D - solveContact_BStaticConcludeBlock, // DY_SC_TYPE_STATIC_CONTACT - solveContactConcludeBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContactPreBlock_Conclude, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContactPreBlock_ConcludeStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4Block_Conclude, // DY_SC_TYPE_BLOCK_1D, + solveContactConcludeBlock, // DY_SC_TYPE_RB_CONTACT + solve1DConcludeBlock, // DY_SC_TYPE_RB_1D + solveExtContactConcludeBlock, // DY_SC_TYPE_EXT_CONTACT + solveExt1DConcludeBlock, // DY_SC_TYPE_EXT_1D + solveContact_BStaticConcludeBlock, // DY_SC_TYPE_STATIC_CONTACT + solveContactConcludeBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContactPreBlock_Conclude, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContactPreBlock_ConcludeStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4Block_Conclude, // DY_SC_TYPE_BLOCK_1D, }; -void SolverCoreRegisterArticulationFns() -{ - gVTableSolveBlock[DY_SC_TYPE_EXT_CONTACT] = solveExtContactBlock; - gVTableSolveBlock[DY_SC_TYPE_EXT_1D] = solveExt1DBlock; - - gVTableSolveWriteBackBlock[DY_SC_TYPE_EXT_CONTACT] = solveExtContactBlockWriteBack; - gVTableSolveWriteBackBlock[DY_SC_TYPE_EXT_1D] = solveExt1DBlockWriteBack; - gVTableSolveConcludeBlock[DY_SC_TYPE_EXT_CONTACT] = solveExtContactConcludeBlock; - gVTableSolveConcludeBlock[DY_SC_TYPE_EXT_1D] = solveExt1DConcludeBlock; -} - SolveBlockMethod* getSolveBlockTable() { return gVTableSolveBlock; @@ -234,7 +214,7 @@ void SolverCoreGeneral::solveV_Blocks(SolverIslandParams& params) const articulationListStart[j].articulation->solveInternalConstraints(params.dt, params.invDt, cache.Z, cache.deltaV, false, false, 0.f, 0.8f); for (PxU32 i = 0; i < articulationListSize; i++) - ArticulationPImpl::saveVelocity(articulationListStart[i], cache.deltaV); + ArticulationPImpl::saveVelocity(articulationListStart[i].articulation, cache.deltaV); for (PxU32 i = 0; i < velocityIterations; ++i) for (PxU32 j = 0; j < articulationListSize; ++j) @@ -275,7 +255,7 @@ void SolverCoreGeneral::solveV_Blocks(SolverIslandParams& params) const } for (PxU32 i = 0; i < articulationListSize; i++) - ArticulationPImpl::saveVelocity(articulationListStart[i], cache.deltaV); + ArticulationPImpl::saveVelocity(articulationListStart[i].articulation, cache.deltaV); const PxI32 velItersMinOne = (PxI32(velocityIterations)) - 1; @@ -317,7 +297,7 @@ void SolverCoreGeneral::solveV_Blocks(SolverIslandParams& params) const if(cache.mThresholdStreamIndex > 0) { //Write back to global buffer - PxI32 threshIndex = physx::PxAtomicAdd(outThresholdPairs, PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); + PxI32 threshIndex = PxAtomicAdd(outThresholdPairs, PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); for(PxU32 b = 0; b < cache.mThresholdStreamIndex; ++b) { thresholdStream[b + threshIndex] = cache.mThresholdStream[b]; @@ -326,7 +306,7 @@ void SolverCoreGeneral::solveV_Blocks(SolverIslandParams& params) const } } -PxI32 SolverCoreGeneral::solveVParallelAndWriteBack +void SolverCoreGeneral::solveVParallelAndWriteBack (SolverIslandParams& params, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV) const { #if PX_PROFILE_SOLVE_STALLS @@ -363,11 +343,11 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack const PxI32 positionIterations = PxI32(params.positionIterations); const PxI32 velocityIterations = PxI32(params.velocityIterations); - PxI32* constraintIndex = ¶ms.constraintIndex; - PxI32* constraintIndex2 = ¶ms.constraintIndex2; + 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 PxI32* articIndex = ¶ms.articSolveIndex; - PxI32* articIndex2 = ¶ms.articSolveIndex2; + PxI32* articIndexCompleted = ¶ms.articSolveIndexCompleted; PxSolverConstraintDesc* PX_RESTRICT constraintList = params.constraintList; @@ -383,7 +363,7 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack PX_ASSERT(positionIterations >= 1); PxI32 endIndexCount = UnrollCount; - PxI32 index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + PxI32 index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; PxI32 articSolveStart = 0; PxI32 articSolveEnd = 0; @@ -403,12 +383,12 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack SolveBlockMethod* solveTable = i == 0 ? gVTableSolveBlock : gVTableSolveConcludeBlock; for(; a < positionIterations - 1 + i; ++a) { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); // wait for arti solve of previous iteration cache.doFriction = this->frictionEveryIteration ? true : (positionIterations - a) <= 3; for(PxU32 b = 0; b < nbPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for rigid solve of previous partition maxNormalIndex += headersPerPartition[b]; @@ -424,18 +404,18 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if(endIndexCount == 0) { endIndexCount = UnrollCount; - index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - physx::PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } targetConstraintIndex += headersPerPartition[b]; //Increment target constraint index by batch count } - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for all rigid partitions to be done maxArticIndex += articulationListSize; targetArticIndex += articulationListSize; @@ -454,14 +434,15 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if (nbSolved) { - physx::PxAtomicAdd(articIndex2, nbSolved); + PxMemoryBarrier(); + PxAtomicAdd(articIndexCompleted, nbSolved); } const PxI32 remaining = articSolveEnd - articSolveStart; if (remaining == 0) { - articSolveStart = physx::PxAtomicAdd(articIndex, ArticCount) - ArticCount; + articSolveStart = PxAtomicAdd(articIndex, ArticCount) - ArticCount; articSolveEnd = articSolveStart + ArticCount; } } @@ -473,17 +454,17 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack } PxI32* bodyListIndex = ¶ms.bodyListIndex; - PxI32* bodyListIndex2 = ¶ms.bodyListIndex2; + PxI32* bodyListIndexCompleted = ¶ms.bodyListIndexCompleted; PxSolverBody* PX_RESTRICT bodyListStart = params.bodyListStart; Cm::SpatialVector* PX_RESTRICT motionVelocityArray = params.motionVelocityArray; //Save velocity - articulated PxI32 endIndexCount2 = SaveUnrollCount; - PxI32 index2 = physx::PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; + PxI32 index2 = PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); // wait for all articulation solves before saving velocity + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for all rigid partition solves before saving velocity PxI32 nbConcluded = 0; while(index2 < articulationListSize) { @@ -491,11 +472,11 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack endIndexCount2 -= remainder; for(PxI32 b = 0; b < remainder; ++b, ++index2) { - ArticulationPImpl::saveVelocity(articulationListStart[index2], cache.deltaV); + ArticulationPImpl::saveVelocity(articulationListStart[index2].articulation, cache.deltaV); } if(endIndexCount2 == 0) { - index2 = physx::PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; + index2 = PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; endIndexCount2 = SaveUnrollCount; } nbConcluded += remainder; @@ -526,7 +507,7 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack //Branch not required because this is the last time we use this atomic variable //if(index2 < articulationListSizePlusbodyListSize) { - index2 = physx::PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount - articulationListSize; + index2 = PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount - articulationListSize; endIndexCount2 = SaveUnrollCount; } } @@ -534,19 +515,19 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if(nbConcluded) { PxMemoryBarrier(); - physx::PxAtomicAdd(bodyListIndex2, nbConcluded); + PxAtomicAdd(bodyListIndexCompleted, nbConcluded); } } - WAIT_FOR_PROGRESS(bodyListIndex2, (bodyListSize + articulationListSize)); + WAIT_FOR_PROGRESS(bodyListIndexCompleted, (bodyListSize + articulationListSize)); // wait for all velocity saves to be done a = 1; for(; a < params.velocityIterations; ++a) { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); // wait for arti solve of previous iteration for(PxU32 b = 0; b < nbPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for rigid solve of previous partition maxNormalIndex += headersPerPartition[b]; @@ -562,18 +543,18 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if(endIndexCount == 0) { endIndexCount = UnrollCount; - index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - physx::PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } targetConstraintIndex += headersPerPartition[b]; //Increment target constraint index by batch count } - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for all rigid partitions to be done maxArticIndex += articulationListSize; targetArticIndex += articulationListSize; @@ -592,17 +573,17 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if (nbSolved) { - physx::PxAtomicAdd(articIndex2, nbSolved); + PxMemoryBarrier(); + PxAtomicAdd(articIndexCompleted, nbSolved); } const PxI32 remaining = articSolveEnd - articSolveStart; if (remaining == 0) { - articSolveStart = physx::PxAtomicAdd(articIndex, ArticCount) - ArticCount; + articSolveStart = PxAtomicAdd(articIndex, ArticCount) - ArticCount; articSolveEnd = articSolveStart + ArticCount; } - } ++normalIteration; articIndexCounter += articulationListSize; @@ -619,10 +600,10 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack //Last iteration - do writeback as well! cache.writeBackIteration = true; { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); // wait for arti velocity iterations to be done for(PxU32 b = 0; b < nbPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for rigid partition velocity iterations to be done resp. previous partition writeback iteration maxNormalIndex += headersPerPartition[b]; @@ -640,18 +621,18 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if(endIndexCount == 0) { endIndexCount = UnrollCount; - index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - physx::PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } targetConstraintIndex += headersPerPartition[b]; //Increment target constraint index by batch count } { - WAIT_FOR_PROGRESS(constraintIndex2, targetConstraintIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, targetConstraintIndex); // wait for rigid partitions writeback iterations to be done maxArticIndex += articulationListSize; targetArticIndex += articulationListSize; @@ -671,23 +652,30 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack if (nbSolved) { - physx::PxAtomicAdd(articIndex2, nbSolved); + PxMemoryBarrier(); + PxAtomicAdd(articIndexCompleted, nbSolved); } PxI32 remaining = articSolveEnd - articSolveStart; if (remaining == 0) { - articSolveStart = physx::PxAtomicAdd(articIndex, ArticCount) - ArticCount; + articSolveStart = PxAtomicAdd(articIndex, ArticCount) - ArticCount; articSolveEnd = articSolveStart + ArticCount; } } + + articIndexCounter += articulationListSize; // not strictly necessary but better safe than sorry + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); // wait for arti solve+writeback to be done } + // At this point we've awaited the completion all rigid partitions and all articulations + // No more syncing on the outside of this function is required. + if(cache.mThresholdStreamIndex > 0) { //Write back to global buffer - PxI32 threshIndex = physx::PxAtomicAdd(outThresholdPairs, PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); + PxI32 threshIndex = PxAtomicAdd(outThresholdPairs, PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); for(PxU32 b = 0; b < cache.mThresholdStreamIndex; ++b) { thresholdStream[b + threshIndex] = cache.mThresholdStream[b]; @@ -712,8 +700,6 @@ PxI32 SolverCoreGeneral::solveVParallelAndWriteBack stallRatio * 100.f, stallTime/(PxReal)frequency.QuadPart, totalTime/(PxReal)frequency.QuadPart); } #endif - - return normalIteration * batchCount; } void SolverCoreGeneral::writeBackV @@ -738,11 +724,6 @@ void SolverCoreGeneral::writeBackV outThresholdPairs = PxU32(outThreshIndex); } -void solveVBlock(SOLVEV_BLOCK_METHOD_ARGS) -{ - solverCore->solveV_Blocks(params); -} - } } diff --git a/physx/source/lowleveldynamics/src/DySolverControl.h b/physx/source/lowleveldynamics/src/DySolverControl.h index 7172a5af3..cd0d4ccdf 100644 --- a/physx/source/lowleveldynamics/src/DySolverControl.h +++ b/physx/source/lowleveldynamics/src/DySolverControl.h @@ -99,6 +99,7 @@ inline void SolveBlockParallel (PxSolverConstraintDesc* PX_RESTRICT constraintLi const PxI32 endIndex = indA + batchCount; for(PxI32 i = indA; i < endIndex; ++i) { + PX_ASSERT(i < PxI32(iterator.mSize)); const PxConstraintBatchHeader& header = headers[i]; const PxI32 numToGrab = header.stride; @@ -123,10 +124,10 @@ class SolverCoreGeneral : public SolverCore bool frictionEveryIteration; static SolverCoreGeneral* create(bool fricEveryIteration); - // Implements SolverCore + // SolverCore virtual void destroyV(); - virtual PxI32 solveVParallelAndWriteBack + virtual void solveVParallelAndWriteBack (SolverIslandParams& params, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV) const; virtual void solveV_Blocks @@ -136,20 +137,11 @@ class SolverCoreGeneral : public SolverCore (const PxSolverConstraintDesc* PX_RESTRICT constraintList, const PxU32 constraintListSize, PxConstraintBatchHeader* contactConstraintBatches, const PxU32 numBatches, ThresholdStreamElement* PX_RESTRICT thresholdStream, const PxU32 thresholdStreamLength, PxU32& outThresholdPairs, PxSolverBodyData* atomListData, WriteBackBlockMethod writeBackTable[]) const; - -private: - - //~Implements SolverCore + //~SolverCore }; -#define SOLVEV_BLOCK_METHOD_ARGS SolverCore* solverCore, SolverIslandParams& params - -void solveVBlock(SOLVEV_BLOCK_METHOD_ARGS); - SolveBlockMethod* getSolveBlockTable(); - SolveBlockMethod* getSolverConcludeBlockTable(); - SolveWriteBackBlockMethod* getSolveWritebackBlockTable(); } diff --git a/physx/source/lowleveldynamics/src/DySolverControlPF.cpp b/physx/source/lowleveldynamics/src/DySolverControlPF.cpp index 747c49990..3b2086136 100644 --- a/physx/source/lowleveldynamics/src/DySolverControlPF.cpp +++ b/physx/source/lowleveldynamics/src/DySolverControlPF.cpp @@ -30,8 +30,6 @@ #include "foundation/PxAllocator.h" #include "foundation/PxAtomic.h" #include "foundation/PxIntrinsics.h" -#include -#include #include "DySolverBody.h" #include "DySolverConstraint1D.h" #include "DySolverContact.h" @@ -46,66 +44,59 @@ namespace physx { - namespace Dy { -//----------------------------------- - -void solve1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExt1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solve1D4_Block (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - - -void solve1DConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExt1DConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solve1D4Block_Conclude (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - -void solve1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExt1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solve1D4Block_WriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - -void writeBack1DBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void ext1DBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void writeBack1D4Block (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - - -void solveFrictionBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveFriction_BStaticBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtFrictionBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulombBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtContactCoulombBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulomb_BStaticBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - - -void solveContactCoulombConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtContactCoulombConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulomb_BStaticConcludeBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - -void solveContactCoulombBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtContactCoulombBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulomb_BStaticBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveFrictionBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveFriction_BStaticBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveExtFrictionBlockWriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); +void solve1DBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExt1DBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solve1D4_Block (DY_PGS_SOLVE_METHOD_PARAMS); + +void solve1DConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExt1DConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solve1D4Block_Conclude (DY_PGS_SOLVE_METHOD_PARAMS); + +void solve1DBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExt1DBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solve1D4Block_WriteBack (DY_PGS_SOLVE_METHOD_PARAMS); + +void writeBack1DBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void ext1DBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void writeBack1D4Block (DY_PGS_SOLVE_METHOD_PARAMS); + +void solveFrictionBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveFriction_BStaticBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtFrictionBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulombBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtContactCoulombBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulomb_BStaticBlock (DY_PGS_SOLVE_METHOD_PARAMS); + +void solveContactCoulombConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtContactCoulombConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulomb_BStaticConcludeBlock (DY_PGS_SOLVE_METHOD_PARAMS); + +void solveContactCoulombBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtContactCoulombBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulomb_BStaticBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveFrictionBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveFriction_BStaticBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveExtFrictionBlockWriteBack (DY_PGS_SOLVE_METHOD_PARAMS); //Pre-block 1d/2d friction stuff... -void solveContactCoulombPreBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulombPreBlock_Static (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulombPreBlock_Conclude (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulombPreBlock_ConcludeStatic (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulombPreBlock_WriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveContactCoulombPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveFrictionCoulombPreBlock (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); +void solveContactCoulombPreBlock (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulombPreBlock_Static (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulombPreBlock_Conclude (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulombPreBlock_ConcludeStatic (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulombPreBlock_WriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveContactCoulombPreBlock_WriteBackStatic(DY_PGS_SOLVE_METHOD_PARAMS); +void solveFrictionCoulombPreBlock (DY_PGS_SOLVE_METHOD_PARAMS); -void solveFrictionCoulombPreBlock_Static (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveFrictionCoulombPreBlock_Conclude (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); -void solveFrictionCoulombPreBlock_ConcludeStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); +void solveFrictionCoulombPreBlock_Static (DY_PGS_SOLVE_METHOD_PARAMS); +void solveFrictionCoulombPreBlock_Conclude (DY_PGS_SOLVE_METHOD_PARAMS); +void solveFrictionCoulombPreBlock_ConcludeStatic(DY_PGS_SOLVE_METHOD_PARAMS); -void solveFrictionCoulombPreBlock_WriteBack (const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); - -void solveFrictionCoulombPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache); +void solveFrictionCoulombPreBlock_WriteBack (DY_PGS_SOLVE_METHOD_PARAMS); +void solveFrictionCoulombPreBlock_WriteBackStatic(DY_PGS_SOLVE_METHOD_PARAMS); // could move this to PxPreprocessor.h but // no implementation available for MSVC @@ -115,83 +106,63 @@ void solveFrictionCoulombPreBlock_WriteBackStatic(const PxSolverConstraintDesc* #define PX_UNUSED_ATTRIBUTE #endif -#define DYNAMIC_ARTICULATION_REGISTRATION(x) 0 - - static SolveBlockMethod gVTableSolveBlockCoulomb[] PX_UNUSED_ATTRIBUTE = { 0, - solveContactCoulombBlock, // DY_SC_TYPE_RB_CONTACT - solve1DBlock, // DY_SC_TYPE_RB_1D - DYNAMIC_ARTICULATION_REGISTRATION(solveExtContactCoulombBlock), // DY_SC_TYPE_EXT_CONTACT - DYNAMIC_ARTICULATION_REGISTRATION(solveExt1DBlock), // DY_SC_TYPE_EXT_1D - solveContactCoulomb_BStaticBlock, // DY_SC_TYPE_STATIC_CONTACT - solveContactCoulombBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContactCoulombPreBlock, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContactCoulombPreBlock_Static, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4_Block, // DY_SC_TYPE_BLOCK_1D, - solveFrictionBlock, // DY_SC_TYPE_FRICTION_CONSTRAINT - solveFriction_BStaticBlock, // DY_SC_TYPE_STATIC_FRICTION_CONSTRAINT - DYNAMIC_ARTICULATION_REGISTRATION(solveExtFrictionBlock), // DY_SC_TYPE_EXT_FRICTION_CONSTRAINT - solveFrictionCoulombPreBlock, // DY_SC_TYPE_BLOCK_FRICTION - solveFrictionCoulombPreBlock_Static // DY_SC_TYPE_BLOCK_STATIC_FRICTION + solveContactCoulombBlock, // DY_SC_TYPE_RB_CONTACT + solve1DBlock, // DY_SC_TYPE_RB_1D + solveExtContactCoulombBlock, // DY_SC_TYPE_EXT_CONTACT + solveExt1DBlock, // DY_SC_TYPE_EXT_1D + solveContactCoulomb_BStaticBlock, // DY_SC_TYPE_STATIC_CONTACT + solveContactCoulombBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContactCoulombPreBlock, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContactCoulombPreBlock_Static, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4_Block, // DY_SC_TYPE_BLOCK_1D, + solveFrictionBlock, // DY_SC_TYPE_FRICTION + solveFriction_BStaticBlock, // DY_SC_TYPE_STATIC_FRICTION + solveExtFrictionBlock, // DY_SC_TYPE_EXT_FRICTION + solveFrictionCoulombPreBlock, // DY_SC_TYPE_BLOCK_FRICTION + solveFrictionCoulombPreBlock_Static // DY_SC_TYPE_BLOCK_STATIC_FRICTION }; static SolveWriteBackBlockMethod gVTableSolveWriteBackBlockCoulomb[] PX_UNUSED_ATTRIBUTE = { 0, - solveContactCoulombBlockWriteBack, // DY_SC_TYPE_RB_CONTACT - solve1DBlockWriteBack, // DY_SC_TYPE_RB_1D - DYNAMIC_ARTICULATION_REGISTRATION(solveExtContactCoulombBlockWriteBack), // DY_SC_TYPE_EXT_CONTACT - DYNAMIC_ARTICULATION_REGISTRATION(solveExt1DBlockWriteBack), // DY_SC_TYPE_EXT_1D - solveContactCoulomb_BStaticBlockWriteBack, // DY_SC_TYPE_STATIC_CONTACT - solveContactCoulombBlockWriteBack, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContactCoulombPreBlock_WriteBack, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContactCoulombPreBlock_WriteBackStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4Block_WriteBack, // DY_SC_TYPE_BLOCK_1D, - solveFrictionBlockWriteBack, // DY_SC_TYPE_FRICTION_CONSTRAINT - solveFriction_BStaticBlockWriteBack, // DY_SC_TYPE_STATIC_FRICTION_CONSTRAINT - DYNAMIC_ARTICULATION_REGISTRATION(solveExtFrictionBlockWriteBack), // DY_SC_TYPE_EXT_FRICTION_CONSTRAINT - solveFrictionCoulombPreBlock_WriteBack, // DY_SC_TYPE_BLOCK_FRICTION - solveFrictionCoulombPreBlock_WriteBackStatic // DY_SC_TYPE_BLOCK_STATIC_FRICTION + solveContactCoulombBlockWriteBack, // DY_SC_TYPE_RB_CONTACT + solve1DBlockWriteBack, // DY_SC_TYPE_RB_1D + solveExtContactCoulombBlockWriteBack, // DY_SC_TYPE_EXT_CONTACT + solveExt1DBlockWriteBack, // DY_SC_TYPE_EXT_1D + solveContactCoulomb_BStaticBlockWriteBack, // DY_SC_TYPE_STATIC_CONTACT + solveContactCoulombBlockWriteBack, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContactCoulombPreBlock_WriteBack, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContactCoulombPreBlock_WriteBackStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4Block_WriteBack, // DY_SC_TYPE_BLOCK_1D, + solveFrictionBlockWriteBack, // DY_SC_TYPE_FRICTION + solveFriction_BStaticBlockWriteBack, // DY_SC_TYPE_STATIC_FRICTION + solveExtFrictionBlockWriteBack, // DY_SC_TYPE_EXT_FRICTION + solveFrictionCoulombPreBlock_WriteBack, // DY_SC_TYPE_BLOCK_FRICTION + solveFrictionCoulombPreBlock_WriteBackStatic // DY_SC_TYPE_BLOCK_STATIC_FRICTION }; - static SolveBlockMethod gVTableSolveConcludeBlockCoulomb[] PX_UNUSED_ATTRIBUTE = { 0, - solveContactCoulombConcludeBlock, // DY_SC_TYPE_RB_CONTACT - solve1DConcludeBlock, // DY_SC_TYPE_RB_1D - DYNAMIC_ARTICULATION_REGISTRATION(solveExtContactCoulombConcludeBlock), // DY_SC_TYPE_EXT_CONTACT - DYNAMIC_ARTICULATION_REGISTRATION(solveExt1DConcludeBlock), // DY_SC_TYPE_EXT_1D - solveContactCoulomb_BStaticConcludeBlock, // DY_SC_TYPE_STATIC_CONTACT - solveContactCoulombConcludeBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContactCoulombPreBlock_Conclude, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContactCoulombPreBlock_ConcludeStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4Block_Conclude, // DY_SC_TYPE_BLOCK_1D, - solveFrictionBlock, // DY_SC_TYPE_FRICTION_CONSTRAINT - solveFriction_BStaticBlock, // DY_SC_TYPE_STATIC_FRICTION_CONSTRAINT - DYNAMIC_ARTICULATION_REGISTRATION(solveExtFrictionBlock), // DY_SC_TYPE_EXT_FRICTION_CONSTRAINT - solveFrictionCoulombPreBlock_Conclude, // DY_SC_TYPE_BLOCK_FRICTION - solveFrictionCoulombPreBlock_ConcludeStatic // DY_SC_TYPE_BLOCK_STATIC_FRICTION + solveContactCoulombConcludeBlock, // DY_SC_TYPE_RB_CONTACT + solve1DConcludeBlock, // DY_SC_TYPE_RB_1D + solveExtContactCoulombConcludeBlock, // DY_SC_TYPE_EXT_CONTACT + solveExt1DConcludeBlock, // DY_SC_TYPE_EXT_1D + solveContactCoulomb_BStaticConcludeBlock, // DY_SC_TYPE_STATIC_CONTACT + solveContactCoulombConcludeBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContactCoulombPreBlock_Conclude, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContactCoulombPreBlock_ConcludeStatic, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4Block_Conclude, // DY_SC_TYPE_BLOCK_1D, + solveFrictionBlock, // DY_SC_TYPE_FRICTION + solveFriction_BStaticBlock, // DY_SC_TYPE_STATIC_FRICTION + solveExtFrictionBlock, // DY_SC_TYPE_EXT_FRICTION + solveFrictionCoulombPreBlock_Conclude, // DY_SC_TYPE_BLOCK_FRICTION + solveFrictionCoulombPreBlock_ConcludeStatic // DY_SC_TYPE_BLOCK_STATIC_FRICTION }; - -void SolverCoreRegisterArticulationFnsCoulomb() -{ - gVTableSolveBlockCoulomb[DY_SC_TYPE_EXT_CONTACT] = solveExtContactCoulombBlock; - gVTableSolveBlockCoulomb[DY_SC_TYPE_EXT_1D] = solveExt1DBlock; - - gVTableSolveWriteBackBlockCoulomb[DY_SC_TYPE_EXT_CONTACT] = solveExtContactCoulombBlockWriteBack; - gVTableSolveWriteBackBlockCoulomb[DY_SC_TYPE_EXT_1D] = solveExt1DBlockWriteBack; - gVTableSolveConcludeBlockCoulomb[DY_SC_TYPE_EXT_CONTACT] = solveExtContactCoulombConcludeBlock; - gVTableSolveConcludeBlockCoulomb[DY_SC_TYPE_EXT_1D] = solveExt1DConcludeBlock; - - gVTableSolveBlockCoulomb[DY_SC_TYPE_EXT_FRICTION] = solveExtFrictionBlock; - gVTableSolveWriteBackBlockCoulomb[DY_SC_TYPE_EXT_FRICTION] = solveExtFrictionBlockWriteBack; - gVTableSolveConcludeBlockCoulomb[DY_SC_TYPE_EXT_FRICTION] = solveExtFrictionBlock; -} - SolverCoreGeneralPF* SolverCoreGeneralPF::create() { SolverCoreGeneralPF* scg = reinterpret_cast( @@ -257,7 +228,7 @@ void SolverCoreGeneralPF::solveV_Blocks(SolverIslandParams& params) const articulationListStart[j].articulation->solveInternalConstraints(params.dt, params.invDt, cache.Z, cache.deltaV, false, false, 0.f, 0.8f); for (PxU32 i = 0; i < articulationListSize; i++) - ArticulationPImpl::saveVelocity(articulationListStart[i], cache.deltaV); + ArticulationPImpl::saveVelocity(articulationListStart[i].articulation, cache.deltaV); for (PxU32 i = 0; i < velocityIterations; ++i) for (PxU32 j = 0; j < articulationListSize; ++j) @@ -313,7 +284,7 @@ void SolverCoreGeneralPF::solveV_Blocks(SolverIslandParams& params) const } for (PxU32 i = 0; i < articulationListSize; i++) - ArticulationPImpl::saveVelocity(articulationListStart[i], cache.deltaV); + ArticulationPImpl::saveVelocity(articulationListStart[i].articulation, cache.deltaV); const PxU32 velItersMinOne = velocityIterations - 1; @@ -370,7 +341,7 @@ void SolverCoreGeneralPF::solveV_Blocks(SolverIslandParams& params) const if(cache.mThresholdStreamIndex > 0) { //Write back to global buffer - const PxI32 threshIndex = physx::PxAtomicAdd(reinterpret_cast(&outThresholdPairs), PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); + const PxI32 threshIndex = PxAtomicAdd(reinterpret_cast(&outThresholdPairs), PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); for(PxU32 b = 0; b < cache.mThresholdStreamIndex; ++b) { thresholdStream[b + threshIndex] = cache.mThresholdStream[b]; @@ -379,7 +350,7 @@ void SolverCoreGeneralPF::solveV_Blocks(SolverIslandParams& params) const } } -PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params, +void SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV) const { SolverContext cache; @@ -415,12 +386,12 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params PX_ASSERT(positionIterations >= 1); PxI32* constraintIndex = ¶ms.constraintIndex; - PxI32* constraintIndex2 = ¶ms.constraintIndex2; + PxI32* constraintIndexCompleted = ¶ms.constraintIndexCompleted; PxI32* frictionConstraintIndex = ¶ms.frictionConstraintIndex; PxI32 endIndexCount = UnrollCount; - PxI32 index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; - PxI32 frictionIndex = physx::PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; + PxI32 index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + PxI32 frictionIndex = PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; BatchIterator contactIter(params.constraintBatchHeaders, params.numConstraintHeaders); BatchIterator frictionIter(params.frictionConstraintBatches, params.numFrictionConstraintHeaders); @@ -446,7 +417,7 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params PxI32 targetArticIndex = 0; PxI32* articIndex = ¶ms.articSolveIndex; - PxI32* articIndex2 = ¶ms.articSolveIndex2; + PxI32* articIndexCompleted = ¶ms.articSolveIndexCompleted; PxI32 normalIteration = 0; PxI32 frictionIteration = 0; @@ -456,11 +427,11 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params SolveBlockMethod* solveTable = i == 0 ? gVTableSolveBlockCoulomb : gVTableSolveConcludeBlockCoulomb; for(; a < positionIterations - 1 + i; ++a) { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); for(PxU32 b = 0; b < nbPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxNormalIndex += headersPerPartition[b]; maxProgress += headersPerPartition[b]; PxI32 nbSolved = 0; @@ -475,17 +446,17 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(endIndexCount == 0) { endIndexCount = UnrollCount; - index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } } - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxArticIndex += articulationListSize; targetArticIndex += articulationListSize; @@ -504,14 +475,15 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if (nbSolved) { - physx::PxAtomicAdd(articIndex2, nbSolved); + PxMemoryBarrier(); + PxAtomicAdd(articIndexCompleted, nbSolved); } const PxI32 remaining = articSolveEnd - articSolveStart; if (remaining == 0) { - articSolveStart = physx::PxAtomicAdd(articIndex, ArticCount) - ArticCount; + articSolveStart = PxAtomicAdd(articIndex, ArticCount) - ArticCount; articSolveEnd = articSolveStart + ArticCount; } } @@ -520,11 +492,10 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params ++normalIteration; } - - - } + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); + for(PxU32 i = 0; i < 2; ++i) { SolveBlockMethod* solveTable = i == 0 ? gVTableSolveBlockCoulomb : gVTableSolveConcludeBlockCoulomb; @@ -533,7 +504,7 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params { for(PxU32 b = 0; b < nbFrictionPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxProgress += frictionHeadersPerPartition[b]; maxFrictionIndex += frictionHeadersPerPartition[b]; PxI32 nbSolved = 0; @@ -548,34 +519,30 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(frictionEndIndexCount == 0) { frictionEndIndexCount = UnrollCount; - frictionIndex = physx::PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; + frictionIndex = PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } } ++frictionIteration; } } - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); PxI32* bodyListIndex = ¶ms.bodyListIndex; - - + PxI32* bodyListIndexCompleted = ¶ms.bodyListIndexCompleted; PxSolverBody* PX_RESTRICT bodyListStart = params.bodyListStart; Cm::SpatialVector* PX_RESTRICT motionVelocityArray = params.motionVelocityArray; - PxI32* bodyListIndex2 = ¶ms.bodyListIndex2; - PxI32 endIndexCount2 = SaveUnrollCount; - PxI32 index2 = physx::PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; + PxI32 index2 = PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; { PxI32 nbConcluded = 0; while(index2 < articulationListSize) @@ -584,15 +551,14 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params endIndexCount2 -= remainder; for(PxI32 b = 0; b < remainder; ++b, ++index2) { - ArticulationPImpl::saveVelocity(articulationListStart[index2], cache.deltaV); + ArticulationPImpl::saveVelocity(articulationListStart[index2].articulation, cache.deltaV); } nbConcluded += remainder; if(endIndexCount2 == 0) { - index2 = physx::PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; + index2 = PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount; endIndexCount2 = SaveUnrollCount; } - nbConcluded += remainder; } index2 -= articulationListSize; @@ -620,7 +586,7 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params //Branch not required because this is the last time we use this atomic variable //if(index2 < articulationListSizePlusbodyListSize) { - index2 = physx::PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount - articulationListSize; + index2 = PxAtomicAdd(bodyListIndex, SaveUnrollCount) - SaveUnrollCount - articulationListSize; endIndexCount2 = SaveUnrollCount; } } @@ -628,19 +594,19 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(nbConcluded) { PxMemoryBarrier(); - physx::PxAtomicAdd(bodyListIndex2, nbConcluded); + PxAtomicAdd(bodyListIndexCompleted, nbConcluded); } } - WAIT_FOR_PROGRESS(bodyListIndex2, (bodyListSize + articulationListSize)); + WAIT_FOR_PROGRESS(bodyListIndexCompleted, (bodyListSize + articulationListSize)); a = 0; for(; a < velocityIterations-1; ++a) { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); for(PxU32 b = 0; b < nbPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxNormalIndex += headersPerPartition[b]; maxProgress += headersPerPartition[b]; @@ -655,20 +621,20 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(endIndexCount == 0) { endIndexCount = UnrollCount; - index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } } ++normalIteration; for(PxU32 b = 0; b < nbFrictionPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxFrictionIndex += frictionHeadersPerPartition[b]; maxProgress += frictionHeadersPerPartition[b]; @@ -676,8 +642,8 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params while(frictionIndex < maxFrictionIndex) { const PxI32 remainder = PxMin(maxFrictionIndex - frictionIndex, frictionEndIndexCount); - SolveBlockParallel(constraintList, remainder, index, batchCount, cache, contactIter, gVTableSolveBlockCoulomb, - normalIteration); + SolveBlockParallel(frictionConstraintList, remainder, frictionIndex, frictionBatchCount, cache, frictionIter, gVTableSolveBlockCoulomb, + frictionIteration); frictionIndex += remainder; frictionEndIndexCount -= remainder; @@ -685,17 +651,18 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(frictionEndIndexCount == 0) { frictionEndIndexCount = UnrollCount; - frictionIndex = physx::PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; + frictionIndex = PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } } + ++frictionIteration; - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxArticIndex += articulationListSize; targetArticIndex += articulationListSize; @@ -714,20 +681,19 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if (nbSolved) { - physx::PxAtomicAdd(articIndex2, nbSolved); + PxMemoryBarrier(); + PxAtomicAdd(articIndexCompleted, nbSolved); } const PxI32 remaining = articSolveEnd - articSolveStart; if (remaining == 0) { - articSolveStart = physx::PxAtomicAdd(articIndex, ArticCount) - ArticCount; + articSolveStart = PxAtomicAdd(articIndex, ArticCount) - ArticCount; articSolveEnd = articSolveStart + ArticCount; } - } - - ++frictionIteration; + articIndexCounter += articulationListSize; } ThresholdStreamElement* PX_RESTRICT thresholdStream = params.thresholdStream; @@ -738,12 +704,13 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params cache.mSharedOutThresholdPairs = outThresholdPairs; cache.mSharedThresholdStreamLength = thresholdStreamLength; + // last velocity + write-back iteration { - WAIT_FOR_PROGRESS(articIndex2, targetArticIndex); + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); for(PxU32 b = 0; b < nbPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxNormalIndex += headersPerPartition[b]; maxProgress += headersPerPartition[b]; @@ -752,7 +719,7 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params { const PxI32 remainder = PxMin(maxNormalIndex - index, endIndexCount); - SolveBlockParallel(constraintList, remainder, normalIteration * batchCount, batchCount, + SolveBlockParallel(constraintList, remainder, index, batchCount, cache, contactIter, gVTableSolveWriteBackBlockCoulomb, normalIteration); index += remainder; @@ -761,13 +728,13 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(endIndexCount == 0) { endIndexCount = UnrollCount; - index = physx::PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; + index = PxAtomicAdd(constraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } } @@ -779,7 +746,7 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params for(PxU32 b = 0; b < nbFrictionPartitions; ++b) { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxFrictionIndex += frictionHeadersPerPartition[b]; maxProgress += frictionHeadersPerPartition[b]; @@ -797,17 +764,19 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if(frictionEndIndexCount == 0) { frictionEndIndexCount = UnrollCount; - frictionIndex = physx::PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; + frictionIndex = PxAtomicAdd(frictionConstraintIndex, UnrollCount) - UnrollCount; } } if(nbSolved) { PxMemoryBarrier(); - PxAtomicAdd(constraintIndex2, nbSolved); + PxAtomicAdd(constraintIndexCompleted, nbSolved); } } + ++frictionIteration; + { - WAIT_FOR_PROGRESS(constraintIndex2, maxProgress); + WAIT_FOR_PROGRESS(constraintIndexCompleted, maxProgress); maxArticIndex += articulationListSize; targetArticIndex += articulationListSize; @@ -826,24 +795,30 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params if (nbSolved) { - physx::PxAtomicAdd(articIndex2, nbSolved); + PxMemoryBarrier(); + PxAtomicAdd(articIndexCompleted, nbSolved); } PxI32 remaining = articSolveEnd - articSolveStart; if (remaining == 0) { - articSolveStart = physx::PxAtomicAdd(articIndex, ArticCount) - ArticCount; + articSolveStart = PxAtomicAdd(articIndex, ArticCount) - ArticCount; articSolveEnd = articSolveStart + ArticCount; } } + articIndexCounter += articulationListSize; // not strictly necessary but better safe than sorry + WAIT_FOR_PROGRESS(articIndexCompleted, targetArticIndex); } + // At this point we've awaited the completion all rigid partitions and all articulations + // No more syncing on the outside of this function is required. + if(cache.mThresholdStreamIndex > 0) { //Write back to global buffer - PxI32 threshIndex = physx::PxAtomicAdd(outThresholdPairs, PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); + PxI32 threshIndex = PxAtomicAdd(outThresholdPairs, PxI32(cache.mThresholdStreamIndex)) - PxI32(cache.mThresholdStreamIndex); for(PxU32 b = 0; b < cache.mThresholdStreamIndex; ++b) { thresholdStream[b + threshIndex] = cache.mThresholdStream[b]; @@ -851,13 +826,9 @@ PxI32 SolverCoreGeneralPF::solveVParallelAndWriteBack(SolverIslandParams& params cache.mThresholdStreamIndex = 0; } - ++frictionIteration; } - - return normalIteration * batchCount + frictionIteration * frictionBatchCount; } - void SolverCoreGeneralPF::writeBackV (const PxSolverConstraintDesc* PX_RESTRICT constraintList, const PxU32 /*constraintListSize*/, PxConstraintBatchHeader* batchHeaders, const PxU32 numBatches, ThresholdStreamElement* PX_RESTRICT thresholdStream, const PxU32 thresholdStreamLength, PxU32& outThresholdPairs, diff --git a/physx/source/lowleveldynamics/src/DySolverControlPF.h b/physx/source/lowleveldynamics/src/DySolverControlPF.h index 13a04b21b..d3022671f 100644 --- a/physx/source/lowleveldynamics/src/DySolverControlPF.h +++ b/physx/source/lowleveldynamics/src/DySolverControlPF.h @@ -46,7 +46,7 @@ class SolverCoreGeneralPF : public SolverCore // Implements SolverCore virtual void destroyV(); - virtual PxI32 solveVParallelAndWriteBack + virtual void solveVParallelAndWriteBack (SolverIslandParams& params, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV) const; virtual void solveV_Blocks diff --git a/physx/source/lowleveldynamics/src/DySolverCore.h b/physx/source/lowleveldynamics/src/DySolverCore.h index b91ea9f67..6fc740d02 100644 --- a/physx/source/lowleveldynamics/src/DySolverCore.h +++ b/physx/source/lowleveldynamics/src/DySolverCore.h @@ -32,11 +32,10 @@ #include "PxvConfig.h" #include "foundation/PxArray.h" #include "foundation/PxThread.h" - +#include "DyPGS.h" namespace physx { - struct PxSolverBody; struct PxSolverBodyData; struct PxSolverConstraintDesc; @@ -45,23 +44,12 @@ struct PxConstraintBatchHeader; namespace Dy { struct ThresholdStreamElement; - - struct ArticulationSolverDesc; -class Articulation; -struct SolverContext; - -typedef void (*WriteBackMethod)(const PxSolverConstraintDesc& desc, SolverContext& cache, PxSolverBodyData& sbd0, PxSolverBodyData& sbd1); -typedef void (*SolveMethod)(const PxSolverConstraintDesc& desc, SolverContext& cache); -typedef void (*SolveBlockMethod)(const PxSolverConstraintDesc* desc, const PxU32 constraintCount, SolverContext& cache); -typedef void (*SolveWriteBackBlockMethod)(const PxSolverConstraintDesc* desc, const PxU32 constraintCount, SolverContext& cache); -typedef void (*WriteBackBlockMethod)(const PxSolverConstraintDesc* desc, const PxU32 constraintCount, SolverContext& cache); #define PX_PROFILE_SOLVE_STALLS 0 #if PX_PROFILE_SOLVE_STALLS #if PX_WINDOWS -#include - +#include "foundation/windows/PxWindowsInclude.h" PX_FORCE_INLINE PxU64 readTimer() { @@ -75,7 +63,6 @@ PX_FORCE_INLINE PxU64 readTimer() #endif #endif - #define YIELD_THREADS 1 #if YIELD_THREADS @@ -114,7 +101,6 @@ PX_INLINE void WaitForProgressCount(volatile PxI32* pGlobalIndex, const PxI32 ta #endif } - #if PX_PROFILE_SOLVE_STALLS PX_INLINE void WaitForProgressCount(volatile PxI32* pGlobalIndex, const PxI32 targetIndex, PxU64& stallTime) { @@ -150,7 +136,6 @@ PX_INLINE void WaitForProgressCount(volatile PxI32* pGlobalIndex, const PxI32 ta #endif #define WAIT_FOR_PROGRESS_NO_TIMER(pGlobalIndex, targetIndex) if(*pGlobalIndex < targetIndex) WaitForProgressCount(pGlobalIndex, targetIndex) - struct SolverIslandParams { //Default friction model params @@ -174,18 +159,17 @@ struct SolverIslandParams //Shared state progress counters PxI32 constraintIndex; - PxI32 constraintIndex2; + PxI32 constraintIndexCompleted; PxI32 bodyListIndex; - PxI32 bodyListIndex2; + PxI32 bodyListIndexCompleted; PxI32 articSolveIndex; - PxI32 articSolveIndex2; + PxI32 articSolveIndexCompleted; PxI32 bodyIntegrationListIndex; PxI32 numObjectsIntegrated; PxReal dt; PxReal invDt; - //Additional 1d/2d friction model params PxSolverConstraintDesc* PX_RESTRICT frictionConstraintList; @@ -208,10 +192,8 @@ struct SolverIslandParams Cm::SpatialVectorF* deltaV; }; - /*! Interface to constraint solver cores - */ class SolverCore { @@ -224,18 +206,13 @@ class SolverCore the solution forces are saved in a vector. state should not be stored, this function is safe to call from multiple threads. - - Returns the total number of constraints that should be solved across all threads. Used for synchronization outside of this method */ - - virtual PxI32 solveVParallelAndWriteBack + virtual void solveVParallelAndWriteBack (SolverIslandParams& params, Cm::SpatialVectorF* Z, Cm::SpatialVectorF* deltaV) const = 0; - virtual void solveV_Blocks (SolverIslandParams& params) const = 0; - virtual void writeBackV (const PxSolverConstraintDesc* PX_RESTRICT constraintList, const PxU32 constraintListSize, PxConstraintBatchHeader* contactConstraintBatches, const PxU32 numConstraintBatches, ThresholdStreamElement* PX_RESTRICT thresholdStream, const PxU32 thresholdStreamLength, PxU32& outThresholdPairs, diff --git a/physx/source/lowleveldynamics/src/DySolverPFConstraints.cpp b/physx/source/lowleveldynamics/src/DySolverPFConstraints.cpp index d4aa8a8cd..fa49ccbc2 100644 --- a/physx/source/lowleveldynamics/src/DySolverPFConstraints.cpp +++ b/physx/source/lowleveldynamics/src/DySolverPFConstraints.cpp @@ -42,13 +42,14 @@ #include "DyThresholdTable.h" #include "DySolverConstraintsShared.h" #include "DyFeatherstoneArticulation.h" +#include "DyPGS.h" namespace physx { namespace Dy { -void solveContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) +static void solveContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { PxSolverBody& b0 = *desc.bodyA; PxSolverBody& b1 = *desc.bodyB; @@ -98,7 +99,7 @@ void solveContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& /*ca PX_ASSERT(currPtr == last); } -void solveFriction(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) +static void solveFriction(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { PxSolverBody& b0 = *desc.bodyA; PxSolverBody& b1 = *desc.bodyB; @@ -194,7 +195,7 @@ void solveFriction(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) PX_ASSERT(currPtr == last); } -void solveContactCoulomb_BStatic(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) +static void solveContactCoulomb_BStatic(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { PxSolverBody& b0 = *desc.bodyA; @@ -240,7 +241,7 @@ void solveContactCoulomb_BStatic(const PxSolverConstraintDesc& desc, SolverConte PX_ASSERT(currPtr == last); } -void solveFriction_BStatic(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) +static void solveFriction_BStatic(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { PxSolverBody& b0 = *desc.bodyA; @@ -323,7 +324,7 @@ void solveFriction_BStatic(const PxSolverConstraintDesc& desc, SolverContext& /* PX_ASSERT(currPtr == last); } -void concludeContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) +static void concludeContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& /*cache*/) { PxU8* PX_RESTRICT cPtr = desc.constraint; @@ -355,7 +356,7 @@ void concludeContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& / PX_ASSERT(cPtr == last); } -void writeBackContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache, +static void writeBackContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache, PxSolverBodyData& bd0, PxSolverBodyData& bd1) { PxReal normalForce = 0.f; @@ -367,7 +368,6 @@ void writeBackContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& const PxU32 pointStride = firstHeader->type == DY_SC_TYPE_EXT_CONTACT ? sizeof(SolverContactPointExt) : sizeof(SolverContactPoint); - bool hasForceThresholds = false; while(cPtr < last) { @@ -414,55 +414,43 @@ void writeBackContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& } } -void solveFrictionBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveFrictionBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveFriction(desc[a], cache); - } } -void solveFrictionBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveFrictionBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveFriction(desc[a], cache); - } } -void solveFriction_BStaticBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveFriction_BStaticBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveFriction_BStatic(desc[a], cache); - } } -void solveFriction_BStaticConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +/*void solveFriction_BStaticConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveFriction_BStatic(desc[a], cache); - } -} +}*/ -void solveFriction_BStaticBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveFriction_BStaticBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveFriction_BStatic(desc[a], cache); - } } -void solveContactCoulombBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactCoulombBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveContactCoulomb(desc[a], cache); - } } -void solveContactCoulombConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactCoulombConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -471,7 +459,7 @@ void solveContactCoulombConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT } } -void solveContactCoulombBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactCoulombBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -493,15 +481,13 @@ void solveContactCoulombBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT } } -void solveContactCoulomb_BStaticBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactCoulomb_BStaticBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveContactCoulomb_BStatic(desc[a], cache); - } } -void solveContactCoulomb_BStaticConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactCoulomb_BStaticConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -510,7 +496,7 @@ void solveContactCoulomb_BStaticConcludeBlock(const PxSolverConstraintDesc* PX_R } } -void solveContactCoulomb_BStaticBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveContactCoulomb_BStaticBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -533,7 +519,7 @@ void solveContactCoulomb_BStaticBlockWriteBack(const PxSolverConstraintDesc* PX_ } } -void solveExtContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache) +static void solveExtContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache) { //We'll need this. // const FloatV zero = FZero(); @@ -759,45 +745,39 @@ void solveExtFriction(const PxSolverConstraintDesc& desc, SolverContext& cache) PX_ASSERT(currPtr == last); } -void solveExtFrictionBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtFrictionBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveExtFriction(desc[a], cache); - } } -void solveExtFrictionConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +/*void solveExtFrictionConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) { for(PxU32 a = 0; a < constraintCount; ++a) { solveExtFriction(desc[a], cache); } -} +}*/ -void solveExtFrictionBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtFrictionBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveExtFriction(desc[a], cache); - } } -void solveConcludeExtContactCoulomb (const PxSolverConstraintDesc& desc, SolverContext& cache) +/*void solveConcludeExtContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache) { solveExtContactCoulomb(desc, cache); concludeContactCoulomb(desc, cache); -} +}*/ -void solveExtContactCoulombBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtContactCoulombBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) - { solveExtContactCoulomb(desc[a], cache); - } } -void solveExtContactCoulombConcludeBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtContactCoulombConcludeBlock(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -806,7 +786,7 @@ void solveExtContactCoulombConcludeBlock(const PxSolverConstraintDesc* PX_RESTRI } } -void solveExtContactCoulombBlockWriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 constraintCount, SolverContext& cache) +void solveExtContactCoulombBlockWriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { for(PxU32 a = 0; a < constraintCount; ++a) { @@ -832,7 +812,7 @@ void solveExtContactCoulombBlockWriteBack(const PxSolverConstraintDesc* PX_RESTR } } -void solveConcludeContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache) +/*void solveConcludeContactCoulomb(const PxSolverConstraintDesc& desc, SolverContext& cache) { solveContactCoulomb(desc, cache); concludeContactCoulomb(desc, cache); @@ -842,7 +822,7 @@ void solveConcludeContactCoulomb_BStatic(const PxSolverConstraintDesc& desc, Sol { solveContactCoulomb_BStatic(desc, cache); concludeContactCoulomb(desc, cache); -} +}*/ } diff --git a/physx/source/lowleveldynamics/src/DySolverPFConstraintsBlock.cpp b/physx/source/lowleveldynamics/src/DySolverPFConstraintsBlock.cpp index 97ff38f15..601b563f5 100644 --- a/physx/source/lowleveldynamics/src/DySolverPFConstraintsBlock.cpp +++ b/physx/source/lowleveldynamics/src/DySolverPFConstraintsBlock.cpp @@ -26,7 +26,6 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #include "foundation/PxPreprocessor.h" #include "foundation/PxVecMath.h" #include "foundation/PxFPU.h" @@ -40,10 +39,10 @@ #include "DyConstraint.h" #include "foundation/PxAtomic.h" #include "DySolverContact.h" +#include "DyPGS.h" namespace physx { - namespace Dy { @@ -81,21 +80,16 @@ static void solveContactCoulomb4_Block(const PxSolverConstraintDesc* PX_RESTRICT Vec4V angState30 = V4LoadA(&b30.angularState.x); Vec4V angState31 = V4LoadA(&b31.angularState.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V linVel1T0, linVel1T1, linVel1T2, linVel1T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; Vec4V angState1T0, angState1T1, angState1T2, angState1T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2, linVel1T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); PX_TRANSPOSE_44(angState01, angState11, angState21, angState31, angState1T0, angState1T1, angState1T2, angState1T3); - - - //hopefully pointer aliasing doesn't bite. PxU8* PX_RESTRICT currPtr = desc[0].constraint; @@ -105,11 +99,9 @@ static void solveContactCoulomb4_Block(const PxSolverConstraintDesc* PX_RESTRICT //const PxU8* PX_RESTRICT endPtr = desc[0].constraint + getConstraintLength(desc[0]); - //TODO - can I avoid this many tests??? while(currPtr < last) { - SolverContactCoulombHeader4* PX_RESTRICT hdr = reinterpret_cast(currPtr); Vec4V* appliedForceBuffer = reinterpret_cast(currPtr + hdr->frictionOffset + sizeof(SolverFrictionHeader4)); @@ -165,16 +157,13 @@ static void solveContactCoulomb4_Block(const PxSolverConstraintDesc* PX_RESTRICT const Vec4V rbXnT0 = c.rbXnX; const Vec4V rbXnT1 = c.rbXnY; const Vec4V rbXnT2 = c.rbXnZ; - - + const Vec4V normalVel2_tmp2 = V4Mul(raXnT0, angState0T0); const Vec4V normalVel4_tmp2 = V4Mul(rbXnT0, angState1T0); - - + const Vec4V normalVel2_tmp1 = V4MulAdd(raXnT1, angState0T1, normalVel2_tmp2); const Vec4V normalVel4_tmp1 = V4MulAdd(rbXnT1, angState1T1, normalVel4_tmp2); - - + const Vec4V normalVel2 = V4MulAdd(raXnT2, angState0T2, normalVel2_tmp1); const Vec4V normalVel4 = V4MulAdd(rbXnT2, angState1T2, normalVel4_tmp1); @@ -228,7 +217,6 @@ static void solveContactCoulomb4_Block(const PxSolverConstraintDesc* PX_RESTRICT PX_ASSERT(currPtr == last); - //KS - we need to use PX_TRANSPOSE_44 here instead of the 34_43 variants because the W components are being used to //store the bodies' progress counters. @@ -237,7 +225,6 @@ static void solveContactCoulomb4_Block(const PxSolverConstraintDesc* PX_RESTRICT PX_TRANSPOSE_44(angState0T0, angState0T1, angState0T2, angState0T3, angState00, angState10, angState20, angState30); PX_TRANSPOSE_44(angState1T0, angState1T1, angState1T2, angState1T3, angState01, angState11, angState21, angState31); - // Write back V4StoreA(linVel00, &b00.linearVelocity.x); V4StoreA(linVel10, &b10.linearVelocity.x); @@ -260,7 +247,6 @@ static void solveContactCoulomb4_Block(const PxSolverConstraintDesc* PX_RESTRICT V4StoreA(angState31, &b31.angularState.x); } - static void solveContactCoulomb4_StaticBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& /*cache*/) { PxSolverBody& b00 = *desc[0].bodyA; @@ -283,15 +269,12 @@ static void solveContactCoulomb4_StaticBlock(const PxSolverConstraintDesc* PX_RE Vec4V linVel30 = V4LoadA(&b30.linearVelocity.x); Vec4V angState30 = V4LoadA(&b30.angularState.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); - //hopefully pointer aliasing doesn't bite. PxU8* PX_RESTRICT currPtr = desc[0].constraint; @@ -299,11 +282,9 @@ static void solveContactCoulomb4_StaticBlock(const PxSolverConstraintDesc* PX_RE const PxU8* PX_RESTRICT last = desc[0].constraint + firstHeader->frictionOffset; - //TODO - can I avoid this many tests??? while(currPtr < last) { - SolverContactCoulombHeader4* PX_RESTRICT hdr = reinterpret_cast(currPtr); Vec4V* appliedForceBuffer = reinterpret_cast(currPtr + hdr->frictionOffset + sizeof(SolverFrictionHeader4)); @@ -347,8 +328,7 @@ static void solveContactCoulomb4_StaticBlock(const PxSolverConstraintDesc* PX_RE const Vec4V raXnT0 = c.raXnX; const Vec4V raXnT1 = c.raXnY; const Vec4V raXnT2 = c.raXnZ; - - + const Vec4V normalVel2_tmp2 = V4Mul(raXnT0, angState0T0); const Vec4V normalVel2_tmp1 = V4MulAdd(raXnT1, angState0T1, normalVel2_tmp2); @@ -420,7 +400,6 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, PxSolverBody& b30 = *desc[3].bodyA; PxSolverBody& b31 = *desc[3].bodyB; - Vec4V linVel00 = V4LoadA(&b00.linearVelocity.x); Vec4V linVel01 = V4LoadA(&b01.linearVelocity.x); Vec4V angState00 = V4LoadA(&b00.angularState.x); @@ -441,13 +420,11 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Vec4V angState30 = V4LoadA(&b30.angularState.x); Vec4V angState31 = V4LoadA(&b31.angularState.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V linVel1T0, linVel1T1, linVel1T2, linVel1T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; Vec4V angState1T0, angState1T1, angState1T2, angState1T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2, linVel1T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); @@ -456,7 +433,6 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, PxU8* PX_RESTRICT currPtr = desc[0].constraint; PxU8* PX_RESTRICT endPtr = desc[0].constraint + getConstraintLength(desc[0]); - while(currPtr < endPtr) { SolverFrictionHeader4* PX_RESTRICT hdr = reinterpret_cast(currPtr); @@ -497,7 +473,7 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const Vec4V appliedImpulse = appliedImpulses[i>>hdr->frictionPerContact]; - const Vec4V maxFriction = V4Mul(staticFric, appliedImpulse); + const Vec4V maxFriction = V4Mul(staticFric, appliedImpulse); const Vec4V nMaxFriction = V4Neg(maxFriction); @@ -534,7 +510,6 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const Vec4V normalVel3 = V4MulAdd(linVel1T2, normalZ, normalVel3_tmp1); const Vec4V normalVel4 = V4MulAdd(rbXnZ, angState1T2, normalVel4_tmp1); - const Vec4V normalVel_tmp2 = V4Add(normalVel1, normalVel2); const Vec4V normalVel_tmp1 = V4Add(normalVel3, normalVel4); @@ -551,7 +526,6 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const Vec4V deltaAngF0 = V4Mul(angD0, deltaF); const Vec4V deltaAngF1 = V4Mul(angD1, deltaF); - linVel0T0 = V4MulAdd(normalX, deltaLinF0, linVel0T0); linVel1T0 = V4NegMulSub(normalX, deltaLinF1, linVel1T0); angState0T0 = V4MulAdd(raXnX, deltaAngF0, angState0T0); @@ -581,7 +555,6 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, PX_TRANSPOSE_44(angState0T0, angState0T1, angState0T2, angState0T3, angState00, angState10, angState20, angState30); PX_TRANSPOSE_44(angState1T0, angState1T1, angState1T2, angState1T3, angState01, angState11, angState21, angState31); - // Write back // Write back V4StoreA(linVel00, &b00.linearVelocity.x); @@ -603,19 +576,15 @@ static void solveFriction4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, V4StoreA(angState11, &b11.angularState.x); V4StoreA(angState21, &b21.angularState.x); V4StoreA(angState31, &b31.angularState.x); - } - static void solveFriction4_StaticBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext& /*cache*/) { - PxSolverBody& b00 = *desc[0].bodyA; PxSolverBody& b10 = *desc[1].bodyA; PxSolverBody& b20 = *desc[2].bodyA; PxSolverBody& b30 = *desc[3].bodyA; - Vec4V linVel00 = V4LoadA(&b00.linearVelocity.x); Vec4V angState00 = V4LoadA(&b00.angularState.x); @@ -628,18 +597,15 @@ static void solveFriction4_StaticBlock(const PxSolverConstraintDesc* PX_RESTRICT Vec4V linVel30 = V4LoadA(&b30.linearVelocity.x); Vec4V angState30 = V4LoadA(&b30.angularState.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); PxU8* PX_RESTRICT currPtr = desc[0].constraint; PxU8* PX_RESTRICT endPtr = desc[0].constraint + getConstraintLength(desc[0]); - while(currPtr < endPtr) { SolverFrictionHeader4* PX_RESTRICT hdr = reinterpret_cast(currPtr); @@ -676,7 +642,7 @@ static void solveFriction4_StaticBlock(const PxSolverConstraintDesc* PX_RESTRICT const Vec4V appliedImpulse = appliedImpulses[i>>hdr->frictionPerContact]; - const Vec4V maxFriction = V4Mul(staticFric, appliedImpulse); + const Vec4V maxFriction = V4Mul(staticFric, appliedImpulse); const Vec4V nMaxFriction = V4Neg(maxFriction); @@ -787,7 +753,7 @@ static void concludeContactCoulomb4(const PxSolverConstraintDesc* desc, SolverCo PX_ASSERT(cPtr == last); } -void writeBackContactCoulomb4(const PxSolverConstraintDesc* desc, SolverContext& cache, +static void writeBackContactCoulomb4(const PxSolverConstraintDesc* desc, SolverContext& cache, const PxSolverBodyData** PX_RESTRICT bd0, const PxSolverBodyData** PX_RESTRICT bd1) { Vec4V normalForceV = V4Zero(); @@ -805,7 +771,6 @@ void writeBackContactCoulomb4(const PxSolverConstraintDesc* desc, SolverContext bool writeBackThresholds[4] = {false, false, false, false}; - while(cPtr < last) { const SolverContactCoulombHeader4* PX_RESTRICT hdr = reinterpret_cast(cPtr); @@ -820,8 +785,7 @@ void writeBackContactCoulomb4(const PxSolverConstraintDesc* desc, SolverContext PxPrefetchLine(cPtr, 256); PxPrefetchLine(cPtr, 384); - - + for(PxU32 i=0; i(cPtr); @@ -867,30 +831,35 @@ void writeBackContactCoulomb4(const PxSolverConstraintDesc* desc, SolverContext } } -void solveContactCoulombPreBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactCoulombPreBlock(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContactCoulomb4_Block(desc, cache); } -void solveContactCoulombPreBlock_Static(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactCoulombPreBlock_Static(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContactCoulomb4_StaticBlock(desc, cache); } -void solveContactCoulombPreBlock_Conclude(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactCoulombPreBlock_Conclude(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContactCoulomb4_Block(desc, cache); concludeContactCoulomb4(desc, cache); } -void solveContactCoulombPreBlock_ConcludeStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactCoulombPreBlock_ConcludeStatic(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContactCoulomb4_StaticBlock(desc, cache); concludeContactCoulomb4(desc, cache); } -void solveContactCoulombPreBlock_WriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactCoulombPreBlock_WriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContactCoulomb4_Block(desc, cache); const PxSolverBodyData* bd0[4] = { &cache.solverBodyArray[desc[0].bodyADataIndex], @@ -903,8 +872,6 @@ void solveContactCoulombPreBlock_WriteBack(const PxSolverConstraintDesc* PX_REST &cache.solverBodyArray[desc[2].bodyBDataIndex], &cache.solverBodyArray[desc[3].bodyBDataIndex]}; - - writeBackContactCoulomb4(desc, cache, bd0, bd1); if(cache.mThresholdStreamIndex > (cache.mThresholdStreamLength - 4)) @@ -919,8 +886,9 @@ void solveContactCoulombPreBlock_WriteBack(const PxSolverConstraintDesc* PX_REST } } -void solveContactCoulombPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveContactCoulombPreBlock_WriteBackStatic(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveContactCoulomb4_StaticBlock(desc, cache); const PxSolverBodyData* bd0[4] = { &cache.solverBodyArray[desc[0].bodyADataIndex], &cache.solverBodyArray[desc[1].bodyADataIndex], @@ -946,37 +914,42 @@ void solveContactCoulombPreBlock_WriteBackStatic(const PxSolverConstraintDesc* P } } -void solveFrictionCoulombPreBlock(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveFrictionCoulombPreBlock(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveFriction4_Block(desc, cache); } -void solveFrictionCoulombPreBlock_Static(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveFrictionCoulombPreBlock_Static(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveFriction4_StaticBlock(desc, cache); } -void solveFrictionCoulombPreBlock_Conclude(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveFrictionCoulombPreBlock_Conclude(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveFriction4_Block(desc, cache); } -void solveFrictionCoulombPreBlock_ConcludeStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveFrictionCoulombPreBlock_ConcludeStatic(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveFriction4_StaticBlock(desc, cache); } -void solveFrictionCoulombPreBlock_WriteBack(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveFrictionCoulombPreBlock_WriteBack(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveFriction4_Block(desc, cache); } -void solveFrictionCoulombPreBlock_WriteBackStatic(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxU32 /*constraintCount*/, SolverContext& cache) +void solveFrictionCoulombPreBlock_WriteBackStatic(DY_PGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(constraintCount); solveFriction4_StaticBlock(desc, cache); } - } } diff --git a/physx/source/lowleveldynamics/src/DySpatial.h b/physx/source/lowleveldynamics/src/DySpatial.h deleted file mode 100644 index ce628e706..000000000 --- a/physx/source/lowleveldynamics/src/DySpatial.h +++ /dev/null @@ -1,139 +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-2023 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef DY_SPATIAL_H -#define DY_SPATIAL_H - -#include "foundation/PxVec3.h" -#include "foundation/PxTransform.h" -#include "CmSpatialVector.h" - -namespace physx -{ -namespace Dy -{ -// translate a motion resolved at position p to the origin - - -// should have a 'from' frame and a 'to' frame -class SpInertia -{ -public: - SpInertia() {} - - SpInertia(const PxMat33& ll, const PxMat33& la, const PxMat33& aa): mLL(ll), mLA(la), mAA(aa) - { - } - - static SpInertia getZero() - { - return SpInertia(PxMat33(PxZero), PxMat33(PxZero), - PxMat33(PxZero)); - } - - static SpInertia dyad(const Cm::SpatialVector& column, const Cm::SpatialVector& row) - { - return SpInertia(dyad(column.linear, row.linear), - dyad(column.linear, row.angular), - dyad(column.angular, row.angular)); - } - - - static SpInertia inertia(PxReal mass, const PxVec3& inertia) - { - return SpInertia(PxMat33::createDiagonal(PxVec3(mass,mass,mass)), PxMat33(PxZero), - PxMat33::createDiagonal(inertia)); - } - - - SpInertia operator+(const SpInertia& m) const - { - return SpInertia(mLL+m.mLL, mLA+m.mLA, mAA+m.mAA); - } - - SpInertia operator-(const SpInertia& m) const - { - return SpInertia(mLL-m.mLL, mLA-m.mLA, mAA-m.mAA); - } - - SpInertia operator*(PxReal r) const - { - return SpInertia(mLL*r, mLA*r, mAA*r); - } - - void operator+=(const SpInertia& m) - { - mLL+=m.mLL; - mLA+=m.mLA; - mAA+=m.mAA; - } - - void operator-=(const SpInertia& m) - { - mLL-=m.mLL; - mLA-=m.mLA; - mAA-=m.mAA; - } - - - PX_FORCE_INLINE Cm::SpatialVector operator *(const Cm::SpatialVector& v) const - { - return Cm::SpatialVector(mLL*v.linear +mLA*v.angular, - mLA.transformTranspose(v.linear)+mAA*v.angular); - } - - SpInertia operator *(const SpInertia& v) const - { - return SpInertia(mLL*v.mLL + mLA * v.mLA.getTranspose(), - mLL*v.mLA + mLA * v.mAA, - mLA.getTranspose()*v.mLA + mAA * v.mAA); - } - - - bool isFinite() const - { - return true; -// return mLL.isFinite() && mLA.isFinite() && mAA.isFinite(); - } - - PxMat33 mLL, mLA; // linear force from angular motion, linear force from linear motion - PxMat33 mAA; // angular force from angular motion, mAL = mLA.transpose() - -private: - static PxMat33 dyad(PxVec3 col, PxVec3 row) - { - return PxMat33(col*row.x, col*row.y, col*row.z); - } - - -}; - -} -} - -#endif diff --git a/physx/source/simulationcontroller/src/ScConstraintProjectionTree.h b/physx/source/lowleveldynamics/src/DyTGS.h similarity index 54% rename from physx/source/simulationcontroller/src/ScConstraintProjectionTree.h rename to physx/source/lowleveldynamics/src/DyTGS.h index d592c052f..7626052dc 100644 --- a/physx/source/simulationcontroller/src/ScConstraintProjectionTree.h +++ b/physx/source/lowleveldynamics/src/DyTGS.h @@ -26,47 +26,38 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef SC_CONSTRAINT_PROJECTION_TREE_H -#define SC_CONSTRAINT_PROJECTION_TREE_H +#ifndef DY_TGS_H +#define DY_TGS_H -#include "foundation/PxArray.h" -#include "foundation/PxUserAllocated.h" +#include "foundation/PxPreprocessor.h" +#include "foundation/PxSimpleTypes.h" namespace physx { -namespace Sc -{ - struct ConstraintGroupNode; - class ConstraintSim; - class BodySim; - class BodyRank; + struct PxConstraintBatchHeader; + struct PxSolverConstraintDesc; + struct PxTGSSolverBodyTxInertia; - class ConstraintProjectionTree + namespace Dy { - /** - This class serves both the static administration of an articulation and the actual articulation itself. - An Articulation object holds several articulation root nodes which make up a simulation island that - is further connected with lagrange joints. - */ - public: - ConstraintProjectionTree() {} - ~ConstraintProjectionTree() {} - - static void buildProjectionTrees(ConstraintGroupNode& root); - static void purgeProjectionTrees(ConstraintGroupNode& root); - - static void projectPose(ConstraintGroupNode& root, PxArray& projectedBodies); - - private: - static PxU32 projectionTreeBuildStep(ConstraintGroupNode& node, ConstraintSim* cToParent, ConstraintGroupNode** nodeStack); - - static void getConstraintStatus(const ConstraintSim& c, const BodySim* b, BodySim*& otherBody, PxU32& projectToBody, PxU32& projectToOtherBody); - static void rankConstraint(ConstraintSim&, BodyRank&, PxU32& dominanceTracking, PxU32& constraintsToProjectCount); - static void projectPoseForTree(ConstraintGroupNode& node, PxArray& projectedBodies); - }; - -} // namespace Sc - + struct SolverContext; + + // PT: using defines like we did in Gu (GU_OVERLAP_FUNC_PARAMS, etc). Additionally this gives a + // convenient way to find the TGS solver methods, which are scattered in different files and use + // the same function names as other functions (with a different signature). + + #define DY_TGS_SOLVE_METHOD_PARAMS const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, const PxTGSSolverBodyTxInertia* const txInertias, PxReal minPenetration, PxReal elapsedTime, SolverContext& cache + #define DY_TGS_CONCLUDE_METHOD_PARAMS const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, const PxTGSSolverBodyTxInertia* const txInertias, PxReal elapsedTime, SolverContext& cache + #define DY_TGS_WRITEBACK_METHOD_PARAMS const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, SolverContext* cache + + typedef void (*TGSSolveBlockMethod) (DY_TGS_SOLVE_METHOD_PARAMS); + typedef void (*TGSSolveConcludeMethod) (DY_TGS_CONCLUDE_METHOD_PARAMS); + typedef void (*TGSWriteBackMethod) (DY_TGS_WRITEBACK_METHOD_PARAMS); + + extern TGSSolveBlockMethod g_SolveTGSMethods[]; + extern TGSSolveConcludeMethod g_SolveConcludeTGSMethods[]; + extern TGSWriteBackMethod g_WritebackTGSMethods[]; + } } #endif diff --git a/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp b/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp index 67d4dc4ab..127b59b93 100644 --- a/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp +++ b/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp @@ -42,6 +42,7 @@ using namespace Gu; #include "DySolverContext.h" #include "DySolverConstraint1DStep.h" +#include "DyTGS.h" using namespace aos; @@ -49,11 +50,6 @@ namespace physx { namespace Dy { - PX_FORCE_INLINE PxReal safeRecip(const PxReal x) - { - return x > PX_EPS_F32 ? 1.f/x : 0.f; - } - PX_FORCE_INLINE void computeBlockStreamByteSizesStep(const bool useExtContacts, const CorrelationBuffer& c, PxU32& _solverConstraintByteSize, PxU32& _frictionPatchByteSize, PxU32& _numFrictionPatches, PxU32& _axisConstraintCount, PxReal torsionalPatchRadius) @@ -68,7 +64,6 @@ namespace Dy PxU32 numFrictionPatches = 0; PxU32 axisConstraintCount = 0; - for (PxU32 i = 0; i < c.frictionPatchCount; i++) { //Friction patches. @@ -97,7 +92,6 @@ namespace Dy solverConstraintByteSize += useExtContacts ? nbAnchors * sizeof(SolverContactFrictionStepExt) : nbAnchors * sizeof(SolverContactFrictionStep); axisConstraintCount += nbAnchors; - } } } @@ -298,7 +292,6 @@ namespace Dy Cm::SpatialVectorF Z[64]; articulation->getImpulseResponse(b1.mLinkIndex, Z, impulse1.scale(dom1, angDom1), deltaV1); //ArticulationHelper::getImpulseResponse(*b1.mFsData, b1.mLinkIndex, impulse1.scale(dom1, angDom1), deltaV1); - } response += impulse1.dot(deltaV1); } @@ -312,7 +305,6 @@ namespace Dy { Vec3V response; { - if (b0.mLinkIndex == PxSolverConstraintDesc::RIGID_BODY) { deltaV0.linear = V3Scale(impulse0.linear, FMul(FLoad(b0.mData->invMass), dom0)); @@ -339,8 +331,6 @@ namespace Dy return V3SumElems(response); } - - PxReal SolverExtBodyStep::projectVelocity(const PxVec3& linear, const PxVec3& angular) const { if (mLinkIndex == PxSolverConstraintDesc::RIGID_BODY) @@ -358,8 +348,6 @@ namespace Dy } } - - static FloatV constructContactConstraintStep(const Mat33V& sqrtInvInertia0, const Mat33V& sqrtInvInertia1, const FloatVArg invMassNorLenSq0, const FloatVArg invMassNorLenSq1, const FloatVArg angD0, const FloatVArg angD1, const Vec3VArg bodyFrame0p, const Vec3VArg bodyFrame1p, const QuatV& /*bodyFrame0q*/, const QuatV& /*bodyFrame1q*/, @@ -409,7 +397,6 @@ namespace Dy const FloatV unitResponse = FAdd(resp0, resp1); - const FloatV penetration = FSub(separation, restDistance); const BoolV isSeparated = FIsGrtr(penetration, zero); @@ -418,7 +405,6 @@ namespace Dy const BoolV isGreater2 = BAnd(BAnd(FIsGrtr(restitution, zero), FIsGrtr(bounceThreshold, vrel)), FIsGrtr(FNeg(vrel), penetrationInvDt)); - //The following line was replaced by an equivalent to avoid triggering an assert when FAdd sums totalDt to infinity which happens if vrel==0 //const FloatV ratio = FSel(isGreater2, FAdd(totalDt, FDiv(penetration, vrel)), zero); const FloatV ratio = FAdd(totalDt, FSel(isGreater2, FDiv(penetration, vrel), FNeg(totalDt))); @@ -440,7 +426,6 @@ namespace Dy velMultiplier = FMul(x, a); //scaledBias = FSel(isSeparated, FNeg(invStepDt), FDiv(FMul(nrdt, FMul(x, unitResponse)), velMultiplier)); scaledBias = FMul(nrdt, FMul(x, unitResponse)); - } else { @@ -475,10 +460,8 @@ namespace Dy solverContact.maxImpulse = contact.maxImpulse; return penetration; - } - static void setupFinalizeSolverConstraints(Sc::ShapeInteraction* shapeInteraction, const PxContactPoint* buffer, const CorrelationBuffer& c, @@ -507,7 +490,7 @@ namespace Dy const PxReal biasCoefficient, const PxReal solverOffsetSlop) { - bool hasTorsionalFriction = torsionalPatchRadiusF32 > 0.f || minTorsionalPatchRadiusF32 > 0.f; + const bool hasTorsionalFriction = torsionalPatchRadiusF32 > 0.f || minTorsionalPatchRadiusF32 > 0.f; // NOTE II: the friction patches are sparse (some of them have no contact patches, and // therefore did not get written back to the cache) but the patch addresses are dense, @@ -518,12 +501,11 @@ namespace Dy const FloatV ccdMaxSeparation = FLoad(maxCCDSeparation); - PxU8 flags = PxU8(hasForceThreshold ? SolverContactHeaderStep::eHAS_FORCE_THRESHOLDS : 0); + const PxU8 flags = PxU8(hasForceThreshold ? SolverContactHeaderStep::eHAS_FORCE_THRESHOLDS : 0); PxU8* PX_RESTRICT ptr = workspace; - PxU8 type = PxTo8(staticOrKinematicBody ? DY_SC_TYPE_STATIC_CONTACT - : DY_SC_TYPE_RB_CONTACT); + const PxU8 type = PxTo8(staticOrKinematicBody ? DY_SC_TYPE_STATIC_CONTACT : DY_SC_TYPE_RB_CONTACT); const FloatV zero = FZero(); @@ -556,8 +538,6 @@ namespace Dy const QuatV bodyFrame1q = QuatVLoadU(&bodyFrame1.q.x); const Vec3V bodyFrame1p = V3LoadU(bodyFrame1.p); - - PxU32 frictionPatchWritebackAddrIndex = 0; PxPrefetchLine(c.contactID); @@ -568,13 +548,11 @@ namespace Dy //const Vec3V angVel0 = V3LoadU_SafeReadW(b0.angularVelocity); // PT: safe because 'reportThreshold' follows 'initialAngVel' in PxSolverBodyData //const Vec3V angVel1 = V3LoadU_SafeReadW(b1.angularVelocity); // PT: safe because 'reportThreshold' follows 'initialAngVel' in PxSolverBodyData - const Vec3V linVel0 = V3LoadU_SafeReadW(data0.originalLinearVelocity); // PT: safe because 'invMass' follows 'initialLinVel' in PxSolverBodyData const Vec3V linVel1 = V3LoadU_SafeReadW(data1.originalLinearVelocity); // PT: safe because 'invMass' follows 'initialLinVel' in PxSolverBodyData const Vec3V angVel0 = V3LoadU_SafeReadW(data0.originalAngularVelocity); // PT: safe because 'reportThreshold' follows 'initialAngVel' in PxSolverBodyData const Vec3V angVel1 = V3LoadU_SafeReadW(data1.originalAngularVelocity); // PT: safe because 'reportThreshold' follows 'initialAngVel' in PxSolverBodyData - PX_ALIGN(16, const Mat33V sqrtInvInertia0) ( V3LoadU_SafeReadW(txI0.sqrtInvInertia.column0), // PT: safe because 'column1' follows 'column0' in PxMat33 @@ -604,7 +582,6 @@ namespace Dy const PxReal frictionBiasScale = disableStrongFriction ? 0.f : invDtF32 * scale; - for (PxU32 i = 0; i(ptr); ptr += sizeof(SolverContactHeaderStep); - PxPrefetchLine(ptr, 128); PxPrefetchLine(ptr, 256); @@ -705,8 +681,6 @@ namespace Dy if (haveFriction) { - - const Vec3V linVrel = V3Sub(linVel0, linVel1); //const Vec3V normal = Vec3V_From_PxVec3_Aligned(buffer.contacts[c.contactPatches[c.correlationListHeads[i]].start].normal); @@ -730,7 +704,6 @@ namespace Dy const Vec3V t1 = V3Normalize(V3Cross(norCross, t0Cross)); //const VecCrossV t1Cross = V3PrepareCross(t1); - // since we don't even have the body velocities we can't compute the tangent dirs, so // the only thing we can do right now is to write the geometric information (which is the // same for both axis constraints of an anchor) We put ra in the raXn field, rb in the rbXn @@ -745,8 +718,6 @@ namespace Dy //Using the value stored in the work unit guarantees that the main memory address is used on all platforms. PxU8* PX_RESTRICT writeback = frictionDataPtr + frictionPatchWritebackAddrIndex*sizeof(FrictionPatch); - - const FloatV norVel00 = V3Dot(linVel0, t0); const FloatV norVel01 = V3Dot(linVel1, t0); const FloatV norVel10 = V3Dot(linVel0, t1); @@ -781,8 +752,6 @@ namespace Dy const Vec3V error = V3Add(V3Sub(ra, rb), relTr); - - { Vec3V raXn = V3Cross(ra, t0); Vec3V rbXn = V3Cross(rb, t0); @@ -823,7 +792,6 @@ namespace Dy { FloatV targetVel = V3Dot(tvel, t1); - Vec3V raXn = V3Cross(ra, t1); Vec3V rbXn = V3Cross(rb, t1); @@ -846,7 +814,6 @@ namespace Dy if (isKinematic1) targetVel = FAdd(targetVel, FAdd(norVel11, V3Dot(rbXn, angVel1))); - f1->normalXYZ_ErrorW = V4SetW(t1, V3Dot(error, t1)); //f1->raXnXYZ_targetVelW = V4SetW(body0Anchor, targetVel); //f1->rbXnXYZ_biasW = V4SetW(body1Anchor, FZero()); @@ -899,7 +866,6 @@ namespace Dy } } - static FloatV setupExtSolverContactStep(const SolverExtBodyStep& b0, const SolverExtBodyStep& b1, const FloatV& d0, const FloatV& d1, const FloatV& angD0, const FloatV& angD1, const Vec3V& bodyFrame0p, const Vec3V& bodyFrame1p, const Vec3VArg normal, const FloatVArg invDt, const FloatVArg invDtp8, const FloatVArg invStepDt, const FloatVArg totalDt, @@ -922,8 +888,6 @@ namespace Dy Cm::SpatialVectorV deltaV0, deltaV1; - - const FloatV vRelAng = V3SumElems(V3Sub(V3Mul(v0.angular, raXn), V3Mul(v1.angular, rbXn))); const FloatV vRelLin = FSub(norVel0, norVel1); @@ -938,16 +902,16 @@ namespace Dy const Cm::SpatialVectorV resp0 = createImpulseResponseVector(normal, raXn, b0); const Cm::SpatialVectorV resp1 = createImpulseResponseVector(V3Neg(normal), V3Neg(rbXn), b1); - FloatV unitResponse = getImpulseResponse(b0, resp0, deltaV0, d0, angD0, - b1, resp1, deltaV1, d1, angD1, false); - + FloatV unitResponse = getImpulseResponse( + b0, resp0, deltaV0, d0, angD0, + b1, resp1, deltaV1, d1, angD1, + false); const FloatV vrel = FAdd(vRelAng, vRelLin); FloatV scaledBias, velMultiplier; - FloatV recipResponse = FSel(FIsGrtr(unitResponse, FEps()), FRecip(FAdd(unitResponse, cfm)), zero); - + FloatV recipResponse = FSel(FIsGrtr(unitResponse, FZero()), FRecip(FAdd(unitResponse, cfm)), zero); if (FAllGrtr(zero, restitution)) { @@ -960,7 +924,6 @@ namespace Dy velMultiplier = FMul(x, a); //scaledBias = FSel(isSeparated, FNeg(invStepDt), FDiv(FMul(nrdt, FMul(x, unitResponse)), velMultiplier)); scaledBias = FMul(nrdt, FMul(x, unitResponse)); - } else { @@ -972,7 +935,6 @@ namespace Dy const BoolV isGreater2 = BAnd(BAnd(FIsGrtr(restitution, zero), FIsGrtr(bounceThreshold, vrel)), FIsGrtr(FNeg(vrel), penetrationInvDt)); - FloatV targetVelocity = FSel(isGreater2, FMul(FNeg(vrel), restitution), zero); const FloatV cTargetVel = V3Dot(V3LoadA(contact.targetVel), normal); @@ -1048,8 +1010,6 @@ namespace Dy return mArticulation->getLinkVelocity(mLinkIndex); } - - void setupFinalizeExtSolverContactsStep( const PxContactPoint* buffer, const CorrelationBuffer& c, @@ -1162,7 +1122,6 @@ namespace Dy SolverContactHeaderStep* PX_RESTRICT header = reinterpret_cast(ptr); ptr += sizeof(SolverContactHeaderStep); - PxPrefetchLine(ptr + 128); PxPrefetchLine(ptr + 256); PxPrefetchLine(ptr + 384); @@ -1219,7 +1178,6 @@ namespace Dy cfm, v0, v1, offsetSlop, norVel0, norVel1)); maxPenetration = FMin(FLoad(contact.separation), maxPenetration); - } ptr = p; @@ -1319,7 +1277,6 @@ namespace Dy } { - Vec3V raXn = V3Cross(ra, t1Cross); Vec3V rbXn = V3Cross(rb, t1Cross); raXn = V3Sel(V3IsGrtr(offsetSlop, V3Abs(raXn)), V3Zero(), raXn); @@ -1327,7 +1284,6 @@ namespace Dy Cm::SpatialVectorV deltaV0, deltaV1; - const Cm::SpatialVectorV resp0 = createImpulseResponseVector(t1, raXn, b0); const Cm::SpatialVectorV resp1 = createImpulseResponseVector(V3Neg(t1), V3Neg(rbXn), b1); @@ -1388,18 +1344,13 @@ namespace Dy f->linDeltaVB = V3LoadA(deltaV1.linear); f->angDeltaVA = V3LoadA(deltaV0.angular); f->angDeltaVB = V3LoadA(deltaV1.angular); - } - } frictionPatchWritebackAddrIndex++; } } - - - bool createFinalizeSolverContactsStep( PxTGSSolverContactDesc& contactDesc, CorrelationBuffer& c, @@ -1430,7 +1381,6 @@ namespace Dy desc.constraintLengthOver16 = 0; - if (contactDesc.numContacts == 0) { contactDesc.frictionPtr = NULL; @@ -1450,10 +1400,7 @@ namespace Dy #if PX_CHECKED if (overflow) - { - PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, - "Dropping contacts in solver because we exceeded limit of 32 friction patches."); - } + PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, PX_FL, "Dropping contacts in solver because we exceeded limit of 32 friction patches."); #endif growPatches(c, contactDesc.contacts, contactDesc.bodyFrame0, contactDesc.bodyFrame1, 0, frictionOffsetThreshold + contactDesc.restDistance); @@ -1515,8 +1462,7 @@ namespace Dy //Initialise solverConstraint buffer. if (solverConstraint) - { - + { if (useExtContacts) { const SolverExtBodyStep b0(reinterpret_cast(contactDesc.body0), contactDesc.body0TxI, contactDesc.bodyData0, desc.linkIndexA); @@ -1530,7 +1476,6 @@ namespace Dy } else { - const PxTGSSolverBodyVel& b0 = *contactDesc.body0; const PxTGSSolverBodyVel& b1 = *contactDesc.body1; @@ -1550,9 +1495,6 @@ namespace Dy return successfulReserve; } - - - bool createFinalizeSolverContactsStep(PxTGSSolverContactDesc& contactDesc, PxsContactManagerOutput& output, ThreadContext& threadContext, @@ -1604,7 +1546,6 @@ namespace Dy frictionOffsetThreshold, correlationDistance, biasCoefficient, constraintAllocator); } - static FloatV solveDynamicContactsStep(SolverContactPointStep* contacts, const PxU32 nbContactPoints, const Vec3VArg contactNormal, const FloatVArg invMassA, const FloatVArg invMassB, Vec3V& linVel0_, Vec3V& angState0_, Vec3V& linVel1_, Vec3V& angState1_, PxF32* PX_RESTRICT forceBuffer, @@ -1630,7 +1571,6 @@ namespace Dy SolverContactPointStep& c = contacts[i]; PxPrefetchLine(&contacts[i], 128); - const Vec3V raXnI = V3LoadA(c.raXnI); const Vec3V rbXnI = V3LoadA(c.rbXnI); @@ -1689,7 +1629,6 @@ namespace Dy return accumulatedNormalImpulse; } - void solveContact(const PxSolverConstraintDesc& desc, bool doFriction, const PxReal minPenetration, const PxReal elapsedTimeF32) { @@ -1778,7 +1717,6 @@ namespace Dy const FloatV frictionScale = FLoad(f0.frictionScale); - const Vec4V normalXYZ_ErrorW0 = f0.normalXYZ_ErrorW; const Vec4V raXnI_targetVelW0 = f0.raXnI_targetVelW; const Vec4V rbXnI_velMultiplierW0 = f0.rbXnI_velMultiplierW; @@ -1835,8 +1773,6 @@ namespace Dy const Vec3V v11 = V3MulAdd(linVel1, normal1, V3Mul(angState1, rbXnI1)); const FloatV normalVel1 = V3SumElems(V3Sub(v01, v11)); - - // appliedForce -bias * velMultiplier - a hoisted part of the total impulse computation const FloatV tmp10 = FNegScaleSub(FSub(bias0, targetVel0), velMultiplier0, appliedForce0); const FloatV tmp11 = FNegScaleSub(FSub(bias1, targetVel1), velMultiplier1, appliedForce1); @@ -1890,7 +1826,6 @@ namespace Dy const FloatV frictionScale = FLoad(f.frictionScale); - const Vec4V raXnI_targetVelW = f.raXnI_targetVelW; const Vec4V rbXnI_velMultiplierW = f.rbXnI_velMultiplierW; @@ -1941,12 +1876,9 @@ namespace Dy angState1 = V3NegScaleSub(rbXnI, FMul(deltaF, angDom1), angState1); f.setAppliedForce(newAppliedForce); - - } Store_From_BoolV(broken, &hdr->broken); } - } PX_ASSERT(b0.linearVelocity.isFinite()); @@ -1968,9 +1900,8 @@ namespace Dy PX_ASSERT(currPtr == last); } - void writeBackContact(const PxSolverConstraintDesc& desc, SolverContext* cache) + void writeBackContact(const PxSolverConstraintDesc& desc, SolverContext* /*cache*/) { - PX_UNUSED(cache); // PxReal normalForce = 0; PxU8* PX_RESTRICT cPtr = desc.constraint; @@ -2059,15 +1990,12 @@ void setSolverConstantsStep(PxReal& error, PxReal minRowResponse, PxReal erp, PxReal dt, - PxReal totalDt, + PxReal /*totalDt*/, PxReal biasClamp, PxReal recipdt, PxReal recipTotalDt, PxReal velTarget) { - PX_UNUSED(dt); - PX_UNUSED(totalDt); - PX_UNUSED(minRowResponse); PX_ASSERT(PxIsFinite(unitResponse)); PxReal recipResponse = unitResponse <= minRowResponse ? 0 : 1.0f / unitResponse; //PX_ASSERT(recipResponse < 1e5f); @@ -2075,13 +2003,11 @@ void setSolverConstantsStep(PxReal& error, rcpResponse = recipResponse; - - if (c.flags & Px1DConstraintFlag::eSPRING) { - PxReal a = dt * (dt*c.mods.spring.stiffness + c.mods.spring.damping); - PxReal aDamp = dt * dt * (c.mods.spring.damping + c.mods.spring.stiffness); - PxReal b = dt * (c.mods.spring.damping * (c.velocityTarget));// - c.mods.spring.stiffness * geomError); + const PxReal a = dt * (dt*c.mods.spring.stiffness + c.mods.spring.damping); + const PxReal aDamp = dt * dt * (c.mods.spring.damping + c.mods.spring.stiffness); + const PxReal b = dt * (c.mods.spring.damping * (c.velocityTarget));// - c.mods.spring.stiffness * geomError); maxBias = PX_MAX_F32; PxReal errorTerm; @@ -2104,8 +2030,7 @@ void setSolverConstantsStep(PxReal& error, biasScale = errorTerm - xDamp*c.mods.spring.damping*unitResponse*dt; } - error = geomError * errorTerm; - + error = geomError * errorTerm; } else { @@ -2120,8 +2045,7 @@ void setSolverConstantsStep(PxReal& error, maxBias = 0.f; } else - { - + { biasScale = -recipdt*erp;// *recipResponse; if (c.flags & Px1DConstraintFlag::eDRIVE_ROW) { @@ -2141,21 +2065,17 @@ void setSolverConstantsStep(PxReal& error, /*PxReal errorBias = PxClamp(geomError*erp*recipdt, -biasClamp, biasClamp); constant = (c.velocityTarget - errorBias) * recipResponse;*/ - } } targetVel -= velMultiplier * velTarget; } - - PxU32 setupSolverConstraintStep( const PxTGSSolverConstraintPrepDesc& prepDesc, PxConstraintAllocator& allocator, const PxReal dt, const PxReal totalDt, const PxReal invdt, const PxReal invTotalDt, const PxReal lengthScale, const PxReal biasCoefficient) { - if (prepDesc.numRows == 0) { prepDesc.desc->constraint = NULL; @@ -2175,7 +2095,7 @@ PxU32 setupSolverConstraintStep( const bool isKinematic1 = desc.linkIndexB == PxSolverConstraintDesc::RIGID_BODY && desc.tgsBodyB->isKinematic; - PxU32 stride = isExtended ? sizeof(SolverConstraint1DExtStep) : sizeof(SolverConstraint1DStep); + const PxU32 stride = isExtended ? sizeof(SolverConstraint1DExtStep) : sizeof(SolverConstraint1DStep); const PxU32 constraintLength = sizeof(SolverConstraint1DHeaderStep) + stride * prepDesc.numRows; //KS - +16 is for the constraint progress counter, which needs to be the last element in the constraint (so that we @@ -2246,7 +2166,7 @@ PxU32 setupSolverConstraintStep( prepDesc.body0TxI->sqrtInvInertia, prepDesc.body1TxI->sqrtInvInertia, prepDesc.bodyData0->invMass, prepDesc.bodyData1->invMass, prepDesc.invMassScales, isExtended || prepDesc.disablePreprocessing, prepDesc.improvedSlerp); - PxReal erp = 0.5f * biasCoefficient; + const PxReal erp = 0.5f * biasCoefficient; const PxReal recipDt = invdt; @@ -2306,8 +2226,7 @@ PxU32 setupSolverConstraintStep( s.ang0 = PxVec3(0.f); s.ang1 = PxVec3(0.f); s.angularErrorScale = 0.f; - } - + } } else { @@ -2332,9 +2251,7 @@ PxU32 setupSolverConstraintStep( } else unitResponse += cfm; - - - + { vel0 = eb0.projectVelocity(s.lin0, s.ang0); vel1 = eb1.projectVelocity(s.lin1, s.ang1); @@ -2363,10 +2280,6 @@ PxU32 setupSolverConstraintStep( s.recipResponse = recipResponse; - - - - if (c.flags & Px1DConstraintFlag::eOUTPUT_FORCE) s.flags |= DY_SC_FLAG_OUTPUT_FORCE; @@ -2402,21 +2315,16 @@ PxU32 setupSolverConstraintStep( s.flags |= DY_SC_FLAG_ORTHO_TARGET; } - - - constraints += stride; outCount++; } - //KS - we now need to re-set count because we may have skipped degenerate rows when solving articulation constraints. //In this case, the degenerate rows would have produced no force. Skipping them is just an optimization header->count = PxU8(outCount); return prepDesc.numRows; } - PxU32 SetupSolverConstraintStep(SolverConstraintShaderPrepDesc& shaderDesc, PxTGSSolverConstraintPrepDesc& prepDesc, PxConstraintAllocator& allocator, @@ -2483,7 +2391,8 @@ void solveExt1D(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& linVe Vec3V li0 = V3Zero(), li1 = V3Zero(), ai0 = V3Zero(), ai1 = V3Zero(); - for (PxU32 i = 0; icount; ++i, base++) + const PxU32 count = header->count; + for (PxU32 i = 0; icount; ++i, base++) + const PxU32 count = header->count; + for (PxU32 i = 0; itype == DY_SC_TYPE_RB_1D ? sizeof(SolverConstraint1DStep) : sizeof(SolverConstraint1DExtStep); - for (PxU32 i = 0; icount; ++i, base+=stride) + const PxU32 count = header->count; + for (PxU32 i = 0; i(base); PxPrefetchLine(&c + 1); @@ -2910,9 +2817,6 @@ void concludeContact(const PxSolverConstraintDesc& desc) //PX_ASSERT(currPtr == last); } - - - void writeBack1D(const PxSolverConstraintDesc& desc) { ConstraintWriteback* writeback = reinterpret_cast(desc.writeBack); @@ -2920,10 +2824,11 @@ void writeBack1D(const PxSolverConstraintDesc& desc) { SolverConstraint1DHeaderStep* header = reinterpret_cast(desc.constraint); PxU8* base = desc.constraint + sizeof(SolverConstraint1DHeaderStep); - PxU32 stride = header->type == DY_SC_TYPE_EXT_1D ? sizeof(SolverConstraint1DExtStep) : sizeof(SolverConstraint1DStep); + const PxU32 stride = header->type == DY_SC_TYPE_EXT_1D ? sizeof(SolverConstraint1DExtStep) : sizeof(SolverConstraint1DStep); PxVec3 lin(0), ang(0); - for (PxU32 i = 0; icount; i++) + const PxU32 count = header->count; + for (PxU32 i = 0; i(base); if (c->flags & DY_SC_FLAG_OUTPUT_FORCE) @@ -2955,7 +2860,6 @@ static FloatV solveExtContactsStep(SolverContactPointStepExt* contacts, const Px const FloatV& minPen, const FloatV& elapsedTime) { - PX_UNUSED(elapsedTime); const FloatV deltaV = V3Dot(contactNormal, V3Sub(linDeltaA, linDeltaB)); FloatV accumulatedNormalImpulse = FZero(); @@ -2971,6 +2875,8 @@ static FloatV solveExtContactsStep(SolverContactPointStepExt* contacts, const Px const FloatV velMultiplier = FLoad(c.velMultiplier); const FloatV recipResponse = FLoad(c.recipResponse); + //Component of relative velocity at contact point that is along the contact normal. + //n.[(va + wa X ra) - (vb + wb X rb)] Vec3V v = V3MulAdd(linVel0, contactNormal, V3Mul(angVel0, raXn)); v = V3Sub(v, V3MulAdd(linVel1, contactNormal, V3Mul(angVel1, rbXn))); const FloatV normalVel = V3SumElems(v); @@ -3018,11 +2924,13 @@ static FloatV solveExtContactsStep(SolverContactPointStepExt* contacts, const Px return accumulatedNormalImpulse; } -void solveExtContactStep(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec3V& linVel1, Vec3V& angVel0, Vec3V& angVel1, - Vec3V& linDelta0, Vec3V& linDelta1, Vec3V& angDelta0, Vec3V& angDelta1, Vec3V& linImpulse0, Vec3V& linImpulse1, Vec3V& angImpulse0, Vec3V& angImpulse1, - bool doFriction, const PxReal minPenetration, const PxReal elapsedTimeF32) +void solveExtContactStep( +const PxSolverConstraintDesc& desc, +Vec3V& linVel0, Vec3V& linVel1, Vec3V& angVel0, Vec3V& angVel1, +Vec3V& linDelta0, Vec3V& linDelta1, Vec3V& angDelta0, Vec3V& angDelta1, +Vec3V& linImpulse0, Vec3V& linImpulse1, Vec3V& angImpulse0, Vec3V& angImpulse1, +bool /*doFriction*/, const PxReal minPenetration, const PxReal elapsedTimeF32) { - PX_UNUSED(doFriction); const FloatV elapsedTime = FLoad(elapsedTimeF32); const FloatV minPen = FLoad(minPenetration); @@ -3057,9 +2965,13 @@ void solveExtContactStep(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec const Vec3V contactNormal = V3LoadA(hdr->normal); - const FloatV accumulatedNormalImpulse = FMax(solveExtContactsStep(contacts, numNormalConstr, contactNormal, linVel0, angVel0, linVel1, - angVel1, li0, ai0, li1, ai1, linDelta0, linDelta1, angDelta0, angDelta1, FLoad(hdr->maxPenBias), appliedForceBuffer, minPen, elapsedTime), - FLoad(hdr->minNormalForce)); + const FloatV accumulatedNormalImpulse = FMax(solveExtContactsStep( + contacts, numNormalConstr, contactNormal, + linVel0, angVel0, linVel1, angVel1, + li0, ai0, li1, ai1, + linDelta0, linDelta1, angDelta0, angDelta1, + FLoad(hdr->maxPenBias), appliedForceBuffer, minPen, elapsedTime), + FLoad(hdr->minNormalForce)); if (numFrictionConstr) { @@ -3257,9 +3169,7 @@ void solveExtContactStep(const PxSolverConstraintDesc& desc, Vec3V& linVel0, Vec PX_ASSERT(currPtr == last); } - -void solveExtContactStep(const PxSolverConstraintDesc& desc, bool doFriction, const PxReal minPenetration, - const PxReal elapsedTimeF32, SolverContext& cache) +static void solveExtContactStep(const PxSolverConstraintDesc& desc, bool doFriction, PxReal minPenetration, PxReal elapsedTimeF32, SolverContext& cache) { Vec3V linVel0, angVel0, linVel1, angVel1; Vec3V linDelta0, angDelta0, linDelta1, angDelta1; @@ -3328,7 +3238,6 @@ void solveExtContactStep(const PxSolverConstraintDesc& desc, bool doFriction, co Vec3V linImpulse0 = V3Zero(), linImpulse1 = V3Zero(), angImpulse0 = V3Zero(), angImpulse1 = V3Zero(); - solveExtContactStep(desc, linVel0, linVel1, angVel0, angVel1, linDelta0, linDelta1, angDelta0, angDelta1, linImpulse0, linImpulse1, angImpulse0, angImpulse1, doFriction, minPenetration, elapsedTimeF32); @@ -3339,7 +3248,6 @@ void solveExtContactStep(const PxSolverConstraintDesc& desc, bool doFriction, co } else { - if (desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY) { V3StoreA(linVel0, desc.tgsBodyA->linearVelocity); @@ -3362,61 +3270,58 @@ void solveExtContactStep(const PxSolverConstraintDesc& desc, bool doFriction, co } } -void solveContactBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const /*txInertias*/, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& /*cache*/) +void solveContactBlock(DY_TGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(txInertias); + PX_UNUSED(cache); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) - { solveContact(desc[i], true, minPenetration, elapsedTime); - } } -void solve1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal /*minPenetration*/, const PxReal elapsedTime, SolverContext& /*cache*/) +void solve1DBlock(DY_TGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(minPenetration); + PX_UNUSED(cache); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) - { solve1DStep(desc[i], txInertias, elapsedTime); - } } -void solveExtContactBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const /*txInertias*/, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache) +void solveExtContactBlock(DY_TGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(txInertias); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) - { solveExtContactStep(desc[i], true, minPenetration, elapsedTime, cache); - } } -void solveExt1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal /*minPenetration*/, const PxReal elapsedTime, SolverContext& cache) +void solveExt1DBlock(DY_TGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(minPenetration); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) - { solveExt1DStep(desc[i], elapsedTime, cache, txInertias); - } } -void writeBackContact(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, SolverContext* cache) +void writeBackContact(DY_TGS_WRITEBACK_METHOD_PARAMS) { for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) - { writeBackContact(desc[i], cache); - } } -void writeBack1D(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, SolverContext* /*cache*/) +void writeBack1D(DY_TGS_WRITEBACK_METHOD_PARAMS) { + PX_UNUSED(cache); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) - { writeBack1D(desc[i]); - } } -void solveConclude1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& /*cache*/) +void solveConclude1DBlock(DY_TGS_CONCLUDE_METHOD_PARAMS) { + PX_UNUSED(cache); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) { solve1DStep(desc[i], txInertias, elapsedTime); @@ -3424,8 +3329,7 @@ void solveConclude1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverCons } } -void solveConclude1DBlockExt(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache) +void solveConclude1DBlockExt(DY_TGS_CONCLUDE_METHOD_PARAMS) { for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) { @@ -3434,10 +3338,11 @@ void solveConclude1DBlockExt(const PxConstraintBatchHeader& hdr, const PxSolverC } } - -void solveConcludeContactBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const /*txInertias*/, const PxReal elapsedTime, SolverContext& /*cache*/) +void solveConcludeContactBlock(DY_TGS_CONCLUDE_METHOD_PARAMS) { + PX_UNUSED(txInertias); + PX_UNUSED(cache); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) { solveContact(desc[i], true, -PX_MAX_F32, elapsedTime); @@ -3445,9 +3350,10 @@ void solveConcludeContactBlock(const PxConstraintBatchHeader& hdr, const PxSolve } } -void solveConcludeContactExtBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const /*txInertias*/, const PxReal elapsedTime, SolverContext& cache) +void solveConcludeContactExtBlock(DY_TGS_CONCLUDE_METHOD_PARAMS) { + PX_UNUSED(txInertias); + for (PxU32 i = hdr.startIndex, endIdx = hdr.startIndex + hdr.stride; i < endIdx; ++i) { solveExtContactStep(desc[i], true, -PX_MAX_F32, elapsedTime, cache); @@ -3455,6 +3361,5 @@ void solveConcludeContactExtBlock(const PxConstraintBatchHeader& hdr, const PxSo } } - } } diff --git a/physx/source/lowleveldynamics/src/DyTGSContactPrep.h b/physx/source/lowleveldynamics/src/DyTGSContactPrep.h index d1573f2d3..64c8be06f 100644 --- a/physx/source/lowleveldynamics/src/DyTGSContactPrep.h +++ b/physx/source/lowleveldynamics/src/DyTGSContactPrep.h @@ -36,16 +36,8 @@ namespace physx { - - struct PxcNpWorkUnit; - class PxsConstraintBlockManager; - class PxcConstraintBlockStream; struct PxsContactManagerOutput; - class FrictionPatchStreamPair; - struct PxSolverBody; - struct PxSolverBodyData; struct PxSolverConstraintDesc; - class PxsContactManager; namespace Dy { @@ -128,23 +120,7 @@ namespace physx const PxReal correlationDistance, const PxReal biasCoefficient, PxConstraintAllocator& constraintAllocator); - - typedef void(*TGSSolveBlockMethod) (const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - - typedef void (*TGSWriteBackMethod) (const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, SolverContext* cache); - - typedef void (*TGSSolveConcludeMethod) (const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); - - extern TGSSolveBlockMethod g_SolveTGSMethods[]; - - extern TGSWriteBackMethod g_WritebackTGSMethods[]; - - extern TGSSolveConcludeMethod g_SolveConcludeTGSMethods[]; - } - } #endif diff --git a/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp b/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp index 1cd0eb35f..bd06c59b1 100644 --- a/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp +++ b/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp @@ -38,12 +38,12 @@ using namespace Gu; #include "PxsMaterialManager.h" #include "DyContactPrepShared.h" #include "DyConstraintPrep.h" +#include "DyTGS.h" namespace physx { namespace Dy { - inline bool ValidateVec4(const Vec4V v) { PX_ALIGN(16, PxVec4 vF); @@ -83,7 +83,6 @@ namespace Dy rZ = V4Mul(V4MulAdd(qz, dotuv, tempZ), two); } - struct SolverContactHeaderStepBlock { enum @@ -185,16 +184,16 @@ PX_ALIGN_PREFIX(16) struct SolverConstraint1DStep4 { public: - Vec4V lin0[3]; //!< linear velocity projection (body 0) + Vec4V lin0[3]; //!< linear velocity projection (body 0) Vec4V error; //!< constraint error term - must be scaled by biasScale. Can be adjusted at run-time - Vec4V lin1[3]; //!< linear velocity projection (body 1) + Vec4V lin1[3]; //!< linear velocity projection (body 1) Vec4V biasScale; //!< constraint constant bias scale. Constant - Vec4V ang0[3]; //!< angular velocity projection (body 0) + Vec4V ang0[3]; //!< angular velocity projection (body 0) Vec4V velMultiplier; //!< constraint velocity multiplier - Vec4V ang1[3]; //!< angular velocity projection (body 1) + Vec4V ang1[3]; //!< angular velocity projection (body 1) Vec4V velTarget; //!< Scaled target velocity of the constraint drive @@ -203,13 +202,13 @@ struct SolverConstraint1DStep4 Vec4V appliedForce; //!< applied force to correct velocity+bias Vec4V maxBias; - Vec4V angularErrorScale; //Constant + Vec4V angularErrorScale; //Constant PxU32 flags[4]; } PX_ALIGN_SUFFIX(16); static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTRICT descs, CorrelationBuffer& c, - PxU8* PX_RESTRICT workspace, const PxReal invDtF32, const PxReal totalDtF32, const PxReal invTotalDtF32, - const PxReal dtF32, PxReal bounceThresholdF32, const PxReal biasCoefficient, + PxU8* PX_RESTRICT workspace, PxReal invDtF32, PxReal totalDtF32, PxReal invTotalDtF32, + PxReal dtF32, PxReal bounceThresholdF32, PxReal biasCoefficient, const aos::Vec4VArg invMassScale0, const aos::Vec4VArg invInertiaScale0, const aos::Vec4VArg invMassScale1, const aos::Vec4VArg invInertiaScale1) { @@ -227,7 +226,7 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR PxU8(descs[2].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0), PxU8(descs[3].hasForceThresholds ? SolverContactHeader::eHAS_FORCE_THRESHOLDS : 0) }; - bool hasMaxImpulse = descs[0].hasMaxImpulse || descs[1].hasMaxImpulse || descs[2].hasMaxImpulse || descs[3].hasMaxImpulse; + const bool hasMaxImpulse = descs[0].hasMaxImpulse || descs[1].hasMaxImpulse || descs[2].hasMaxImpulse || descs[3].hasMaxImpulse; //The block is dynamic if **any** of the constraints have a non-static body B. This allows us to batch static and non-static constraints but we only get a memory/perf //saving if all 4 are static. This simplifies the constraint partitioning such that it only needs to care about separating contacts and 1D constraints (which it already does) @@ -269,7 +268,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR const Vec4V restDistance = V4LoadXYZW(descs[0].restDistance, descs[1].restDistance, descs[2].restDistance, descs[3].restDistance); - //load up velocities Vec4V linVel00 = V4LoadA(&descs[0].bodyData0->originalLinearVelocity.x); Vec4V linVel10 = V4LoadA(&descs[1].bodyData0->originalLinearVelocity.x); @@ -361,7 +359,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR PX_TRANSPOSE_44_34(invInertia01Y, invInertia11Y, invInertia21Y, invInertia31Y, invInertia1X1, invInertia1Y1, invInertia1Z1); PX_TRANSPOSE_44_34(invInertia01Z, invInertia11Z, invInertia21Z, invInertia31Z, invInertia1X2, invInertia1Y2, invInertia1Z2); - const FloatV invDt = FLoad(invDtF32); const PxReal scale = PxMin(0.8f, biasCoefficient); @@ -390,7 +387,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR Vec4V bodyFrame0pX, bodyFrame0pY, bodyFrame0pZ; PX_TRANSPOSE_44_34(bodyFrame00p4, bodyFrame01p4, bodyFrame02p4, bodyFrame03p4, bodyFrame0pX, bodyFrame0pY, bodyFrame0pZ); - const Vec3V bodyFrame10p = V3LoadU(descs[0].bodyFrame1.p); const Vec3V bodyFrame11p = V3LoadU(descs[1].bodyFrame1.p); const Vec3V bodyFrame12p = V3LoadU(descs[2].bodyFrame1.p); @@ -404,7 +400,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR Vec4V bodyFrame1pX, bodyFrame1pY, bodyFrame1pZ; PX_TRANSPOSE_44_34(bodyFrame10p4, bodyFrame11p4, bodyFrame12p4, bodyFrame13p4, bodyFrame1pX, bodyFrame1pY, bodyFrame1pZ); - const QuatV bodyFrame00q = QuatVLoadU(&descs[0].bodyFrame0.q.x); const QuatV bodyFrame01q = QuatVLoadU(&descs[1].bodyFrame0.q.x); const QuatV bodyFrame02q = QuatVLoadU(&descs[2].bodyFrame0.q.x); @@ -426,7 +421,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR PxU32 frictionIndex0 = 0, frictionIndex1 = 0, frictionIndex2 = 0, frictionIndex3 = 0; //PxU32 contactIndex0 = 0, contactIndex1 = 0, contactIndex2 = 0, contactIndex3 = 0; - //OK, we iterate through all friction patch counts in the constraint patch, building up the constraint list etc. PxU32 maxPatches = PxMax(descs[0].numFrictionPatches, PxMax(descs[1].numFrictionPatches, PxMax(descs[2].numFrictionPatches, descs[3].numFrictionPatches))); @@ -434,7 +428,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR const Vec4V p1 = V4Splat(FLoad(0.0001f)); const Vec4V orthoThreshold = V4Splat(FLoad(0.70710678f)); - PxU32 contact0 = 0, contact1 = 0, contact2 = 0, contact3 = 0; PxU32 patch0 = 0, patch1 = 0, patch2 = 0, patch3 = 0; @@ -451,7 +444,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR hasFinished[2] = i >= descs[2].numFrictionPatches; hasFinished[3] = i >= descs[3].numFrictionPatches; - frictionIndex0 = hasFinished[0] ? frictionIndex0 : descs[0].startFrictionPatchIndex + i; frictionIndex1 = hasFinished[1] ? frictionIndex1 : descs[1].startFrictionPatchIndex + i; frictionIndex2 = hasFinished[2] ? frictionIndex2 : descs[2].startFrictionPatchIndex + i; @@ -479,7 +471,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR SolverContactHeaderStepBlock* PX_RESTRICT header = reinterpret_cast(ptr); ptr += sizeof(SolverContactHeaderStepBlock); - header->flags[0] = flags[0]; header->flags[1] = flags[1]; header->flags[2] = flags[2]; @@ -633,7 +624,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR PX_ASSERT(ValidateVec4(rbY)); PX_ASSERT(ValidateVec4(rbZ)); - //raXn = cross(ra, normal) which = 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); Vec4V raXnX = V4NegMulSub(raZ, normalY, V4Mul(raY, normalZ)); @@ -644,7 +634,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR Vec4V rbXnY = V4NegMulSub(rbX, normalZ, V4Mul(rbZ, normalX)); Vec4V rbXnZ = V4NegMulSub(rbY, normalX, V4Mul(rbX, normalY)); - const Vec4V relAngVel0 = V4MulAdd(raXnZ, angVelT20, V4MulAdd(raXnY, angVelT10, V4Mul(raXnX, angVelT00))); const Vec4V relAngVel1 = V4MulAdd(rbXnZ, angVelT21, V4MulAdd(rbXnY, angVelT11, V4Mul(rbXnX, angVelT01))); @@ -668,16 +657,12 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR delAngVel0Y = V4MulAdd(invInertia0Z1, raXnZ, delAngVel0Y); delAngVel0Z = V4MulAdd(invInertia0Z2, raXnZ, delAngVel0Z); - - - PX_ASSERT(ValidateVec4(delAngVel0X)); PX_ASSERT(ValidateVec4(delAngVel0Y)); PX_ASSERT(ValidateVec4(delAngVel0Z)); const Vec4V dotDelAngVel0 = V4MulAdd(delAngVel0X, delAngVel0X, V4MulAdd(delAngVel0Y, delAngVel0Y, V4Mul(delAngVel0Z, delAngVel0Z))); - Vec4V unitResponse = V4MulAdd(dotDelAngVel0, angDom0, invMass0D0); Vec4V vrel0 = V4Add(norVel0, relAngVel0); Vec4V vrel1 = V4Add(norVel1, relAngVel1); @@ -689,8 +674,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR //The dynamic-only parts - need to if-statement these up. A branch here shouldn't cost us too much if (isDynamic) { - - rbXnX = V4Sel(V4IsGrtr(slop, V4Abs(rbXnX)), zero, rbXnX); rbXnY = V4Sel(V4IsGrtr(slop, V4Abs(rbXnY)), zero, rbXnY); rbXnZ = V4Sel(V4IsGrtr(slop, V4Abs(rbXnZ)), zero, rbXnZ); @@ -724,7 +707,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR solverContact->rbXnI[1] = delAngVel1Y; solverContact->rbXnI[2] = delAngVel1Z; - Vec4V penetration = V4Sub(separation, restDistance); const Vec4V penetrationInvDt = V4Scale(penetration, invTotalDt); @@ -749,10 +731,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR penetration = V4MulAdd(targetVelocity, ratio, penetration); - - - - //Vec4V biasedErr = V4Sel(isGreater2, targetVelocity, scaledBias); //Vec4V biasedErr = V4Add(targetVelocity, scaledBias); @@ -816,7 +794,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR Vec4V maxImpulseScale = V4One(); { - const FrictionPatch& frictionPatch0 = c.frictionPatches[frictionIndex0]; const FrictionPatch& frictionPatch1 = c.frictionPatches[frictionIndex1]; const FrictionPatch& frictionPatch2 = c.frictionPatches[frictionIndex2]; @@ -886,7 +863,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR Vec4V t0Y = V4Sel(bcon2, vrelSubNorVelY, t0FallbackY); Vec4V t0Z = V4Sel(bcon2, vrelSubNorVelZ, t0FallbackZ); - //Now normalize this... const Vec4V recipLen = V4Rsqrt(V4MulAdd(t0Z, t0Z, V4MulAdd(t0Y, t0Y, V4Mul(t0X, t0X)))); @@ -903,7 +879,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR PX_ASSERT((uintptr_t(descs[2].frictionPtr) & 0xF) == 0); PX_ASSERT((uintptr_t(descs[3].frictionPtr) & 0xF) == 0); - PxU8* PX_RESTRICT writeback0 = descs[0].frictionPtr + frictionPatchWritebackAddrIndex0 * sizeof(FrictionPatch); PxU8* PX_RESTRICT writeback1 = descs[1].frictionPtr + frictionPatchWritebackAddrIndex1 * sizeof(FrictionPatch); PxU8* PX_RESTRICT writeback2 = descs[2].frictionPtr + frictionPatchWritebackAddrIndex2 * sizeof(FrictionPatch); @@ -917,7 +892,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR header->frictionBrokenWritebackByte[2] = writeback2; header->frictionBrokenWritebackByte[3] = writeback3; - /*header->frictionNormal[0][0] = t0X; header->frictionNormal[0][1] = t0Y; header->frictionNormal[0][2] = t0Z; @@ -963,7 +937,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR t1Y = V4Mul(maxImpulseScale, t1Y); t1Z = V4Mul(maxImpulseScale, t1Z); - Vec3V body0Anchor0 = V3LoadU(frictionPatch0.body0Anchors[index0]); Vec3V body0Anchor1 = V3LoadU(frictionPatch1.body0Anchors[index1]); Vec3V body0Anchor2 = V3LoadU(frictionPatch2.body0Anchors[index2]); @@ -1020,7 +993,7 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR PxU32 contactIndex2 = c.contactID[frictionIndex2][index2]; PxU32 contactIndex3 = c.contactID[frictionIndex3][index3]; - //Ensure that the ocntact indices are valid + //Ensure that the contact indices are valid PX_ASSERT(contactIndex0 == 0xffff || contactIndex0 < descs[0].numContacts); PX_ASSERT(contactIndex1 == 0xffff || contactIndex1 < descs[1].numContacts); PX_ASSERT(contactIndex2 == 0xffff || contactIndex2 < descs[2].numContacts); @@ -1034,7 +1007,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR Vec4V targetVelX, targetVelY, targetVelZ; PX_TRANSPOSE_44_34(targetVel0, targetVel1, targetVel2, targetVel3, targetVelX, targetVelY, targetVelZ); - { Vec4V raXnX = V4NegMulSub(raZ, t0Y, V4Mul(raY, t0Z)); Vec4V raXnY = V4NegMulSub(raX, t0Z, V4Mul(raZ, t0X)); @@ -1167,7 +1139,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR if (isDynamic) { - Vec4V rbXnX = V4NegMulSub(rbZ, t1Y, V4Mul(rbY, t1Z)); Vec4V rbXnY = V4NegMulSub(rbX, t1Z, V4Mul(rbZ, t1X)); Vec4V rbXnZ = V4NegMulSub(rbY, t1X, V4Mul(rbX, t1Y)); @@ -1193,8 +1164,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR resp = V4Add(resp, resp1); - - const Vec4V tVel1 = V4MulAdd(t1Z, linVelT21, V4MulAdd(t1Y, linVelT11, V4Mul(t1X, linVelT01))); vrel1 = V4MulAdd(rbXnZ, angVelT21, V4MulAdd(rbXnY, angVelT11, V4MulAdd(rbXnX, angVelT01, tVel1))); } @@ -1212,7 +1181,6 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR f1->rbXnI[1] = delAngVel1Y; f1->rbXnI[2] = delAngVel1Z; - const Vec4V velMultiplier = V4Mul(maxImpulseScale, V4Sel(V4IsGrtr(resp, zero), V4Div(p84, resp), zero)); Vec4V error = V4MulAdd(t1Z, errorZ, V4MulAdd(t1Y, errorY, V4Mul(t1X, errorX))); @@ -1244,9 +1212,7 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR } } - - -PX_FORCE_INLINE void computeBlockStreamFrictionByteSizes(const CorrelationBuffer& c, +static PX_FORCE_INLINE void computeBlockStreamFrictionByteSizes(const CorrelationBuffer& c, PxU32& _frictionPatchByteSize, PxU32& _numFrictionPatches, PxU32 frictionPatchStartIndex, PxU32 frictionPatchEndIndex) { @@ -1268,12 +1234,10 @@ PX_FORCE_INLINE void computeBlockStreamFrictionByteSizes(const CorrelationBuffer PX_ASSERT(0 == (_frictionPatchByteSize & 0x0f)); } - static bool reserveFrictionBlockStreams(const CorrelationBuffer& c, PxConstraintAllocator& constraintAllocator, PxU32 frictionPatchStartIndex, PxU32 frictionPatchEndIndex, FrictionPatch*& _frictionPatches, PxU32& numFrictionPatches) { - //From frictionPatchStream we just need to reserve a single buffer. PxU32 frictionPatchByteSize = 0; //Compute the sizes of all the buffers. @@ -1312,7 +1276,7 @@ static bool reserveFrictionBlockStreams(const CorrelationBuffer& c, PxConstraint //The persistent friction patch correlation/allocation will already have happenned as this is per-pair. //This function just computes the size of the combined solve data. -void computeBlockStreamByteSizes4(PxTGSSolverContactDesc* descs, +static void computeBlockStreamByteSizes4(PxTGSSolverContactDesc* descs, PxU32& _solverConstraintByteSize, PxU32* _axisConstraintCount, const CorrelationBuffer& c) { @@ -1362,7 +1326,6 @@ void computeBlockStreamByteSizes4(PxTGSSolverContactDesc* descs, maxFrictionPatches++; } - PxU32 totalContacts = 0, totalFriction = 0; for (PxU32 a = 0; a < maxPatches; ++a) { @@ -1380,7 +1343,6 @@ void computeBlockStreamByteSizes4(PxTGSSolverContactDesc* descs, hasDynamicBody = hasDynamicBody || ((descs[a].bodyState1 == PxSolverContactDesc::eDYNAMIC_BODY)); } - const bool isStatic = !hasDynamicBody;*/ const PxU32 headerSize = sizeof(SolverContactHeaderStepBlock) * maxPatches; @@ -1456,8 +1418,6 @@ static SolverConstraintPrepState::Enum reserveBlockStreams4(PxTGSSolverContactDe return ((0 == constraintBlockByteSize || constraintBlock)) ? SolverConstraintPrepState::eSUCCESS : SolverConstraintPrepState::eOUT_OF_MEMORY; } - - SolverConstraintPrepState::Enum createFinalizeSolverContacts4Step( Dy::CorrelationBuffer& c, PxTGSSolverContactDesc* blockDescs, @@ -1491,7 +1451,7 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Step( blockDesc.startFrictionPatchIndex = c.frictionPatchCount; if (!(blockDesc.disableStrongFriction)) { - bool valid = getFrictionPatches(c, blockDesc.frictionPtr, blockDesc.frictionCount, + const bool valid = getFrictionPatches(c, blockDesc.frictionPtr, blockDesc.frictionCount, blockDesc.bodyFrame0, blockDesc.bodyFrame1, correlationDistance); if (!valid) return SolverConstraintPrepState::eUNBATCHABLE; @@ -1502,7 +1462,7 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Step( return SolverConstraintPrepState::eUNBATCHABLE; blockDesc.numContactPatches = PxU16(c.contactPatchCount - blockDesc.startContactPatchIndex); - bool overflow = correlatePatches(c, blockDesc.contacts, blockDesc.bodyFrame0, blockDesc.bodyFrame1, PXC_SAME_NORMAL, + const bool overflow = correlatePatches(c, blockDesc.contacts, blockDesc.bodyFrame0, blockDesc.bodyFrame1, PXC_SAME_NORMAL, blockDesc.startContactPatchIndex, blockDesc.startFrictionPatchIndex); if (overflow) @@ -1592,7 +1552,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Step( } } - blockDesc.axisConstraintCount += PxTo16(axisConstraintCount[a]); desc.constraint = solverConstraint; @@ -1629,7 +1588,6 @@ SolverConstraintPrepState::Enum createFinalizeSolverContacts4Step( const PxReal biasCoefficient, PxConstraintAllocator& constraintAllocator) { - for (PxU32 a = 0; a < 4; ++a) { blockDescs[a].desc->constraintLengthOver16 = 0; @@ -1720,57 +1678,52 @@ void setSolverConstantsStep(PxReal& error, PxReal recipTotalDt, PxReal velTarget); -namespace +static void setConstants(PxReal& error, PxReal& biasScale, PxReal& targetVel, PxReal& maxBias, PxReal& velMultiplier, + PxReal& rcpResponse, const Px1DConstraint& c, PxReal unitResponse, PxReal minRowResponse, PxReal dt, PxReal totalDt, + PxReal recipdt, PxReal recipTotalDt, bool finished, + PxReal lengthScale, PxReal nv, PxReal nv0, PxReal nv1, bool isKinematic0, bool isKinematic1, PxReal erp) { - void setConstants(PxReal& error, PxReal& biasScale, PxReal& targetVel, PxReal& maxBias, PxReal& velMultiplier, - PxReal& rcpResponse, const Px1DConstraint& c, PxReal unitResponse, PxReal minRowResponse, PxReal dt, PxReal totalDt, - PxReal recipdt, PxReal recipTotalDt, const bool finished, - const PxReal lengthScale, const PxReal nv, const PxReal nv0, const PxReal nv1, const bool isKinematic0, const bool isKinematic1, - const PxReal erp) + if (finished) { - PX_UNUSED(dt); - if (finished) - { - error = 0.f; - biasScale = 0.f; - maxBias = 0.f; - velMultiplier = 0.f; - rcpResponse = 0.f; - targetVel = 0.f; - return; - } + error = 0.f; + biasScale = 0.f; + maxBias = 0.f; + velMultiplier = 0.f; + rcpResponse = 0.f; + targetVel = 0.f; + return; + } - //PxReal biasClamp = c.flags & Px1DConstraintFlag::eANGULAR_CONSTRAINT ? 50.f : 200.f*lengthScale; - PxReal biasClamp = c.flags & Px1DConstraintFlag::eANGULAR_CONSTRAINT ? 100.f : 1000.f*lengthScale; + //PxReal biasClamp = c.flags & Px1DConstraintFlag::eANGULAR_CONSTRAINT ? 50.f : 200.f*lengthScale; + PxReal biasClamp = c.flags & Px1DConstraintFlag::eANGULAR_CONSTRAINT ? 100.f : 1000.f*lengthScale; - PxReal vt = 0.f; - if (isKinematic0) - vt -= nv0; - if (isKinematic1) - vt += nv1; + PxReal vt = 0.f; + if (isKinematic0) + vt -= nv0; + if (isKinematic1) + vt += nv1; - setSolverConstantsStep(error, biasScale, targetVel, maxBias, velMultiplier, rcpResponse, c, nv, unitResponse, - minRowResponse, erp, dt, totalDt, biasClamp, recipdt, recipTotalDt, vt); - } + setSolverConstantsStep(error, biasScale, targetVel, maxBias, velMultiplier, rcpResponse, c, nv, unitResponse, + minRowResponse, erp, dt, totalDt, biasClamp, recipdt, recipTotalDt, vt); +} - void setOrthoData(const PxReal& ang0X, const PxReal& ang0Y, const PxReal& ang0Z, const PxReal& ang1X, const PxReal& ang1Y, const PxReal& ang1Z, - const PxReal& recipResponse, const PxReal& error, PxReal& orthoAng0X, PxReal& orthoAng0Y, PxReal& orthoAng0Z, PxReal& orthoAng1X, PxReal& orthoAng1Y, PxReal& orthoAng1Z, - PxReal& orthoRecipResponse, PxReal& orthoError, const bool disableProcessing, const PxU32 solveHint, PxU32& flags, PxU32& orthoCount, const bool finished) +static void setOrthoData(const PxReal& ang0X, const PxReal& ang0Y, const PxReal& ang0Z, const PxReal& ang1X, const PxReal& ang1Y, const PxReal& ang1Z, + const PxReal& recipResponse, const PxReal& error, PxReal& orthoAng0X, PxReal& orthoAng0Y, PxReal& orthoAng0Z, PxReal& orthoAng1X, PxReal& orthoAng1Y, PxReal& orthoAng1Z, + PxReal& orthoRecipResponse, PxReal& orthoError, bool disableProcessing, PxU32 solveHint, PxU32& flags, PxU32& orthoCount, bool finished) +{ + if (!finished && !disableProcessing) { - if (!finished && !disableProcessing) + if (solveHint == PxConstraintSolveHint::eROTATIONAL_EQUALITY) { - if (solveHint == PxConstraintSolveHint::eROTATIONAL_EQUALITY) - { - flags |= DY_SC_FLAG_ROT_EQ; - orthoAng0X = ang0X; orthoAng0Y = ang0Y; orthoAng0Z = ang0Z; - orthoAng1X = ang1X; orthoAng1Y = ang1Y; orthoAng1Z = ang1Z; - orthoRecipResponse = recipResponse; - orthoError = error; - orthoCount++; - } - else if (solveHint & PxConstraintSolveHint::eEQUALITY) - flags |= DY_SC_FLAG_ORTHO_TARGET; + flags |= DY_SC_FLAG_ROT_EQ; + orthoAng0X = ang0X; orthoAng0Y = ang0Y; orthoAng0Z = ang0Z; + orthoAng1X = ang1X; orthoAng1Y = ang1Y; orthoAng1Z = ang1Z; + orthoRecipResponse = recipResponse; + orthoError = error; + orthoCount++; } + else if (solveHint & PxConstraintSolveHint::eEQUALITY) + flags |= DY_SC_FLAG_ORTHO_TARGET; } } @@ -1954,7 +1907,6 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 const Vec4V invMassScale1 = V4LoadXYZW(constraintDescs[0].invMassScales.linear1, constraintDescs[1].invMassScales.linear1, constraintDescs[2].invMassScales.linear1, constraintDescs[3].invMassScales.linear1); - const Vec4V iMass0 = V4LoadXYZW(bd00.invMass, bd01.invMass, bd02.invMass, bd03.invMass); const Vec4V iMass1 = V4LoadXYZW(bd10.invMass, bd11.invMass, bd12.invMass, bd13.invMass); @@ -1962,13 +1914,11 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 const Vec4V invMass0 = V4Mul(iMass0, invMassScale0); const Vec4V invMass1 = V4Mul(iMass1, invMassScale1); - const Vec4V invInertiaScale0 = V4LoadXYZW(constraintDescs[0].invMassScales.angular0, constraintDescs[1].invMassScales.angular0, constraintDescs[2].invMassScales.angular0, constraintDescs[3].invMassScales.angular0); const Vec4V invInertiaScale1 = V4LoadXYZW(constraintDescs[0].invMassScales.angular1, constraintDescs[1].invMassScales.angular1, constraintDescs[2].invMassScales.angular1, constraintDescs[3].invMassScales.angular1); - //body world offsets Vec4V workOffset0 = Vec4V_From_Vec3V(V3LoadU(constraintDescs[0].body0WorldOffset)); Vec4V workOffset1 = Vec4V_From_Vec3V(V3LoadU(constraintDescs[1].body0WorldOffset)); @@ -1985,7 +1935,6 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 Vec4V angBreakForce = V4LoadXYZW(constraintDescs[0].angBreakForce, constraintDescs[1].angBreakForce, constraintDescs[2].angBreakForce, constraintDescs[3].angBreakForce); - header->breakable[0] = PxU8((constraintDescs[0].linBreakForce != PX_MAX_F32) || (constraintDescs[0].angBreakForce != PX_MAX_F32)); header->breakable[1] = PxU8((constraintDescs[1].linBreakForce != PX_MAX_F32) || (constraintDescs[1].angBreakForce != PX_MAX_F32)); header->breakable[2] = PxU8((constraintDescs[2].linBreakForce != PX_MAX_F32) || (constraintDescs[2].angBreakForce != PX_MAX_F32)); @@ -2010,7 +1959,6 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 header->counts[2] = PxTo8(constraintDescs[2].numRows); header->counts[3] = PxTo8(constraintDescs[3].numRows); - Vec4V ca2WX, ca2WY, ca2WZ; Vec4V cb2WX, cb2WY, cb2WZ; @@ -2062,20 +2010,16 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 Vec4V angState30 = V4LoadA(&constraintDescs[3].bodyData0->originalAngularVelocity.x); Vec4V angState31 = V4LoadA(&constraintDescs[3].bodyData1->originalAngularVelocity.x); - Vec4V linVel0T0, linVel0T1, linVel0T2; Vec4V linVel1T0, linVel1T1, linVel1T2; Vec4V angState0T0, angState0T1, angState0T2; Vec4V angState1T0, angState1T1, angState1T2; - PX_TRANSPOSE_44_34(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2); PX_TRANSPOSE_44_34(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2); PX_TRANSPOSE_44_34(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2); PX_TRANSPOSE_44_34(angState01, angState11, angState21, angState31, angState1T0, angState1T1, angState1T2); - - const Vec4V raWorldX = V4Sub(ca2WX, pos0X); const Vec4V raWorldY = V4Sub(ca2WY, pos0Y); const Vec4V raWorldZ = V4Sub(ca2WZ, pos0Z); @@ -2124,7 +2068,7 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 for (PxU32 a = 0; a < maxRows; ++a) { - bool finished[] = { a >= constraintDescs[0].numRows, a >= constraintDescs[1].numRows, a >= constraintDescs[2].numRows, a >= constraintDescs[3].numRows }; + const bool finished[] = { a >= constraintDescs[0].numRows, a >= constraintDescs[1].numRows, a >= constraintDescs[2].numRows, a >= constraintDescs[3].numRows }; BoolV bFinished = BLoad(finished); SolverConstraint1DStep4* c = reinterpret_cast(currPtr); currPtr += stride; @@ -2134,7 +2078,7 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 Px1DConstraint* con2 = allSorted[index2]; Px1DConstraint* con3 = allSorted[index3]; - bool angularConstraint[4] = + const bool angularConstraint[4] = { !!(con0->flags & Px1DConstraintFlag::eANGULAR_CONSTRAINT), !!(con1->flags & Px1DConstraintFlag::eANGULAR_CONSTRAINT), @@ -2169,7 +2113,6 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 if (con3->flags&Px1DConstraintFlag::eHAS_DRIVE_LIMIT && constraintDescs[3].driveLimitsAreForces) driveScale = V4SetW(driveScale, FMin(fOne, dtV)); - Vec4V clin00 = V4LoadA(&con0->linear0.x); Vec4V clin01 = V4LoadA(&con1->linear0.x); Vec4V clin02 = V4LoadA(&con2->linear0.x); @@ -2269,9 +2212,7 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 angDelta1X = V4Mul(angDelta1X, invInertiaScale1); angDelta1Y = V4Mul(angDelta1Y, invInertiaScale1); angDelta1Z = V4Mul(angDelta1Z, invInertiaScale1); - - - + { PxReal recipResponse[4]; const PxVec4& ur = reinterpret_cast(unitResponse); @@ -2336,7 +2277,6 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 angOrthoAxes0Y[orthoCount3].w, angOrthoAxes0Z[orthoCount3].w, angOrthoAxes1X[orthoCount3].w, angOrthoAxes1Y[orthoCount3].w, angOrthoAxes1Z[orthoCount3].w, orthoRecipResponse[orthoCount3].w, orthoError[orthoCount3].w, constraintDescs[3].disablePreprocessing, con3->solveHint, c->flags[3], orthoCount3, a >= constraintDescs[3].numRows); - } if (con0->flags & Px1DConstraintFlag::eOUTPUT_FORCE) @@ -2366,7 +2306,6 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 c->flags[2] |= DY_SC_FLAG_INEQUALITY; if (con3->solveHint & 1) c->flags[3] |= DY_SC_FLAG_INEQUALITY; - } *(reinterpret_cast(currPtr)) = 0; *(reinterpret_cast(currPtr + 4)) = 0; @@ -2376,11 +2315,7 @@ SolverConstraintPrepState::Enum setupSolverConstraintStep4 return SolverConstraintPrepState::eSUCCESS; } - - - - -void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const bool doFriction, const PxReal minPenetration, +static void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const bool doFriction, const PxReal minPenetration, const PxReal elapsedTimeF32) { PxTGSSolverBodyVel& b00 = *desc[0].tgsBodyA; @@ -2419,19 +2354,16 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b Vec4V angState30 = V4LoadA(&b30.angularVelocity.x); Vec4V angState31 = V4LoadA(&b31.angularVelocity.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V linVel1T0, linVel1T1, linVel1T2, linVel1T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; Vec4V angState1T0, angState1T1, angState1T2, angState1T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2, linVel1T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); PX_TRANSPOSE_44(angState01, angState11, angState21, angState31, angState1T0, angState1T1, angState1T2, angState1T3); - Vec4V linDelta00_ = V4LoadA(&b00.deltaLinDt.x); Vec4V linDelta01_ = V4LoadA(&b01.deltaLinDt.x); Vec4V angDelta00_ = V4LoadA(&b00.deltaAngDt.x); @@ -2457,13 +2389,11 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b Vec4V angDelta0T0, angDelta0T1, angDelta0T2; Vec4V angDelta1T0, angDelta1T1, angDelta1T2; - PX_TRANSPOSE_44_34(linDelta00_, linDelta10_, linDelta20_, linDelta30_, linDelta0T0, linDelta0T1, linDelta0T2); PX_TRANSPOSE_44_34(linDelta01_, linDelta11_, linDelta21_, linDelta31_, linDelta1T0, linDelta1T1, linDelta1T2); PX_TRANSPOSE_44_34(angDelta00_, angDelta10_, angDelta20_, angDelta30_, angDelta0T0, angDelta0T1, angDelta0T2); PX_TRANSPOSE_44_34(angDelta01_, angDelta11_, angDelta21_, angDelta31_, angDelta1T0, angDelta1T1, angDelta1T2); - const PxU8* PX_RESTRICT last = desc[0].constraint + getConstraintLength(desc[0]); //hopefully pointer aliasing doesn't bite. @@ -2482,10 +2412,8 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b Vec4V linDeltaY = V4Sub(linDelta0T1, linDelta1T1); Vec4V linDeltaZ = V4Sub(linDelta0T2, linDelta1T2); - while (currPtr < last) { - hdr = reinterpret_cast(currPtr); PX_ASSERT(hdr->type == DY_SC_TYPE_BLOCK_RB_CONTACT); @@ -2495,7 +2423,7 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b const PxU32 numNormalConstr = hdr->numNormalConstr; const PxU32 numFrictionConstr = hdr->numFrictionConstr; - bool hasMaxImpulse = (hdr->flag & SolverContactHeaderStepBlock::eHAS_MAX_IMPULSE) != 0; + const bool hasMaxImpulse = (hdr->flag & SolverContactHeaderStepBlock::eHAS_MAX_IMPULSE) != 0; Vec4V* appliedForces = reinterpret_cast(currPtr); currPtr += sizeof(Vec4V)*numNormalConstr; @@ -2516,7 +2444,6 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b maxImpulses = &vMax; } - /*SolverFrictionSharedData4* PX_RESTRICT fd = reinterpret_cast(currPtr); if (numFrictionConstr) currPtr += sizeof(SolverFrictionSharedData4);*/ @@ -2597,8 +2524,6 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b const Vec4V bias = V4Min(V4Neg(maxPenBias), V4Mul(biasCoefficient, sep)); - - const Vec4V velMultiplier = c.velMultiplier; const Vec4V tVelBias = V4Mul(bias, c.recipResponse); @@ -2640,7 +2565,6 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b linVel0T2 = V4MulAdd(_normalT2, accumDeltaF_IM0, linVel0T2); linVel1T2 = V4NegMulSub(_normalT2, accumDeltaF_IM1, linVel1T2); - if (doFriction && numFrictionConstr) { const Vec4V staticFric = hdr->staticFriction; @@ -2650,7 +2574,6 @@ void solveContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, const b const Vec4V maxDynFrictionImpulse = V4Mul(dynamicFric, accumulatedNormalImpulse); BoolV broken = BFFFF(); - for (PxU32 i = 0; iflag & SolverContactHeader4::eHAS_MAX_IMPULSE) != 0; + const bool hasMaxImpulse = (hdr->flag & SolverContactHeader4::eHAS_MAX_IMPULSE) != 0; if (hasMaxImpulse) currPtr += sizeof(Vec4V) * numNormalConstr; @@ -2923,7 +2842,6 @@ void writeBackContact4_Block(const PxSolverConstraintDesc* PX_RESTRICT desc, Sol writeBackThresholds[2] = hdr->flags[2] & SolverContactHeader::eHAS_FORCE_THRESHOLDS; writeBackThresholds[3] = hdr->flags[3] & SolverContactHeader::eHAS_FORCE_THRESHOLDS; - for (PxU32 i = 0; iconstraint; if (bPtr == NULL) @@ -3055,19 +2973,16 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol Vec4V angState30 = V4LoadA(&b30.angularVelocity.x); Vec4V angState31 = V4LoadA(&b31.angularVelocity.x); - Vec4V linVel0T0, linVel0T1, linVel0T2, linVel0T3; Vec4V linVel1T0, linVel1T1, linVel1T2, linVel1T3; Vec4V angState0T0, angState0T1, angState0T2, angState0T3; Vec4V angState1T0, angState1T1, angState1T2, angState1T3; - PX_TRANSPOSE_44(linVel00, linVel10, linVel20, linVel30, linVel0T0, linVel0T1, linVel0T2, linVel0T3); PX_TRANSPOSE_44(linVel01, linVel11, linVel21, linVel31, linVel1T0, linVel1T1, linVel1T2, linVel1T3); PX_TRANSPOSE_44(angState00, angState10, angState20, angState30, angState0T0, angState0T1, angState0T2, angState0T3); PX_TRANSPOSE_44(angState01, angState11, angState21, angState31, angState1T0, angState1T1, angState1T2, angState1T3); - Vec4V linDelta00 = V4LoadA(&b00.deltaLinDt.x); Vec4V linDelta01 = V4LoadA(&b01.deltaLinDt.x); Vec4V angDelta00 = V4LoadA(&b00.deltaAngDt.x); @@ -3093,19 +3008,14 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol Vec4V angDelta0T0, angDelta0T1, angDelta0T2; Vec4V angDelta1T0, angDelta1T1, angDelta1T2; - PX_TRANSPOSE_44_34(linDelta00, linDelta10, linDelta20, linDelta30, linDelta0T0, linDelta0T1, linDelta0T2); PX_TRANSPOSE_44_34(linDelta01, linDelta11, linDelta21, linDelta31, linDelta1T0, linDelta1T1, linDelta1T2); PX_TRANSPOSE_44_34(angDelta00, angDelta10, angDelta20, angDelta30, angDelta0T0, angDelta0T1, angDelta0T2); PX_TRANSPOSE_44_34(angDelta01, angDelta11, angDelta21, angDelta31, angDelta1T0, angDelta1T1, angDelta1T2); - - - const SolverConstraint1DHeaderStep4* PX_RESTRICT header = reinterpret_cast(bPtr); SolverConstraint1DStep4* PX_RESTRICT base = reinterpret_cast(bPtr + sizeof(SolverConstraint1DHeaderStep4)); - Vec4V invInertia00X = Vec4V_From_Vec3V(V3LoadU_SafeReadW(txI00.sqrtInvInertia.column0)); // PT: safe because 'column1' follows 'column0' in PxMat33 Vec4V invInertia00Y = Vec4V_From_Vec3V(V3LoadU_SafeReadW(txI00.sqrtInvInertia.column1)); // PT: safe because 'column2' follows 'column1' in PxMat33 Vec4V invInertia00Z = Vec4V_From_Vec3V(V3LoadU(txI00.sqrtInvInertia.column2)); @@ -3179,7 +3089,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol QuatRotate4(rot0X, rot0Y, rot0Z, rot0W, header->rAWorld[0], header->rAWorld[1], header->rAWorld[2], raX, raY, raZ); QuatRotate4(rot1X, rot1Y, rot1Z, rot1W, header->rBWorld[0], header->rBWorld[1], header->rBWorld[2], rbX, rbY, rbZ); - const Vec4V raMotionX = V4Sub(V4Add(raX, linDelta0T0), header->rAWorld[0]); const Vec4V raMotionY = V4Sub(V4Add(raY, linDelta0T1), header->rAWorld[1]); const Vec4V raMotionZ = V4Sub(V4Add(raZ, linDelta0T2), header->rAWorld[2]); @@ -3207,7 +3116,8 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol V4Sub(V4Dot3(header->angOrthoAxis0X[2], header->angOrthoAxis0Y[2], header->angOrthoAxis0Z[2], angDelta0T0, angDelta0T1, angDelta0T2), V4Dot3(header->angOrthoAxis1X[2], header->angOrthoAxis1Y[2], header->angOrthoAxis1Z[2], angDelta1T0, angDelta1T1, angDelta1T2))); - for (PxU32 i = 0; icount; ++i, base++) + const PxU32 count = header->count; + for (PxU32 i = 0; iangOrthoAxis1Y[0], proj0, V4MulAdd(header->angOrthoAxis1Y[1], proj1, V4Mul(header->angOrthoAxis1Y[2], proj2))); const Vec4V delta1Z = V4MulAdd(header->angOrthoAxis1Z[0], proj0, V4MulAdd(header->angOrthoAxis1Z[1], proj1, V4Mul(header->angOrthoAxis1Z[2], proj2))); - delAngVel0X = V4NegMulSub(delta0X, angOrthoCoefficient, delAngVel0X); delAngVel0Y = V4NegMulSub(delta0Y, angOrthoCoefficient, delAngVel0Y); delAngVel0Z = V4NegMulSub(delta0Z, angOrthoCoefficient, delAngVel0Z); @@ -3310,7 +3217,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol ang1IY = V4MulAdd(invInertia1Z1, delAngVel1Z, ang1IY); ang1IZ = V4MulAdd(invInertia1Z2, delAngVel1Z, ang1IZ); - const Vec4V clinVel0X = c.lin0[0]; const Vec4V clinVel0Y = c.lin0[1]; const Vec4V clinVel0Z = c.lin0[2]; @@ -3319,7 +3225,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol const Vec4V clinVel1Y = c.lin1[1]; const Vec4V clinVel1Z = c.lin1[2]; - const Vec4V clinVel0X_ = c.lin0[0]; const Vec4V clinVel0Y_ = c.lin0[1]; const Vec4V clinVel0Z_ = c.lin0[2]; @@ -3328,12 +3233,9 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol const Vec4V clinVel1Y_ = c.lin1[1]; const Vec4V clinVel1Z_ = c.lin1[2]; - //KS - compute raXnI and effective mass. Unfortunately, the joints are noticeably less stable if we don't do this each //iteration. It's skippable. If we do that, there's no need for the invInertiaTensors - - const Vec4V dotDelAngVel0 = V4MulAdd(delAngVel0X, delAngVel0X, V4MulAdd(delAngVel0Y, delAngVel0Y, V4Mul(delAngVel0Z, delAngVel0Z))); const Vec4V dotDelAngVel1 = V4MulAdd(delAngVel1X, delAngVel1X, V4MulAdd(delAngVel1Y, delAngVel1Y, V4Mul(delAngVel1Z, delAngVel1Z))); @@ -3354,7 +3256,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol const Vec4V response = V4Add(resp0, resp1); const Vec4V recipResponse = V4Sel(V4IsGrtr(response, V4Zero()), V4Recip(response), V4Zero()); - const Vec4V vMul = V4Mul(recipResponse, c.velMultiplier); const BoolV isLimitConstraint = VecI32V_IsEq(VecI32V_And(flags, limitMask), limitMask); @@ -3373,7 +3274,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol const Vec4V normalVel = V4Add(V4Sub(normalVel0, normalVel1), V4Sub(angVel0, angVel1)); - const Vec4V unclampedForce = V4Add(c.appliedForce, V4MulAdd(vMul, normalVel, constant)); const Vec4V clampedForce = V4Clamp(unclampedForce, c.minImpulse, c.maxImpulse); const Vec4V deltaF = V4Sub(clampedForce, c.appliedForce); @@ -3385,7 +3285,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol const Vec4V angDetaF0 = V4Mul(deltaF, invInertiaScale0); const Vec4V angDetaF1 = V4Mul(deltaF, invInertiaScale1); - linVel0T0 = V4MulAdd(clinVel0X_, deltaFIM0, linVel0T0); linVel1T0 = V4NegMulSub(clinVel1X_, deltaFIM1, linVel1T0); angState0T0 = V4MulAdd(delAngVel0X, angDetaF0, angState0T0); @@ -3400,7 +3299,6 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol linVel1T2 = V4NegMulSub(clinVel1Z_, deltaFIM1, linVel1T2); angState0T2 = V4MulAdd(delAngVel0Z, angDetaF0, angState0T2); angState1T2 = V4NegMulSub(delAngVel1Z, angDetaF1, angState1T2); - } PX_TRANSPOSE_44(linVel0T0, linVel0T1, linVel0T2, linVel0T3, linVel00, linVel10, linVel20, linVel30); @@ -3464,16 +3362,18 @@ void solve1DStep4(const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSol PX_ASSERT(b31.angularVelocity.isFinite()); } - -void solve1D4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSolverBodyTxInertia* const txInertias, - const PxReal /*minPenetration*/, const PxReal elapsedTime, SolverContext& /*cache*/) +void solve1D4(DY_TGS_SOLVE_METHOD_PARAMS) { + PX_UNUSED(minPenetration); + PX_UNUSED(cache); + solve1DStep4(desc + hdr.startIndex, txInertias, elapsedTime); } -void writeBack1D4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext* /*cache*/) +void writeBack1D4(DY_TGS_WRITEBACK_METHOD_PARAMS) { - PX_UNUSED(hdr); + PX_UNUSED(cache); + ConstraintWriteback* writeback0 = reinterpret_cast(desc[hdr.startIndex].writeBack); ConstraintWriteback* writeback1 = reinterpret_cast(desc[hdr.startIndex + 1].writeBack); ConstraintWriteback* writeback2 = reinterpret_cast(desc[hdr.startIndex + 2].writeBack); @@ -3488,7 +3388,8 @@ void writeBack1D4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDe Vec4V linX(zero), linY(zero), linZ(zero); Vec4V angX(zero), angY(zero), angZ(zero); - for (PxU32 i = 0; icount; i++) + const PxU32 count = header->count; + for (PxU32 i = 0; iconstraint; if (bPtr == NULL) return; - const SolverConstraint1DHeaderStep4* PX_RESTRICT header = reinterpret_cast(bPtr); SolverConstraint1DStep4* PX_RESTRICT base = reinterpret_cast(bPtr + sizeof(SolverConstraint1DHeaderStep4)); const VecI32V mask = I4Load(DY_SC_FLAG_KEEP_BIAS); const Vec4V zero = V4Zero(); - for (PxU32 i = 0; icount; ++i, base++) + const PxU32 count = header->count; + for (PxU32 i = 0; i(&body.partitionMask))++; } - static inline void waitForArticulationProgress(Dy::FeatherstoneArticulation& artic, const PxU32 desiredProgress, const PxU32 iteration) + static inline void waitForArticulationProgress(Dy::FeatherstoneArticulation& artic, PxU32 desiredProgress, PxU32 iteration) { const PxI32 target = PxI32(desiredProgress + artic.maxSolverFrictionProgress * iteration); @@ -104,7 +104,7 @@ namespace Dy (*reinterpret_cast(&artic.solverProgress))++; } - static inline void waitForProgresses(const PxSolverConstraintDesc& desc, const PxU32 iteration) + static inline void waitForProgresses(const PxSolverConstraintDesc& desc, PxU32 iteration) { if (desc.linkIndexA == PxSolverConstraintDesc::RIGID_BODY) waitForBodyProgress(*desc.tgsBodyA, desc.progressA, iteration); @@ -130,40 +130,14 @@ namespace Dy incrementArticulationProgress(*getArticulationB(desc)); } -Context* createTGSDynamicsContext(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, - PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, PxU64 contextID, - const bool enableStabilization, const bool useEnhancedDeterminism, - const PxReal lengthScale - ) +Context* createTGSDynamicsContext( PxcNpMemBlockPool* memBlockPool, PxcScratchAllocator& scratchAllocator, Cm::FlushPool& taskPool, + PxvSimStats& simStats, PxTaskManager* taskManager, PxVirtualAllocatorCallback* allocatorCallback, + PxsMaterialManager* materialManager, IG::SimpleIslandManager* islandManager, PxU64 contextID, + bool enableStabilization, bool useEnhancedDeterminism, + PxReal lengthScale) { - return DynamicsTGSContext::create(memBlockPool, scratchAllocator, taskPool, simStats, taskManager, allocatorCallback, materialManager, islandManager, - contextID, enableStabilization, useEnhancedDeterminism, lengthScale); -} - -// PT: TODO: consider removing this function. We already have "createDynamicsContext". -DynamicsTGSContext* DynamicsTGSContext::create(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocatorCallback, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal lengthScale - ) -{ - // PT: TODO: inherit from UserAllocated, remove placement new - DynamicsTGSContext* dc = reinterpret_cast(PX_ALLOC(sizeof(DynamicsTGSContext), "DynamicsTGSContext")); - if (dc) - { - PX_PLACEMENT_NEW(dc, DynamicsTGSContext(memBlockPool, scratchAllocator, taskPool, simStats, taskManager, allocatorCallback, materialManager, islandManager, contextID, enableStabilization, useEnhancedDeterminism, lengthScale)); - } - return dc; + return PX_NEW(DynamicsTGSContext)( memBlockPool, scratchAllocator, taskPool, simStats, taskManager, allocatorCallback, materialManager, islandManager, contextID, + enableStabilization, useEnhancedDeterminism, lengthScale); } void DynamicsTGSContext::destroy() @@ -189,11 +163,11 @@ PX_FORCE_INLINE PxVec3 safeRecip(const PxVec3& v) return PxVec3(v.x == 0.f ? 0.f : 1.f/v.x, v.y == 0.f ? 0.f : 1.f/v.y, v.z == 0.f ? 0.f : 1.f/v.z); } -void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angularVelocity, const PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, - const PxReal maxDepenetrationVelocity, const PxReal maxContactImpulse, const PxU32 nodeIndex, const PxReal reportThreshold, - const PxReal maxAngVelSq, PxU32 lockFlags, bool isKinematic, - PxTGSSolverBodyVel& solverVel, PxTGSSolverBodyTxInertia& solverBodyTxInertia, PxTGSSolverBodyData& solverBodyData, const PxReal dt, - const bool gyroscopicForces) +void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angularVelocity, PxReal invMass, const PxVec3& invInertia, const PxTransform& globalPose, + PxReal maxDepenetrationVelocity, PxReal maxContactImpulse, PxU32 nodeIndex, PxReal reportThreshold, + PxReal maxAngVelSq, PxU32 lockFlags, bool isKinematic, + PxTGSSolverBodyVel& solverVel, PxTGSSolverBodyTxInertia& solverBodyTxInertia, PxTGSSolverBodyData& solverBodyData, PxReal dt, + bool gyroscopicForces) { const PxMat33Padded rotation(globalPose.q); @@ -212,16 +186,13 @@ void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angula PxVec3 lv = linearVelocity; PxVec3 av = angularVelocity; - if (gyroscopicForces) { - const PxVec3 localInertia( invInertia.x == 0.f ? 0.f : 1.f / invInertia.x, invInertia.y == 0.f ? 0.f : 1.f / invInertia.y, invInertia.z == 0.f ? 0.f : 1.f / invInertia.z); - PxVec3 localAngVel = globalPose.q.rotateInv(av); PxVec3 origMom = localInertia.multiply(localAngVel); PxVec3 torque = -localAngVel.cross(origMom); @@ -231,7 +202,6 @@ void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angula newMom *= ratio; PxVec3 newDeltaAngVel = globalPose.q.rotate(invInertia.multiply(newMom) - localAngVel); av += newDeltaAngVel; - } if (lockFlags) @@ -272,8 +242,6 @@ void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angula solverVel.maxAngVel = PxSqrt(maxAngVelSq); solverVel.partitionMask = 0; - - solverBodyData.nodeIndex = nodeIndex; solverBodyData.invMass = invMass; solverBodyData.penBiasClamp = maxDepenetrationVelocity; @@ -286,11 +254,8 @@ void copyToSolverBodyDataStep(const PxVec3& linearVelocity, const PxVec3& angula PX_ASSERT(av.isFinite()); } - - void copyToSolverBodyDataStepKinematic(const PxVec3& linearVelocity, const PxVec3& angularVelocity, const PxTransform& globalPose, - const PxReal maxDepenetrationVelocity, const PxReal maxContactImpulse, const PxU32 nodeIndex, const PxReal reportThreshold, - const PxReal maxAngVelSq, + PxReal maxDepenetrationVelocity, PxReal maxContactImpulse, PxU32 nodeIndex, PxReal reportThreshold, PxReal maxAngVelSq, PxTGSSolverBodyVel& solverVel, PxTGSSolverBodyTxInertia& solverBodyTxInertia, PxTGSSolverBodyData& solverBodyData) { const PxMat33Padded rotation(globalPose.q); @@ -320,30 +285,27 @@ void copyToSolverBodyDataStepKinematic(const PxVec3& linearVelocity, const PxVec solverBodyData.originalAngularVelocity = angularVelocity; } - // =========================== Basic methods - -DynamicsTGSContext::DynamicsTGSContext(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocatorCallback, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal lengthScale - ) : - Dy::Context(islandManager, allocatorCallback, simStats, enableStabilization, useEnhancedDeterminism, PX_MAX_F32, lengthScale), - mThreadContextPool(memBlockPool), - mMaterialManager(materialManager), - mScratchAllocator(scratchAllocator), - mTaskPool(taskPool), - mTaskManager(taskManager), - mContextID(contextID) +DynamicsTGSContext::DynamicsTGSContext( PxcNpMemBlockPool* memBlockPool, + PxcScratchAllocator& scratchAllocator, + Cm::FlushPool& taskPool, + PxvSimStats& simStats, + PxTaskManager* taskManager, + PxVirtualAllocatorCallback* allocatorCallback, + PxsMaterialManager* materialManager, + IG::SimpleIslandManager* islandManager, + PxU64 contextID, + bool enableStabilization, + bool useEnhancedDeterminism, + PxReal lengthScale) : + Dy::Context (islandManager, allocatorCallback, simStats, enableStabilization, useEnhancedDeterminism, PX_MAX_F32, lengthScale, contextID), + // PT: TODO: would make sense to move all the following members to the base class but include paths get in the way atm + mThreadContextPool (memBlockPool), + mMaterialManager (materialManager), + mScratchAllocator (scratchAllocator), + mTaskPool (taskPool), + mTaskManager (taskManager) { createThresholdStream(*allocatorCallback); createForceChangeThresholdStream(*allocatorCallback); @@ -375,7 +337,7 @@ DynamicsTGSContext::~DynamicsTGSContext() } void DynamicsTGSContext::setDescFromIndices(PxSolverConstraintDesc& desc, const IG::IslandSim& islandSim, - const PxsIndexedInteraction& constraint, const PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies) + const PxsIndexedInteraction& constraint, PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies) { PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eBODY == 0); PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eKINEMATIC == 1); @@ -422,7 +384,7 @@ void DynamicsTGSContext::setDescFromIndices(PxSolverConstraintDesc& desc, const } void DynamicsTGSContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeIndex edgeIndex, const IG::SimpleIslandManager& islandManager, - PxU32* bodyRemap, const PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies) + PxU32* bodyRemap, PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies) { PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eBODY == 0); PX_COMPILE_TIME_ASSERT(PxsIndexedInteraction::eKINEMATIC == 1); @@ -517,6 +479,8 @@ void DynamicsTGSContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::Ed } } +namespace +{ class DynamicsMergeTask : public Cm::Task { PxBaseTask* mSecondContinuation; @@ -539,7 +503,6 @@ class DynamicsMergeTask : public Cm::Task mSecondContinuation->removeReference(); Cm::Task::release(); } - }; class KinematicCopyTGSTask : public Cm::Task @@ -558,7 +521,7 @@ class KinematicCopyTGSTask : public Cm::Task static const PxU32 NbKinematicsPerTask = 1024; KinematicCopyTGSTask(const PxNodeIndex* const kinematicIndices, - const PxU32 nbKinematics, const IG::IslandSim& islandSim, PxTGSSolverBodyVel* vels, + PxU32 nbKinematics, const IG::IslandSim& islandSim, PxTGSSolverBodyVel* vels, PxTGSSolverBodyTxInertia* inertias, PxTGSSolverBodyData* datas, PxU64 contextID) : Cm::Task(contextID), mKinematicIndices(kinematicIndices), mNbKinematics(nbKinematics), mIslandSim(islandSim), mVels(vels), mInertia(inertias), mBodyData(datas) @@ -594,8 +557,8 @@ class UpdateContinuationTGSTask : public Cm::Task UpdateContinuationTGSTask(DynamicsTGSContext& context, IG::SimpleIslandManager& simpleIslandManager, - PxBaseTask* lostTouchTask, - PxU64 contextID, const PxU32 maxLinks) : Cm::Task(contextID), mContext(context), mSimpleIslandManager(simpleIslandManager), + PxBaseTask* lostTouchTask, PxU64 contextID, PxU32 maxLinks) : + Cm::Task(contextID), mContext(context), mSimpleIslandManager(simpleIslandManager), mLostTouchTask(lostTouchTask), mMaxArticulationLinks(maxLinks) { } @@ -608,14 +571,13 @@ class UpdateContinuationTGSTask : public Cm::Task //Allow lost touch task to run once all tasks have be scheduled mLostTouchTask->removeReference(); } - }; - +} void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, PxvNphaseImplementationContext* nphase, - const PxU32 /*maxPatchesPerCM*/, const PxU32 maxArticulationLinks, - const PxReal dt, const PxVec3& gravity, PxBitMapPinned& /*changedHandleMap*/) + PxU32 /*maxPatchesPerCM*/, PxU32 maxArticulationLinks, + PxReal dt, const PxVec3& gravity, PxBitMapPinned& /*changedHandleMap*/) { PX_PROFILE_ZONE("Dynamics.solverQueueTasks", mContextID); @@ -623,11 +585,9 @@ void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, Px mOutputIterator = nphase->getContactManagerOutputs(); - //const PxU32 nbSubsteps = 16; - + // PT: TODO: refactor mDt = dt; - mInvDt = 1.f / dt; - + mInvDt = 1.0f / dt; mGravity = gravity; const IG::IslandSim& islandSim = simpleIslandManager.getAccurateIslandSim(); @@ -641,9 +601,7 @@ void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, Px { PxsContactManager* cm = simpleIslandManager.getContactManager(activatingEdges[a]); if (cm) - { cm->getWorkUnit().frictionPatchCount = 0; //KS - zero the friction patch count on any activating edges - } } #if PX_ENABLE_SIM_STATS @@ -668,10 +626,8 @@ void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, Px resetThreadContexts(); //If there is no work to do then we can do nothing at all. - if (0 == islandCount) - { + if(!islandCount) return; - } //Block to make sure it doesn't run before stage2 of update! lostTouchTask->addReference(); @@ -721,9 +677,10 @@ void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, Px mSolverBodyTxInertiaPool[0] = mWorldSolverBodyTxInertia; mSolverBodyDataPool2[0] = mWorldSolverBodyData2; - + if(kinematicCount) { PX_PROFILE_ZONE("Dynamics.updateKinematics", mContextID); + // PT: TODO: why no PxMemZero here compared to PGS? for (PxU32 i = 0; i < kinematicCount; i+= KinematicCopyTGSTask::NbKinematicsPerTask) { const PxU32 nbToProcess = PxMin(kinematicCount - i, KinematicCopyTGSTask::NbKinematicsPerTask); @@ -738,13 +695,12 @@ void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, Px } } - - PxU32 numArticulationConstraints = numArtics* maxArticulationLinks; //Just allocate enough memory to fit worst-case maximum size articulations... + const PxU32 numArticulationConstraints = numArtics* maxArticulationLinks; //Just allocate enough memory to fit worst-case maximum size articulations... const PxU32 nbActiveContactManagers = islandSim.getNbActiveEdges(IG::Edge::eCONTACT_MANAGER); const PxU32 nbActiveConstraints = islandSim.getNbActiveEdges(IG::Edge::eCONSTRAINT); - PxU32 totalConstraintCount = nbActiveConstraints + nbActiveContactManagers + numArticulationConstraints; + const PxU32 totalConstraintCount = nbActiveConstraints + nbActiveContactManagers + numArticulationConstraints; mSolverConstraintDescPool.forceSize_Unsafe(0); mSolverConstraintDescPool.reserve((totalConstraintCount + 63) & (~63)); @@ -786,24 +742,17 @@ void DynamicsTGSContext::update(IG::SimpleIslandManager& simpleIslandManager, Px mNodeIndexArray.reserve((bodyCount + 63u) & (~63u)); mNodeIndexArray.forceSize_Unsafe(bodyCount); - - - ThresholdStream& stream = getThresholdStream(); stream.forceSize_Unsafe(0); stream.reserve(PxNextPowerOfTwo(nbActiveContactManagers != 0 ? nbActiveContactManagers - 1 : nbActiveContactManagers)); - - //flip exceeded force threshold buffer mCurrentIndex = 1 - mCurrentIndex; task->removeReference(); - } -void DynamicsTGSContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, - PxBaseTask* lostTouchTask, const PxU32 maxLinks) +void DynamicsTGSContext::updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, PxU32 maxLinks) { const IG::IslandSim& islandSim = simpleIslandManager.getAccurateIslandSim(); @@ -814,8 +763,6 @@ void DynamicsTGSContext::updatePostKinematic(IG::SimpleIslandManager& simpleIsla mergeTask->setContinuation(continuation); mergeTask->setSecondContinuation(lostTouchTask); - //PxReal dt = mDt; - PxU32 currentIsland = 0; PxU32 currentBodyIndex = 0; PxU32 currentArticulation = 0; @@ -853,7 +800,6 @@ void DynamicsTGSContext::updatePostKinematic(IG::SimpleIslandManager& simpleIsla PxU32 nbBodies = 0; PxU32 nbConstraints = 0; PxU32 nbContactManagers = 0; - while (nbBodies < minIslandSize && currentIsland < islandCount && nbArticulations < articulationBatchSize) { @@ -894,8 +840,7 @@ void DynamicsTGSContext::updatePostKinematic(IG::SimpleIslandManager& simpleIsla } void DynamicsTGSContext::prepareBodiesAndConstraints(const SolverIslandObjectsStep& objects, - IG::SimpleIslandManager& islandManager, - IslandContextStep& islandContext) + IG::SimpleIslandManager& islandManager, IslandContextStep& islandContext) { Dy::ThreadContext& mThreadContext = *islandContext.mThreadContext; @@ -963,7 +908,6 @@ void DynamicsTGSContext::prepareBodiesAndConstraints(const SolverIslandObjectsSt } } - PxsIndexedContactManager* indexedManagers = objects.contactManagers; PxU32 currentContactIndex = 0; @@ -1012,7 +956,6 @@ void DynamicsTGSContext::prepareBodiesAndConstraints(const SolverIslandObjectsSt } PX_ASSERT(indexedManager.solverBody0 < (islandContext.mCounts.bodies + mKinematicCount + 1)); } - } if (nodeIndex2.isStaticBody()) @@ -1095,40 +1038,36 @@ void DynamicsTGSContext::setupDescs(IslandContextStep& mIslandContext, const Sol contactDescPtr++; edgeId = edge.mNextIslandEdge; } - } PxSort(mObjects.constraintDescs, PxU32(contactDescPtr - mObjects.constraintDescs), ConstraintLess()); if (mIslandContext.mCounts.contactManagers) { + for (PxU32 a = 0; a < mIslandContext.mCounts.contactManagers; ++a) { - for (PxU32 a = 0; a < mIslandContext.mCounts.contactManagers; ++a) + //PxsContactManagerOutput& output = outputs.getContactManager(mObjects.contactManagers[a].contactManager->getWorkUnit().mNpIndex); + //if (output.nbContacts > 0) { - //PxsContactManagerOutput& output = outputs.getContactManager(mObjects.contactManagers[a].contactManager->getWorkUnit().mNpIndex); - //if (output.nbContacts > 0) - { - PxSolverConstraintDesc& desc = *contactDescPtr; - setDescFromIndices(desc, islandSim, mObjects.contactManagers[a], mSolverBodyOffset, mSolverBodyVelPool.begin()); - desc.constraint = reinterpret_cast(mObjects.contactManagers[a].contactManager); - desc.constraintLengthOver16 = DY_SC_TYPE_RB_CONTACT; - contactDescPtr++; - } - //else - //{ - // //Clear friction state! - // mObjects.contactManagers[a].contactManager->getWorkUnit().frictionDataPtr = NULL; - // mObjects.contactManagers[a].contactManager->getWorkUnit().frictionPatchCount = 0; - //} + PxSolverConstraintDesc& desc = *contactDescPtr; + setDescFromIndices(desc, islandSim, mObjects.contactManagers[a], mSolverBodyOffset, mSolverBodyVelPool.begin()); + desc.constraint = reinterpret_cast(mObjects.contactManagers[a].contactManager); + desc.constraintLengthOver16 = DY_SC_TYPE_RB_CONTACT; + contactDescPtr++; } - + //else + //{ + // //Clear friction state! + // mObjects.contactManagers[a].contactManager->getWorkUnit().frictionDataPtr = NULL; + // mObjects.contactManagers[a].contactManager->getWorkUnit().frictionPatchCount = 0; + //} } } mThreadContext.contactDescArraySize = PxU32(contactDescPtr - mObjects.constraintDescs); } void DynamicsTGSContext::preIntegrateBodies(PxsBodyCore** bodyArray, PxsRigidBody** originalBodyArray, - PxTGSSolverBodyVel* solverBodyVelPool, PxTGSSolverBodyTxInertia* solverBodyTxInertia, PxTGSSolverBodyData* solverBodyDataPool2, PxU32* nodeIndexArray, const PxU32 bodyCount, const PxVec3& gravity, const PxReal dt, PxU32& posIters, PxU32& velIters, PxU32 /*iteration*/) + PxTGSSolverBodyVel* solverBodyVelPool, PxTGSSolverBodyTxInertia* solverBodyTxInertia, PxTGSSolverBodyData* solverBodyDataPool2, PxU32* nodeIndexArray, PxU32 bodyCount, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, PxU32 /*iteration*/) { PX_PROFILE_ZONE("PreIntegrate", mContextID); PxU32 localMaxPosIter = 0; @@ -1138,7 +1077,7 @@ void DynamicsTGSContext::preIntegrateBodies(PxsBodyCore** bodyArray, PxsRigidBod PxsBodyCore& core = *bodyArray[i]; const PxsRigidBody& rBody = *originalBodyArray[i]; - PxU16 iterWord = core.solverIterationCounts; + const PxU16 iterWord = core.solverIterationCounts; localMaxPosIter = PxMax(PxU32(iterWord & 0xff), localMaxPosIter); localMaxVelIter = PxMax(PxU32(iterWord >> 8), localMaxVelIter); @@ -1155,7 +1094,7 @@ void DynamicsTGSContext::preIntegrateBodies(PxsBodyCore** bodyArray, PxsRigidBod velIters = localMaxVelIter; } -void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contactDescPtr, PxConstraintBatchHeader* headers, const PxU32 nbHeaders, +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) { @@ -1287,7 +1226,6 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact if (buildState != SolverConstraintPrepState::eSUCCESS) { - for (PxU32 a = startIdx, i = 0; a < endIdx; ++a, i++) { PxSolverConstraintDesc& desc = contactDescPtr[a]; @@ -1314,9 +1252,7 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact PxcNpWorkUnit& unit = cm->getWorkUnit(); unit.frictionDataPtr = blockDescs[i].frictionPtr; unit.frictionPatchCount = blockDescs[i].frictionCount; - } - } else if (contactDescPtr[startIdx].constraintLengthOver16 == DY_SC_TYPE_RB_1D) { @@ -1385,7 +1321,6 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact } #endif #endif - if (buildState != SolverConstraintPrepState::eSUCCESS) { for (PxU32 a = startIdx, i = 0; a < endIdx; ++a, i++) @@ -1399,117 +1334,84 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact } } - - -void solveContactBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - -void solve1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - -void solveExtContactBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertia, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - -void solveExt1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - -void solveContact4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSolverBodyTxInertia* const txInertias, - const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - -void solve1D4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* PX_RESTRICT desc, const PxTGSSolverBodyTxInertia* const txInertias, - const PxReal minPenetration, const PxReal elapsedTime, SolverContext& cache); - +void solveContactBlock (DY_TGS_SOLVE_METHOD_PARAMS); +void solve1DBlock (DY_TGS_SOLVE_METHOD_PARAMS); +void solveExtContactBlock (DY_TGS_SOLVE_METHOD_PARAMS); +void solveExt1DBlock (DY_TGS_SOLVE_METHOD_PARAMS); +void solveContact4 (DY_TGS_SOLVE_METHOD_PARAMS); +void solve1D4 (DY_TGS_SOLVE_METHOD_PARAMS); TGSSolveBlockMethod g_SolveTGSMethods[] = { 0, - solveContactBlock, // DY_SC_TYPE_RB_CONTACT - solve1DBlock, // DY_SC_TYPE_RB_1D - solveExtContactBlock, // DY_SC_TYPE_EXT_CONTACT - solveExt1DBlock, // DY_SC_TYPE_EXT_1D - solveContactBlock, // DY_SC_TYPE_STATIC_CONTACT - solveContactBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveContact4, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveContact4, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solve1D4, // DY_SC_TYPE_BLOCK_1D, + solveContactBlock, // DY_SC_TYPE_RB_CONTACT + solve1DBlock, // DY_SC_TYPE_RB_1D + solveExtContactBlock, // DY_SC_TYPE_EXT_CONTACT + solveExt1DBlock, // DY_SC_TYPE_EXT_1D + solveContactBlock, // DY_SC_TYPE_STATIC_CONTACT + solveContactBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveContact4, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveContact4, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solve1D4, // DY_SC_TYPE_BLOCK_1D, }; -void writeBackContact(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, SolverContext* cache); - -void writeBack1D(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, SolverContext* cache); - -void writeBackContact4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext* cache); - -void writeBack1D4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* PX_RESTRICT desc, SolverContext* cache); +void writeBackContact (DY_TGS_WRITEBACK_METHOD_PARAMS); +void writeBack1D (DY_TGS_WRITEBACK_METHOD_PARAMS); +void writeBackContact4 (DY_TGS_WRITEBACK_METHOD_PARAMS); +void writeBack1D4 (DY_TGS_WRITEBACK_METHOD_PARAMS); TGSWriteBackMethod g_WritebackTGSMethods[] = { 0, - writeBackContact, // DY_SC_TYPE_RB_CONTACT - writeBack1D, // DY_SC_TYPE_RB_1D - writeBackContact, // DY_SC_TYPE_EXT_CONTACT - writeBack1D, // DY_SC_TYPE_EXT_1D - writeBackContact, // DY_SC_TYPE_STATIC_CONTACT - writeBackContact, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - writeBackContact4, // DY_SC_TYPE_BLOCK_RB_CONTACT - writeBackContact4, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - writeBack1D4, // DY_SC_TYPE_BLOCK_1D, + writeBackContact, // DY_SC_TYPE_RB_CONTACT + writeBack1D, // DY_SC_TYPE_RB_1D + writeBackContact, // DY_SC_TYPE_EXT_CONTACT + writeBack1D, // DY_SC_TYPE_EXT_1D + writeBackContact, // DY_SC_TYPE_STATIC_CONTACT + writeBackContact, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + writeBackContact4, // DY_SC_TYPE_BLOCK_RB_CONTACT + writeBackContact4, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + writeBack1D4, // DY_SC_TYPE_BLOCK_1D, }; -void solveConclude1DBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); - -void solveConcludeContactBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); - -void solveConcludeContact4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); - -void solveConclude1D4(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); - -void solveConcludeContactExtBlock(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); - -void solveConclude1DBlockExt(const PxConstraintBatchHeader& hdr, const PxSolverConstraintDesc* desc, - const PxTGSSolverBodyTxInertia* const txInertias, const PxReal elapsedTime, SolverContext& cache); +void solveConclude1DBlock (DY_TGS_CONCLUDE_METHOD_PARAMS); +void solveConcludeContactBlock (DY_TGS_CONCLUDE_METHOD_PARAMS); +void solveConcludeContact4 (DY_TGS_CONCLUDE_METHOD_PARAMS); +void solveConclude1D4 (DY_TGS_CONCLUDE_METHOD_PARAMS); +void solveConcludeContactExtBlock (DY_TGS_CONCLUDE_METHOD_PARAMS); +void solveConclude1DBlockExt (DY_TGS_CONCLUDE_METHOD_PARAMS); TGSSolveConcludeMethod g_SolveConcludeTGSMethods[] = { 0, - solveConcludeContactBlock, // DY_SC_TYPE_RB_CONTACT - solveConclude1DBlock, // DY_SC_TYPE_RB_1D - solveConcludeContactExtBlock, // DY_SC_TYPE_EXT_CONTACT - solveConclude1DBlockExt, // DY_SC_TYPE_EXT_1D - solveConcludeContactBlock, // DY_SC_TYPE_STATIC_CONTACT - solveConcludeContactBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT - solveConcludeContact4, // DY_SC_TYPE_BLOCK_RB_CONTACT - solveConcludeContact4, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT - solveConclude1D4, // DY_SC_TYPE_BLOCK_1D, + solveConcludeContactBlock, // DY_SC_TYPE_RB_CONTACT + solveConclude1DBlock, // DY_SC_TYPE_RB_1D + solveConcludeContactExtBlock, // DY_SC_TYPE_EXT_CONTACT + solveConclude1DBlockExt, // DY_SC_TYPE_EXT_1D + solveConcludeContactBlock, // DY_SC_TYPE_STATIC_CONTACT + solveConcludeContactBlock, // DY_SC_TYPE_NOFRICTION_RB_CONTACT + solveConcludeContact4, // DY_SC_TYPE_BLOCK_RB_CONTACT + solveConcludeContact4, // DY_SC_TYPE_BLOCK_STATIC_RB_CONTACT + solveConclude1D4, // DY_SC_TYPE_BLOCK_1D, }; - - -void DynamicsTGSContext::solveConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders, - PxReal invStepDt, const PxTGSSolverBodyTxInertia* const solverTxInertia, const PxReal elapsedTime, const PxReal minPenetration, SolverContext& cache) +void DynamicsTGSContext::solveConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, + PxReal invStepDt, const PxTGSSolverBodyTxInertia* const solverTxInertia, PxReal elapsedTime, PxReal minPenetration, SolverContext& cache) { PX_UNUSED(invStepDt); - PX_UNUSED(solverTxInertia); for (PxU32 h = 0; h < nbHeaders; ++h) { const PxConstraintBatchHeader& hdr = batchHeaders[h]; g_SolveTGSMethods[hdr.constraintType](hdr, contactDescPtr, solverTxInertia, minPenetration, elapsedTime, cache); } - } template -void DynamicsTGSContext::parallelSolveConstraints(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders, - PxTGSSolverBodyTxInertia* solverTxInertia, const PxReal elapsedTime, const PxReal minPenetration, - SolverContext& cache, const PxU32 iterCount) +void DynamicsTGSContext::parallelSolveConstraints(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, + PxTGSSolverBodyTxInertia* solverTxInertia, PxReal elapsedTime, PxReal minPenetration, + SolverContext& cache, PxU32 iterCount) { - PX_UNUSED(solverTxInertia); for (PxU32 h = 0; h < nbHeaders; ++h) { const PxConstraintBatchHeader& hdr = batchHeaders[h]; @@ -1530,11 +1432,9 @@ void DynamicsTGSContext::parallelSolveConstraints(const PxSolverConstraintDesc* incrementProgress(desc); } } - } - -void DynamicsTGSContext::writebackConstraintsIteration(const PxConstraintBatchHeader* const hdrs, const PxSolverConstraintDesc* const contactDescPtr, const PxU32 nbHeaders) +void DynamicsTGSContext::writebackConstraintsIteration(const PxConstraintBatchHeader* const hdrs, const PxSolverConstraintDesc* const contactDescPtr, PxU32 nbHeaders) { PX_PROFILE_ZONE("Writeback", mContextID); @@ -1546,7 +1446,7 @@ void DynamicsTGSContext::writebackConstraintsIteration(const PxConstraintBatchHe } } -void DynamicsTGSContext::parallelWritebackConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders) +void DynamicsTGSContext::parallelWritebackConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders) { for (PxU32 h = 0; h < nbHeaders; ++h) { @@ -1556,12 +1456,10 @@ void DynamicsTGSContext::parallelWritebackConstraintsIteration(const PxSolverCon } } - - template void DynamicsTGSContext::solveConcludeConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, - const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders, PxTGSSolverBodyTxInertia* solverTxInertia, - const PxReal elapsedTime, SolverContext& cache, const PxU32 iterCount) + const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, PxTGSSolverBodyTxInertia* solverTxInertia, + PxReal elapsedTime, SolverContext& cache, PxU32 iterCount) { for (PxU32 h = 0; h < nbHeaders; ++h) { @@ -1581,8 +1479,7 @@ void DynamicsTGSContext::solveConcludeConstraintsIteration(const PxSolverConstra } } - -void integrateCoreStep(PxTGSSolverBodyVel& vel, PxTGSSolverBodyTxInertia& txInertia, const PxF32 dt) +void integrateCoreStep(PxTGSSolverBodyVel& vel, PxTGSSolverBodyTxInertia& txInertia, PxF32 dt) { PxU32 lockFlags = vel.lockFlags; if (lockFlags) @@ -1606,14 +1503,12 @@ void integrateCoreStep(PxTGSSolverBodyVel& vel, PxTGSSolverBodyTxInertia& txIner PxVec3 linearMotionVel = vel.linearVelocity; const PxVec3 delta = linearMotionVel * dt; - PxVec3 unmolestedAngVel = vel.angularVelocity; PxVec3 angularMotionVel = txInertia.sqrtInvInertia * vel.angularVelocity; PxReal w2 = angularMotionVel.magnitudeSquared(); txInertia.deltaBody2World.p += delta; PX_ASSERT(txInertia.deltaBody2World.p.isFinite()); - // Integrate the rotation using closed form quaternion integrator if (w2 != 0.0f) { @@ -1656,8 +1551,7 @@ void integrateCoreStep(PxTGSSolverBodyVel& vel, PxTGSSolverBodyTxInertia& txIner solverBodyData.deltaAngDt = vel.deltaAngDt;*/ } - -void averageVelocity(PxTGSSolverBodyVel& vel, const PxF32 invDt, const PxReal ratio) +void averageVelocity(PxTGSSolverBodyVel& vel, PxF32 invDt, PxReal ratio) { const PxVec3 frameLinVel = vel.deltaLinDt*invDt; const PxVec3 frameAngVel = vel.deltaAngDt*invDt; @@ -1671,11 +1565,10 @@ void averageVelocity(PxTGSSolverBodyVel& vel, const PxF32 invDt, const PxReal ra } } - void DynamicsTGSContext::integrateBodies(const SolverIslandObjectsStep& /*objects*/, - const PxU32 count, PxTGSSolverBodyVel* PX_RESTRICT vels, PxTGSSolverBodyTxInertia* PX_RESTRICT txInertias, + PxU32 count, PxTGSSolverBodyVel* PX_RESTRICT vels, PxTGSSolverBodyTxInertia* PX_RESTRICT txInertias, const PxTGSSolverBodyData*const PX_RESTRICT /*bodyDatas*/, PxReal dt, PxReal invTotalDt, bool average, - const PxReal ratio) + PxReal ratio) { for (PxU32 k = 0; k < count; k++) { @@ -1686,8 +1579,8 @@ void DynamicsTGSContext::integrateBodies(const SolverIslandObjectsStep& /*object } void DynamicsTGSContext::parallelIntegrateBodies(PxTGSSolverBodyVel* vels, PxTGSSolverBodyTxInertia* txInertias, - const PxTGSSolverBodyData* const /*bodyDatas*/, const PxU32 count, PxReal dt, const PxU32 iteration, PxReal invTotalDt, bool average, - const PxReal ratio) + const PxTGSSolverBodyData* const /*bodyDatas*/, PxU32 count, PxReal dt, PxU32 iteration, PxReal invTotalDt, bool average, + PxReal ratio) { PX_UNUSED(iteration); for (PxU32 k = 0; k < count; k++) @@ -1696,7 +1589,6 @@ void DynamicsTGSContext::parallelIntegrateBodies(PxTGSSolverBodyVel* vels, PxTGS integrateCoreStep(vels[k + 1], txInertias[k + 1], dt); if (average) averageVelocity(vels[k + 1], invTotalDt, ratio); - } } @@ -1728,13 +1620,11 @@ void DynamicsTGSContext::copyBackBodies(const SolverIslandObjectsStep& objects, core.linearVelocity = linearVelocity; core.angularVelocity = angularVelocity; - bool hasStaticTouch = islandSim.getIslandStaticTouchCount(PxNodeIndex(solverBodyData.nodeIndex)) != 0; - sleepCheck(&rBody, mDt, invDt, mEnableStabilization, motionVel, - hasStaticTouch); + const bool hasStaticTouch = islandSim.getIslandStaticTouchCount(PxNodeIndex(solverBodyData.nodeIndex)) != 0; + sleepCheck(&rBody, mDt, mEnableStabilization, motionVel, hasStaticTouch); } } - void DynamicsTGSContext::stepArticulations(Dy::ThreadContext& threadContext, const PxsIslandIndices& counts, PxReal dt, PxReal totalInvDt) { for (PxU32 a = 0; a < counts.articulations; ++a) @@ -1742,12 +1632,11 @@ void DynamicsTGSContext::stepArticulations(Dy::ThreadContext& threadContext, con ArticulationSolverDesc& d = threadContext.getArticulations()[a]; //if(d.articulation->numTotalConstraints > 0) //d.articulation->solveInternalConstraints(dt, 1.f / dt, threadContext.mZVector.begin(), threadContext.mDeltaV.begin(), false); - ArticulationPImpl::updateDeltaMotion(d, dt, threadContext.mDeltaV.begin(), totalInvDt); - + ArticulationPImpl::updateDeltaMotion(d, dt, threadContext.mDeltaV.begin(), totalInvDt); } } -void DynamicsTGSContext::updateArticulations(Dy::ThreadContext& threadContext, const PxU32 startIdx, const PxU32 endIdx, PxReal dt) +void DynamicsTGSContext::updateArticulations(Dy::ThreadContext& threadContext, PxU32 startIdx, PxU32 endIdx, PxReal dt) { for (PxU32 a = startIdx; a < endIdx; ++a) { @@ -1756,6 +1645,8 @@ void DynamicsTGSContext::updateArticulations(Dy::ThreadContext& threadContext, c } } +namespace +{ class ArticulationTask : public Cm::Task { Dy::DynamicsTGSContext& mContext; @@ -1769,7 +1660,7 @@ class ArticulationTask : public Cm::Task public: static const PxU32 MaxNbPerTask = 32; - ArticulationTask(Dy::DynamicsTGSContext& context, ArticulationSolverDesc* descs, const PxU32 nbDescs, const PxVec3& gravity, + ArticulationTask(Dy::DynamicsTGSContext& context, ArticulationSolverDesc* descs, PxU32 nbDescs, const PxVec3& gravity, PxReal dt, PxU64 contextId) : Cm::Task(contextId), mContext(context), mDescs(descs), mNbDescs(nbDescs), mGravity(gravity), mDt(dt) { @@ -1798,19 +1689,17 @@ class ArticulationTask : public Cm::Task const PxReal invLengthScale = 1.f / mContext.getLengthScale(); for (PxU32 a = 0; a < mNbDescs; ++a) - { - + { ArticulationPImpl::computeUnconstrainedVelocitiesTGS(mDescs[a], mDt, mGravity, getContextId(), threadContext.mZVector.begin(), threadContext.mDeltaV.begin(), invLengthScale); } mContext.putThreadContext(&threadContext); } - }; +} - -void DynamicsTGSContext::setupArticulations(IslandContextStep& islandContext, const PxVec3& gravity, const PxReal dt, PxU32& posIters, +void DynamicsTGSContext::setupArticulations(IslandContextStep& islandContext, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, PxBaseTask* continuation) { Dy::FeatherstoneArticulation** articulations = islandContext.mThreadContext->mArticulationArray; @@ -1841,15 +1730,11 @@ void DynamicsTGSContext::setupArticulations(IslandContextStep& islandContext, co task->setContinuation(continuation); task->removeReference(); - - //startIdx += descCount; - } velIters = PxMax(maxVelIters, velIters); posIters = PxMax(maxPosIters, posIters); - } PxU32 DynamicsTGSContext::setupArticulationInternalConstraints(IslandContextStep& islandContext, PxReal dt, PxReal invStepDt) @@ -1912,7 +1797,6 @@ class SetupDescsTask : public Cm::Task } }; - class PreIntegrateParallelTask : public Cm::Task { PxsBodyCore** mBodyArray; @@ -1934,7 +1818,7 @@ class PreIntegrateParallelTask : public Cm::Task PreIntegrateParallelTask(PxsBodyCore** bodyArray, PxsRigidBody** originalBodyArray, PxTGSSolverBodyVel* solverBodyVelPool, PxTGSSolverBodyTxInertia* solverBodyTxInertia, PxTGSSolverBodyData* solverBodyDataPool2, - PxU32* nodeIndexArray, const PxU32 bodyCount, const PxVec3& gravity, const PxReal dt, PxU32& posIters, PxU32& velIters, + PxU32* nodeIndexArray, PxU32 bodyCount, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, DynamicsTGSContext& context) : Cm::Task(context.getContextId()), mBodyArray(bodyArray), mOriginalBodyArray(originalBodyArray), mSolverBodyVelPool(solverBodyVelPool), mSolverBodyTxInertia(solverBodyTxInertia), mSolverBodyDataPool2(solverBodyDataPool2), mNodeIndexArray(nodeIndexArray), @@ -1952,11 +1836,9 @@ class PreIntegrateParallelTask : public Cm::Task PxAtomicMax(reinterpret_cast(&mPosIters), PxI32(posIters)); PxAtomicMax(reinterpret_cast(&mVelIters), PxI32(velIters)); - } }; - class PreIntegrateTask : public Cm::Task { PxsBodyCore** mBodyArray; @@ -1978,7 +1860,7 @@ class PreIntegrateTask : public Cm::Task PreIntegrateTask(PxsBodyCore** bodyArray, PxsRigidBody** originalBodyArray, PxTGSSolverBodyVel* solverBodyVelPool, PxTGSSolverBodyTxInertia* solverBodyTxInertia, PxTGSSolverBodyData* solverBodyDataPool2, - PxU32* nodeIndexArray, const PxU32 bodyCount, const PxVec3& gravity, const PxReal dt, PxU32& posIters, PxU32& velIters, + PxU32* nodeIndexArray, PxU32 bodyCount, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, DynamicsTGSContext& context) : Cm::Task(context.getContextId()), mBodyArray(bodyArray), mOriginalBodyArray(originalBodyArray), mSolverBodyVelPool(solverBodyVelPool), mSolverBodyTxInertia(solverBodyTxInertia), mSolverBodyDataPool2(solverBodyDataPool2), mNodeIndexArray(nodeIndexArray), @@ -2014,8 +1896,6 @@ class PreIntegrateTask : public Cm::Task task->removeReference(); } } - - } }; @@ -2084,7 +1964,7 @@ class SetupArticulationTask : public Cm::Task public: - SetupArticulationTask(IslandContextStep& islandContext, const PxVec3& gravity, const PxReal dt, PxU32& posIters, + SetupArticulationTask(IslandContextStep& islandContext, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, DynamicsTGSContext& context) : Cm::Task(context.getContextId()), mIslandContext(islandContext), mGravity(gravity), mDt(dt), mPosIters(posIters), mVelIters(velIters), mContext(context) { @@ -2148,7 +2028,7 @@ class SetupSolverConstraintsSubTask : public Cm::Task static const PxU32 MaxPerTask = 64; - SetupSolverConstraintsSubTask(PxSolverConstraintDesc* contactDescPtr, PxConstraintBatchHeader* headers, const PxU32 nbHeaders, + 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()), mContactDescPtr(contactDescPtr), mHeaders(headers), mNbHeaders(nbHeaders), mOutputs(outputs), mStepDt(stepDt), mTotalDt(totalDt), mInvStepDt(invStepDt), @@ -2167,7 +2047,6 @@ class SetupSolverConstraintsSubTask : public Cm::Task mBiasCoefficient, mVelIters); mContext.putThreadContext(tempContext); } - }; class PxsCreateArticConstraintsSubTask : public Cm::Task @@ -2239,7 +2118,6 @@ class PxsCreateArticConstraintsSubTask : public Cm::Task IslandContextStep& mIslandContext; }; - class SetupSolverConstraintsTask : public Cm::Task { IslandContextStep& mIslandContext; @@ -2254,8 +2132,6 @@ class SetupSolverConstraintsTask : public Cm::Task public: - - SetupSolverConstraintsTask(IslandContextStep& islandContext, PxSolverConstraintDesc* contactDescPtr, PxsContactManagerOutputIterator& outputs, Dy::ThreadContext& threadContext, PxReal totalDt, DynamicsTGSContext& context) : Cm::Task(context.getContextId()), mIslandContext(islandContext), mContactDescPtr(contactDescPtr), mOutputs(outputs), mThreadContext(threadContext), @@ -2304,11 +2180,10 @@ static bool isArticulationConstraint(PxSolverConstraintDesc& desc) desc.linkIndexB != PxSolverConstraintDesc::RIGID_BODY; } - class PartitionTask : public Cm::Task { IslandContextStep& mIslandContext; - PxSolverConstraintDesc* mContactDescPtr; + const PxSolverConstraintDesc* mContactDescPtr; PxTGSSolverBodyVel* mSolverBodyData; Dy::ThreadContext& mThreadContext; @@ -2318,8 +2193,6 @@ class PartitionTask : public Cm::Task public: - - PartitionTask(IslandContextStep& islandContext, PxSolverConstraintDesc* contactDescPtr, PxTGSSolverBodyVel* solverBodyData, Dy::ThreadContext& threadContext, DynamicsTGSContext& context) : Cm::Task(context.getContextId()), mIslandContext(islandContext), mContactDescPtr(contactDescPtr), mSolverBodyData(solverBodyData), mThreadContext(threadContext), @@ -2331,8 +2204,7 @@ class PartitionTask : public Cm::Task virtual void runInternal() { - - ArticulationSolverDesc* artics = mThreadContext.getArticulations().begin(); + const ArticulationSolverDesc* artics = mThreadContext.getArticulations().begin(); PxU32 totalDescCount = mThreadContext.contactDescArraySize; @@ -2353,10 +2225,10 @@ class PartitionTask : public Cm::Task args.mNumDifferentBodyConstraints = args.mNumSelfConstraints = args.mNumStaticConstraints = 0; args.mConstraintsPerPartition = &mThreadContext.mConstraintsPerPartition; args.mNumOverflowConstraints = 0; - args.mBitField = &mThreadContext.mPartitionNormalizationBitmap; - args.enhancedDeterminism = false; - args.forceStaticConstraintsToSolver = false; - args.maxPartitions = 64; + //args.mBitField = &mThreadContext.mPartitionNormalizationBitmap; // PT: removed, unused + args.mEnhancedDeterminism = false; + args.mForceStaticConstraintsToSolver = false; + args.mMaxPartitions = 64; mThreadContext.mMaxPartitions = partitionContactConstraints(args); mThreadContext.mNumDifferentBodyConstraints = args.mNumDifferentBodyConstraints; @@ -2365,7 +2237,6 @@ class PartitionTask : public Cm::Task mThreadContext.mHasOverflowPartitions = args.mNumOverflowConstraints != 0; - { PxU32 descCount = mThreadContext.mNumDifferentBodyConstraints; PxU32 selfConstraintDescCount = mThreadContext.contactDescArraySize - (mThreadContext.mNumDifferentBodyConstraints + mThreadContext.mNumStaticConstraints); @@ -2378,7 +2249,7 @@ class PartitionTask : public Cm::Task const PxU32 maxBatchPartition = 0xFFFFFFFF; - const PxU32 maxBatchSize2 = args.enhancedDeterminism ? 1u : 4u; + const PxU32 maxBatchSize2 = args.mEnhancedDeterminism ? 1u : 4u; PxConstraintBatchHeader* batchHeaders = mIslandContext.mObjects.constraintBatchHeaders; @@ -2393,8 +2264,6 @@ class PartitionTask : public Cm::Task for (PxU32 a = 0; a < descCount;) { - - PxU32 loopMax = PxMin(maxJ - a, maxBatchSize); PxU16 j = 0; if (loopMax > 0) @@ -2428,8 +2297,6 @@ class PartitionTask : public Cm::Task if (descCount) accumulatedConstraintsPerPartition[currentPartition] = headersPerPartition; - - accumulatedConstraintsPerPartition.forceSize_Unsafe(mThreadContext.mMaxPartitions); PxU32 numDifferentBodyBatchHeaders = numHeaders; @@ -2448,7 +2315,6 @@ class PartitionTask : public Cm::Task mThreadContext.numSelfConstraintBatchHeaders = numSelfConstraintBatchHeaders; mThreadContext.numContactConstraintBatches = numHeaders; } - } }; @@ -2482,7 +2348,6 @@ class ParallelSolveTask : public Cm::Task } }; - class SolveIslandTask : public Cm::Task { IslandContextStep& mIslandContext; @@ -2506,7 +2371,6 @@ class SolveIslandTask : public Cm::Task virtual void runInternal() { - PxU32 j = 0, i = 0; PxU32 numBatches = 0; @@ -2617,7 +2481,11 @@ class SolveIslandTask : public Cm::Task if (mThreadContext.mHasOverflowPartitions) { - PxU32 nbPartitionsMinusOverflow = mThreadContext.mConstraintsPerPartition.size() - 1; + // jcarius: mitigating potential divide-by-zero problem. It's unclear whether size originally includes + // the overflow partition or not. + const PxU32 size = mThreadContext.mConstraintsPerPartition.size(); + const PxU32 nbPartitionsMinusOverflow = (size > 1) ? (size - 1) : 1; + PxU32 nbConstraintsMinusOverflow = currIndex - mThreadContext.mConstraintsPerPartition[0]; nbHeadersPerPartition = ((nbConstraintsMinusOverflow + nbPartitionsMinusOverflow - 1) / nbPartitionsMinusOverflow); } @@ -2634,7 +2502,6 @@ class SolveIslandTask : public Cm::Task mIslandContext.mPosIters, mIslandContext.mVelIters, cache, PxMin(0.5f, mIslandContext.mBiasCoefficient), mIslandContext.mBiasCoefficient); else { - mIslandContext.mSharedSolverIndex = 0; mIslandContext.mSolvedCount = 0; mIslandContext.mSharedRigidBodyIndex = 0; @@ -2712,14 +2579,12 @@ class FinishSolveIslandTask : public Cm::Task } }; - - void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, ThreadContext& mThreadContext, - const PxReal stepDt, const PxReal invStepDt, const PxU32 posIters, const PxU32 velIters, SolverContext& cache, const PxReal ratio, const PxReal biasCoefficient) + PxReal stepDt, PxReal invStepDt, PxU32 posIters, PxU32 velIters, SolverContext& cache, PxReal ratio, PxReal biasCoefficient) { PX_PROFILE_ZONE("Dynamics:solveIsland", mContextID); - PxReal elapsedTime = 0.f; - PxReal recipStepDt = 1.f/stepDt; + PxReal elapsedTime = 0.0f; + const PxReal recipStepDt = 1.0f/stepDt; const PxU32 bodyOffset = objects.solverBodyOffset; @@ -2727,7 +2592,7 @@ void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& obj { for (PxU32 i = 0; i < counts.articulations; ++i) { - elapsedTime = 0.f; + elapsedTime = 0.0f; ArticulationSolverDesc& d = mThreadContext.getArticulations()[i]; for (PxU32 a = 0; a < posIters; a++) { @@ -2736,7 +2601,7 @@ void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& obj elapsedTime += stepDt; } - ArticulationPImpl::saveVelocityTGS(d, mInvDt); + ArticulationPImpl::saveVelocityTGS(d.articulation, mInvDt); d.articulation->concludeInternalConstraints(true); @@ -2746,7 +2611,6 @@ void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& obj } d.articulation->writebackInternalConstraints(true); - } integrateBodies(objects, counts.bodies, mSolverBodyVelPool.begin() + bodyOffset, mSolverBodyTxInertiaPool.begin() + bodyOffset, mSolverBodyDataPool2.begin() + bodyOffset, mDt, @@ -2754,7 +2618,6 @@ void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& obj return; } - for (PxU32 a = 1; a < posIters; a++) { solveConstraintsIteration(objects.orderedConstraintDescs, objects.constraintBatchHeaders, mThreadContext.numContactConstraintBatches, invStepDt, @@ -2796,7 +2659,7 @@ void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& obj Dy::ArticulationSolverDesc& desc = mThreadContext.getArticulations()[a]; //ArticulationPImpl::updateDeltaMotion(desc, stepDt, mThreadContext.mDeltaV.begin()); - ArticulationPImpl::saveVelocityTGS(desc, invDt); + ArticulationPImpl::saveVelocityTGS(desc.articulation, invDt); } for (PxU32 a = 0; a < velIters; ++a) @@ -2818,18 +2681,16 @@ void DynamicsTGSContext::iterativeSolveIsland(const SolverIslandObjectsStep& obj } } - void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, ThreadContext& mThreadContext, - const PxReal stepDt, const PxU32 posIters, const PxU32 velIters, PxI32* solverCounts, PxI32* integrationCounts, PxI32* articulationIntegrationCounts, + PxReal stepDt, PxU32 posIters, PxU32 velIters, PxI32* solverCounts, PxI32* integrationCounts, PxI32* articulationIntegrationCounts, PxI32* solverProgressCount, PxI32* integrationProgressCount, PxI32* articulationProgressCount, PxU32 solverUnrollSize, PxU32 integrationUnrollSize, - const PxReal ratio, const PxReal biasCoefficient) + PxReal ratio, PxReal biasCoefficient) { PX_PROFILE_ZONE("Dynamics:solveIslandParallel", mContextID); Dy::ThreadContext& threadContext = *getThreadContext(); PxU32 startSolveIdx = PxU32(PxAtomicAdd(solverCounts, PxI32(solverUnrollSize))) - solverUnrollSize; PxU32 nbSolveRemaining = solverUnrollSize; - PxU32 startIntegrateIdx = PxU32(PxAtomicAdd(integrationCounts, PxI32(integrationUnrollSize))) - integrationUnrollSize; PxU32 nbIntegrateRemaining = integrationUnrollSize; @@ -2861,9 +2722,9 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS cache.Z = threadContext.mZVector.begin(); cache.deltaV = threadContext.mDeltaV.begin(); - PxReal elapsedTime = 0.f; + PxReal elapsedTime = 0.0f; - PxReal invStepDt = 1.f/ stepDt; + PxReal invStepDt = 1.0f/ stepDt; const bool overflow = mThreadContext.mHasOverflowPartitions; @@ -2927,7 +2788,6 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS WAIT_FOR_PROGRESS(solverProgressCount, PxI32(targetSolverProgressCount)); - PxU32 integStartIdx = startIntegrateIdx - targetIntegrationProgressCount; PxU32 nbIntegrated = 0; @@ -2977,18 +2837,12 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS PxAtomicAdd(articulationProgressCount, PxI32(nbArticsProcessed)); elapsedTime += stepDt; - - - } { WAIT_FOR_PROGRESS(integrationProgressCount, PxI32(targetIntegrationProgressCount)); WAIT_FOR_PROGRESS(articulationProgressCount, PxI32(targetArticulationProgressCount)); - WAIT_FOR_PROGRESS(articulationProgressCount, PxI32(targetArticulationProgressCount)); - - PxU32 offset = 0; for (PxU32 b = 0; b < nbPartitions; ++b) { @@ -3027,15 +2881,12 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS targetSolverProgressCount += nbBatches; offset += nbBatches; - - } iterCount++; WAIT_FOR_PROGRESS(solverProgressCount, PxI32(targetSolverProgressCount)); - const PxReal invDt = mInvDt; //const PxReal invDtPt25 = mInvDt * 0.25f; PxU32 integStartIdx = startIntegrateIdx - targetIntegrationProgressCount; @@ -3078,7 +2929,7 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS d.articulation->concludeInternalConstraints(true); ArticulationPImpl::updateDeltaMotion(d, stepDt, cache.deltaV, mInvDt); - ArticulationPImpl::saveVelocityTGS(d, invDt); + ArticulationPImpl::saveVelocityTGS(d.articulation, invDt); nbArticsProcessed++; @@ -3102,7 +2953,6 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS WAIT_FOR_PROGRESS(integrationProgressCount, PxI32(targetIntegrationProgressCount)); WAIT_FOR_PROGRESS(articulationProgressCount, PxI32(targetArticulationProgressCount)); - for (PxU32 a = 0; a < velIters; ++a) { WAIT_FOR_PROGRESS(solverProgressCount, PxI32(targetSolverProgressCount)); @@ -3135,7 +2985,6 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS nbSolved += nbToSolve; - if (nbSolveRemaining == 0) { startSolveIdx = PxU32(PxAtomicAdd(solverCounts, PxI32(solverUnrollSize))) - solverUnrollSize; @@ -3183,8 +3032,7 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS WAIT_FOR_PROGRESS(articulationProgressCount, PxI32(targetArticulationProgressCount)); } - { - + { { //Find the startIdx in the partition to process PxU32 startIdx = startSolveIdx - targetSolverProgressCount; @@ -3215,9 +3063,7 @@ void DynamicsTGSContext::iterativeSolveIslandParallel(const SolverIslandObjectsS targetSolverProgressCount += nbBatches; } - } - } class CopyBackTask : public Cm::Task @@ -3279,7 +3125,6 @@ class UpdateArticTask : public Cm::Task } }; - void DynamicsTGSContext::finishSolveIsland(ThreadContext& mThreadContext, const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, IG::SimpleIslandManager& islandManager, PxBaseTask* continuation) { @@ -3311,16 +3156,14 @@ void DynamicsTGSContext::finishSolveIsland(ThreadContext& mThreadContext, const } } - void DynamicsTGSContext::endIsland(ThreadContext& mThreadContext) { putThreadContext(&mThreadContext); } - void DynamicsTGSContext::solveIsland(const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, - const PxU32 solverBodyOffset, + PxU32 solverBodyOffset, IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, PxsMaterialManager* /*materialManager*/, PxsContactManagerOutputIterator& iterator, @@ -3336,7 +3179,6 @@ void DynamicsTGSContext::solveIsland(const SolverIslandObjectsStep& objects, islandContext.mVelIters = 0; islandContext.mObjects.solverBodyOffset = solverBodyOffset; - prepareBodiesAndConstraints(islandContext.mObjects, islandManager, islandContext); ////Create task chain... @@ -3391,17 +3233,10 @@ void DynamicsTGSContext::solveIsland(const SolverIslandObjectsStep& objects, descTask->removeReference(); } -void DynamicsTGSContext::updateBodyCore(PxBaseTask* continuation) -{ - PX_UNUSED(continuation); -} - void DynamicsTGSContext::mergeResults() { } - - } } diff --git a/physx/source/lowleveldynamics/src/DyTGSDynamics.h b/physx/source/lowleveldynamics/src/DyTGSDynamics.h index 8dfeb723e..7b87e87ce 100644 --- a/physx/source/lowleveldynamics/src/DyTGSDynamics.h +++ b/physx/source/lowleveldynamics/src/DyTGSDynamics.h @@ -45,7 +45,6 @@ namespace physx { - namespace Cm { class FlushPool; @@ -54,7 +53,6 @@ namespace physx namespace IG { class SimpleIslandManager; - struct Edge; } class PxsRigidBody; @@ -64,17 +62,8 @@ namespace physx struct PxsIndexedInteraction; struct PxsIndexedContactManager; - namespace Cm - { - class SpatialVector; - } - namespace Dy { - class SolverCore; - struct SolverIslandParams; - struct ArticulationSolverDesc; - class DynamicsContext; struct SolverContext; struct SolverIslandObjectsStep @@ -160,135 +149,61 @@ namespace physx #pragma warning( disable : 4324 ) // Padding was added at the end of a structure because of a __declspec(align) value. #endif - class DynamicsTGSContext : public Context - { - PX_NOCOPY(DynamicsTGSContext) - public: - - /**PxBaseTask* continuation - \brief Creates a DynamicsContext associated with a PxsContext - \return A pointer to the newly-created DynamicsContext. - */ - static DynamicsTGSContext* create(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocator, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal lengthScale - ); - - /** - \brief Destroys this DynamicsContext - */ - void destroy(); - - /** - \brief Returns the static world solver body - \return The static world solver body. - */ - //PX_FORCE_INLINE PxSolverBody& getWorldSolverBody() { return mWorldSolverBody; } - - PX_FORCE_INLINE Cm::FlushPool& getTaskPool() { return mTaskPool; } - - PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; } - - PX_FORCE_INLINE PxvSimStats& getSimStats() { return mSimStats; } - -#if PX_ENABLE_SIM_STATS - void addThreadStats(const ThreadContext::ThreadSimStats& stats); +class DynamicsTGSContext : public Context +{ + PX_NOCOPY(DynamicsTGSContext) +public: + DynamicsTGSContext(PxcNpMemBlockPool* memBlockPool, + PxcScratchAllocator& scratchAllocator, + Cm::FlushPool& taskPool, + PxvSimStats& simStats, + PxTaskManager* taskManager, + PxVirtualAllocatorCallback* allocator, + PxsMaterialManager* materialManager, + IG::SimpleIslandManager* islandManager, + PxU64 contextID, + bool enableStabilization, + bool useEnhancedDeterminism, + PxReal lengthScale + ); + + virtual ~DynamicsTGSContext(); + + // Context + virtual void destroy() PX_OVERRIDE; + virtual void update(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, + PxvNphaseImplementationContext* nphase, PxU32 maxPatchesPerCM, PxU32 maxArticulationLinks, PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap) PX_OVERRIDE; + virtual void mergeResults() PX_OVERRIDE; + virtual void setSimulationController(PxsSimulationController* simulationController) PX_OVERRIDE { mSimulationController = simulationController; } + virtual PxSolverType::Enum getSolverType() const PX_OVERRIDE { return PxSolverType::eTGS; } + //~Context + + /** + \brief Allocates and returns a thread context object. + \return A thread context. + */ + PX_FORCE_INLINE ThreadContext* getThreadContext() { return mThreadContextPool.get(); } + + /** + \brief Returns a thread context to the thread context pool. + \param[in] context The thread context to return to the thread context pool. + */ + void putThreadContext(ThreadContext* context) { mThreadContextPool.put(context); } + + PX_FORCE_INLINE Cm::FlushPool& getTaskPool() { return mTaskPool; } + PX_FORCE_INLINE ThresholdStream& getThresholdStream() { return *mThresholdStream; } + PX_FORCE_INLINE PxvSimStats& getSimStats() { return mSimStats; } + PX_FORCE_INLINE PxU32 getKinematicCount() const { return mKinematicCount; } + + void updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, PxU32 maxLinks); +protected: + + // PT: TODO: the thread stats are missing for TGS +/*#if PX_ENABLE_SIM_STATS + void addThreadStats(const ThreadContext::ThreadSimStats& stats); #else - PX_CATCH_UNDEFINED_ENABLE_SIM_STATS -#endif - - /** - \brief The entry point for the constraint solver. - \param[in] dt The simulation time-step - \param[in] continuation The continuation task for the solver - - This method is called after the island generation has completed. Its main responsibilities are: - (1) Reserving the solver body pools - (2) Initializing the static and kinematic solver bodies, which are shared resources between islands. - (3) Construct the solver task chains for each island - - Each island is solved as an independent solver task chain in parallel. - - */ - - virtual void update(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, PxBaseTask* lostTouchTask, - PxvNphaseImplementationContext* nphase, - const PxU32 maxPatchesPerCM, const PxU32 maxArticulationLinks, const PxReal dt, const PxVec3& gravity, PxBitMapPinned& changedHandleMap); - - void updatePostKinematic(IG::SimpleIslandManager& simpleIslandManager, PxBaseTask* continuation, - PxBaseTask* lostTouchTask, const PxU32 maxLinks); - - virtual void processLostPatches(IG::SimpleIslandManager& /*simpleIslandManager*/, PxsContactManager** /*lostPatchManagers*/, PxU32 /*nbLostPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/){} - virtual void processFoundPatches(IG::SimpleIslandManager& /*simpleIslandManager*/, PxsContactManager** /*foundPatchManagers*/, PxU32 /*nbFoundPatchManagers*/, PxsContactManagerOutputCounts* /*outCounts*/) {} - - virtual void updateBodyCore(PxBaseTask* continuation); - - virtual void setSimulationController(PxsSimulationController* simulationController){ mSimulationController = simulationController; } - /** - \brief This method combines the results of several islands, e.g. constructing scene-level simulation statistics and merging together threshold streams for contact notification. - */ - virtual void mergeResults(); - - virtual void getDataStreamBase(void*& /*contactStreamBase*/, void*& /*patchStreamBase*/, void*& /*forceAndIndicesStreamBase*/){} - - virtual PxSolverType::Enum getSolverType() const { return PxSolverType::eTGS; } - - /** - \brief Allocates and returns a thread context object. - \return A thread context. - */ - PX_FORCE_INLINE ThreadContext* getThreadContext() - { - return mThreadContextPool.get(); - } - - /** - \brief Returns a thread context to the thread context pool. - \param[in] context The thread context to return to the thread context pool. - */ - void putThreadContext(ThreadContext* context) - { - mThreadContextPool.put(context); - } - - - PX_FORCE_INLINE PxU32 getKinematicCount() const { return mKinematicCount; } - PX_FORCE_INLINE PxU64 getContextId() const { return mContextID; } - - PX_FORCE_INLINE PxReal getLengthScale() const { return mLengthScale; } - - protected: - - /** - \brief Constructor for DynamicsContext - */ - DynamicsTGSContext(PxcNpMemBlockPool* memBlockPool, - PxcScratchAllocator& scratchAllocator, - Cm::FlushPool& taskPool, - PxvSimStats& simStats, - PxTaskManager* taskManager, - PxVirtualAllocatorCallback* allocator, - PxsMaterialManager* materialManager, - IG::SimpleIslandManager* islandManager, - PxU64 contextID, - const bool enableStabilization, - const bool useEnhancedDeterminism, - const PxReal lengthScale - ); - /** - \brief Destructor for DynamicsContext - */ - virtual ~DynamicsTGSContext(); - + PX_CATCH_UNDEFINED_ENABLE_SIM_STATS +#endif*/ // Solver helper-methods /** @@ -303,16 +218,16 @@ namespace physx \param[in] constraint The PxsIndexedInteraction */ void setDescFromIndices(PxSolverConstraintDesc& desc, const IG::IslandSim& islandSim, - const PxsIndexedInteraction& constraint, const PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies); + const PxsIndexedInteraction& constraint, PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies); void setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeIndex edgeIndex, - const IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, const PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies); + const IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, PxU32 solverBodyOffset, PxTGSSolverBodyVel* solverBodies); void solveIsland(const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, - const PxU32 solverBodyOffset, + PxU32 solverBodyOffset, IG::SimpleIslandManager& islandManager, PxU32* bodyRemapTable, PxsMaterialManager* materialManager, PxsContactManagerOutputIterator& iterator, @@ -327,57 +242,57 @@ namespace physx void preIntegrateBodies(PxsBodyCore** bodyArray, PxsRigidBody** originalBodyArray, PxTGSSolverBodyVel* solverBodyVelPool, PxTGSSolverBodyTxInertia* solverBodyTxInertia, PxTGSSolverBodyData* solverBodyDataPool2, - PxU32* nodeIndexArray, const PxU32 bodyCount, const PxVec3& gravity, const PxReal dt, PxU32& posIters, PxU32& velIters, PxU32 iteration); + PxU32* nodeIndexArray, PxU32 bodyCount, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, PxU32 iteration); - void setupArticulations(IslandContextStep& islandContext, const PxVec3& gravity, const PxReal dt, PxU32& posIters, PxU32& velIters, PxBaseTask* continuation); + void setupArticulations(IslandContextStep& islandContext, const PxVec3& gravity, PxReal dt, PxU32& posIters, PxU32& velIters, PxBaseTask* continuation); PxU32 setupArticulationInternalConstraints(IslandContextStep& islandContext, PxReal dt, PxReal invStepDt); - void createSolverConstraints(PxSolverConstraintDesc* contactDescPtr, PxConstraintBatchHeader* headers, const PxU32 nbHeaders, + void 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); + PxReal invStepDt, PxReal biasCoefficient, PxI32 velIters); - void solveConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders, PxReal invStepDt, - const PxTGSSolverBodyTxInertia* const solverTxInertia, const PxReal elapsedTime, const PxReal minPenetration, SolverContext& cache); + void solveConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, PxReal invStepDt, + const PxTGSSolverBodyTxInertia* const solverTxInertia, PxReal elapsedTime, PxReal minPenetration, SolverContext& cache); template - void solveConcludeConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders, - PxTGSSolverBodyTxInertia* solverTxInertia, const PxReal elapsedTime, SolverContext& cache, const PxU32 iterCount); + void solveConcludeConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, + PxTGSSolverBodyTxInertia* solverTxInertia, PxReal elapsedTime, SolverContext& cache, PxU32 iterCount); template - void parallelSolveConstraints(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders, PxTGSSolverBodyTxInertia* solverTxInertia, - const PxReal elapsedTime, const PxReal minPenetration, SolverContext& cache, const PxU32 iterCount); + void parallelSolveConstraints(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, PxTGSSolverBodyTxInertia* solverTxInertia, + PxReal elapsedTime, PxReal minPenetration, SolverContext& cache, PxU32 iterCount); - void writebackConstraintsIteration(const PxConstraintBatchHeader* const hdrs, const PxSolverConstraintDesc* const contactDescPtr, const PxU32 nbHeaders); + void writebackConstraintsIteration(const PxConstraintBatchHeader* const hdrs, const PxSolverConstraintDesc* const contactDescPtr, PxU32 nbHeaders); - void parallelWritebackConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, const PxU32 nbHeaders); + void parallelWritebackConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders); void integrateBodies(const SolverIslandObjectsStep& objects, - const PxU32 count, PxTGSSolverBodyVel* vels, + PxU32 count, PxTGSSolverBodyVel* vels, PxTGSSolverBodyTxInertia* txInertias, const PxTGSSolverBodyData*const bodyDatas, PxReal dt, PxReal invTotalDt, bool averageBodies, - const PxReal ratio); + PxReal ratio); void parallelIntegrateBodies(PxTGSSolverBodyVel* vels, PxTGSSolverBodyTxInertia* txInertias, - const PxTGSSolverBodyData* const bodyDatas, const PxU32 count, PxReal dt, const PxU32 iteration, PxReal invTotalDt, bool average, - const PxReal ratio); + const PxTGSSolverBodyData* const bodyDatas, PxU32 count, PxReal dt, PxU32 iteration, PxReal invTotalDt, bool average, + PxReal ratio); void copyBackBodies(const SolverIslandObjectsStep& objects, PxTGSSolverBodyVel* vels, PxTGSSolverBodyTxInertia* txInertias, PxTGSSolverBodyData* solverBodyData, PxReal invDt, IG::IslandSim& islandSim, PxU32 startIdx, PxU32 endIdx); - void updateArticulations(Dy::ThreadContext& threadContext, const PxU32 startIdx, const PxU32 endIdx, PxReal dt); + void updateArticulations(Dy::ThreadContext& threadContext, PxU32 startIdx, PxU32 endIdx, PxReal dt); void stepArticulations(Dy::ThreadContext& threadContext, const PxsIslandIndices& counts, PxReal dt, PxReal stepInvDt); void iterativeSolveIsland(const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, ThreadContext& mThreadContext, - const PxReal stepDt, const PxReal invStepDt, const PxU32 posIters, const PxU32 velIters, SolverContext& cache, const PxReal ratio, - const PxReal biasCoefficient); + PxReal stepDt, PxReal invStepDt, PxU32 posIters, PxU32 velIters, SolverContext& cache, PxReal ratio, + PxReal biasCoefficient); void iterativeSolveIslandParallel(const SolverIslandObjectsStep& objects, const PxsIslandIndices& counts, ThreadContext& mThreadContext, - const PxReal stepDt, const PxU32 posIters, const PxU32 velIters, PxI32* solverCounts, PxI32* integrationCounts, PxI32* articulationIntegrationCounts, + PxReal stepDt, PxU32 posIters, PxU32 velIters, PxI32* solverCounts, PxI32* integrationCounts, PxI32* articulationIntegrationCounts, PxI32* solverProgressCount, PxI32* integrationProgressCount, PxI32* articulationProgressCount, PxU32 solverUnrollSize, PxU32 integrationUnrollSize, - const PxReal ratio, const PxReal biasCoefficient); + PxReal ratio, PxReal biasCoefficient); void endIsland(ThreadContext& mThreadContext); @@ -443,7 +358,6 @@ namespace physx SolverBodyDataStepPool mSolverBodyDataPool2; - ThresholdStream* mExceededForceThresholdStream[2]; //this store previous and current exceeded force thresholdStream PxArray mExceededForceThresholdStreamMask; @@ -475,8 +389,6 @@ namespace physx PxTaskManager* mTaskManager; PxU32 mCurrentIndex; // this is the index point to the current exceeded force threshold stream - PxU64 mContextID; - friend class SetupDescsTask; friend class PreIntegrateTask; friend class SetupArticulationTask; diff --git a/physx/source/physx/src/NpActor.cpp b/physx/source/physx/src/NpActor.cpp index 4da463ec2..d511e0c6c 100644 --- a/physx/source/physx/src/NpActor.cpp +++ b/physx/source/physx/src/NpActor.cpp @@ -53,20 +53,20 @@ using namespace physx; /////////////////////////////////////////////////////////////////////////////// -Sc::BodyCore* physx::getBodyCore(PxRigidActor* actor) +const Sc::BodyCore* physx::getBodyCore(const PxRigidActor* actor) { - Sc::BodyCore* core = NULL; + const Sc::BodyCore* core = NULL; if(actor) { const PxType type = actor->getConcreteType(); if(type == PxConcreteType::eRIGID_DYNAMIC) { - NpRigidDynamic* dyn = static_cast(actor); + const NpRigidDynamic* dyn = static_cast(actor); core = &dyn->getCore(); } else if(type == PxConcreteType::eARTICULATION_LINK) { - NpArticulationLink* link = static_cast(actor); + const NpArticulationLink* link = static_cast(actor); core = &link->getCore(); } } @@ -414,7 +414,7 @@ void NpActor::scSetDominanceGroup(PxDominanceGroup v) PX_ASSERT(!isAPIWriteForbidden()); getActorCore().setDominanceGroup(v); UPDATE_PVD_PROPERTY - OMNI_PVD_SET(actor, dominance, *getPxActor(), v) + OMNI_PVD_SET(PxActor, dominance, *getPxActor(), v) } void NpActor::scSetOwnerClient(PxClientID inId) @@ -423,7 +423,7 @@ void NpActor::scSetOwnerClient(PxClientID inId) PX_ASSERT(!isAPIWriteForbidden()); getActorCore().setOwnerClient(inId); UPDATE_PVD_PROPERTY - OMNI_PVD_SET(actor, ownerClient, *getPxActor(), inId) + OMNI_PVD_SET(PxActor, ownerClient, *getPxActor(), inId) } const PxActor* NpActor::getPxActor() const @@ -463,7 +463,6 @@ NpActor::Offsets::Offsets() #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION pxActorToNpActor[PxConcreteType::eFLIP_PARTICLESYSTEM] = size_t(pxToNpActor(n)) - addr; pxActorToNpActor[PxConcreteType::eMPM_PARTICLESYSTEM] = size_t(pxToNpActor(n)) - addr; - pxActorToNpActor[PxConcreteType::eCUSTOM_PARTICLESYSTEM] = size_t(pxToNpActor(n)) - addr; pxActorToNpActor[PxConcreteType::eFEM_CLOTH] = size_t(pxToNpActor(n)) - addr; pxActorToNpActor[PxConcreteType::eHAIR_SYSTEM] = size_t(pxToNpActor(n)) - addr; #endif @@ -537,14 +536,6 @@ NpActor::NpOffsets::NpOffsets() npToSc[NpType::eMPM_PARTICLESYSTEM] = bodyOffset; } - { - size_t addr = 0x100; // casting the null ptr takes a special-case code path, which we don't want - NpCustomParticleSystem* n = reinterpret_cast(addr); - const size_t npOffset = size_t(static_cast(n)) - addr; - const size_t bodyOffset = NpCustomParticleSystem::getCoreOffset() - npOffset; - npToSc[NpType::eCUSTOM_PARTICLESYSTEM] = bodyOffset; - } - { size_t addr = 0x100; // casting the null ptr takes a special-case code path, which we don't want NpHairSystem* n = reinterpret_cast(addr); diff --git a/physx/source/physx/src/NpActor.h b/physx/source/physx/src/NpActor.h index c6f115f49..40e897a1f 100644 --- a/physx/source/physx/src/NpActor.h +++ b/physx/source/physx/src/NpActor.h @@ -39,17 +39,15 @@ namespace physx class NpScene; class NpShape; - Sc::BodyCore* getBodyCore(PxRigidActor* actor); + const Sc::BodyCore* getBodyCore(const PxRigidActor* actor); + PX_FORCE_INLINE Sc::BodyCore* getBodyCore(PxRigidActor* actor) + { + const Sc::BodyCore* core = getBodyCore(static_cast(actor)); + return const_cast(core); + } class NpActor : public NpBase { -//= 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. -//================================================================================================== - public: // PX_SERIALIZATION NpActor(const PxEMPTY) : NpBase(PxEmpty) {} diff --git a/physx/source/physx/src/NpActorTemplate.h b/physx/source/physx/src/NpActorTemplate.h index a1a8e829f..b94e18e82 100644 --- a/physx/source/physx/src/NpActorTemplate.h +++ b/physx/source/physx/src/NpActorTemplate.h @@ -52,12 +52,6 @@ See comments for PX_BINARY_SERIAL_VERSION. template class NpActorTemplate : public APIClass, public NpActor { -//= 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(NpActorTemplate) public: // PX_SERIALIZATION diff --git a/physx/source/physx/src/NpAggregate.cpp b/physx/source/physx/src/NpAggregate.cpp index 2bb1b8968..7de05f9dd 100644 --- a/physx/source/physx/src/NpAggregate.cpp +++ b/physx/source/physx/src/NpAggregate.cpp @@ -36,6 +36,7 @@ #include "NpArticulationReducedCoordinate.h" using namespace physx; +using namespace Gu; namespace { @@ -61,9 +62,9 @@ namespace npScene->getScenePvdClientInternal().updatePvdProperties( pAggregate ); } #else -#define PvdAttachActorToAggregate(aggregate, scActor) {} -#define PvdDetachActorFromAggregate(aggregate, scActor) {} -#define PvdUpdateProperties(aggregate) {} + #define PvdAttachActorToAggregate(aggregate, scActor) {} + #define PvdDetachActorFromAggregate(aggregate, scActor) {} + #define PvdUpdateProperties(aggregate) {} #endif } @@ -101,6 +102,30 @@ NpAggregate::~NpAggregate() PX_FREE(mActors); } +void NpAggregate::scAddActor(NpActor& actor) +{ + PX_ASSERT(!isAPIWriteForbidden()); + + actor.getActorCore().setAggregateID(mAggregateID); + PvdAttachActorToAggregate( this, &actor ); + PvdUpdateProperties( this ); +} + +void NpAggregate::scRemoveActor(NpActor& actor, bool reinsert) +{ + PX_ASSERT(!isAPIWriteForbidden()); + + Sc::ActorCore& ac = actor.getActorCore(); + ac.setAggregateID(PX_INVALID_U32); + + if(getNpScene() && reinsert) + ac.reinsertShapes(); + + //Update pvd status + PvdDetachActorFromAggregate( this, &actor ); + PvdUpdateProperties( this ); +} + void NpAggregate::removeAndReinsert(PxActor& actor, bool reinsert) { NpActor& np = NpActor::getFromPxActor(actor); @@ -121,11 +146,9 @@ void NpAggregate::release() NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, NULL); - /* - "An aggregate should be empty when it gets released. If it isn't, the behavior should be: remove the actors from - the aggregate, then remove the aggregate from the scene (if any) then delete it. I guess that implies the actors - get individually reinserted into the broad phase if the aggregate is in a scene." - */ + // "An aggregate should be empty when it gets released. If it isn't, the behavior should be: remove the actors from + // the aggregate, then remove the aggregate from the scene (if any) then delete it. I guess that implies the actors + // get individually reinserted into the broad phase if the aggregate is in a scene." for(PxU32 i=0;igetType() == PxActorType::eARTICULATION_LINK) @@ -172,6 +195,29 @@ void NpAggregate::addActorInternal(PxActor& actor, NpScene& s, const PxBVH* bvh) } } +void NpAggregate::addToScene(NpScene& scene) +{ + const PxU32 nb = mNbActors; + + for(PxU32 i=0;i(NpConnectorType::eBvh, &bvh, 1)) + npActor.removeConnector(actor, NpConnectorType::eBvh, bvh, "PxBVH connector could not have been removed!"); + + addActorInternal(actor, scene, bvh); + + // if a bvh was used dec ref count, we increased the ref count when adding the actor connection + if(bvh) + bvh->decRefCount(); + } +} + bool NpAggregate::addActor(PxActor& actor, const PxBVH* bvh) { NpScene* npScene = getNpScene(); @@ -225,7 +271,7 @@ bool NpAggregate::addActor(PxActor& actor, const PxBVH* bvh) mNbShapes += numShapes; - OMNI_PVD_ADD(aggregate, actors, static_cast(*this), actor); + OMNI_PVD_ADD(PxAggregate, actors, static_cast(*this), actor); // PT: when an object is added to a aggregate at runtime, i.e. when the aggregate has already been added to the scene, // we need to immediately add the newcomer to the scene as well. @@ -239,7 +285,7 @@ bool NpAggregate::addActor(PxActor& actor, const PxBVH* bvh) if(bvh) { PxBVH* bvhMutable = const_cast(bvh); - static_cast(bvhMutable)->incRefCount(); + static_cast(bvhMutable)->incRefCount(); NpActor::getFromPxActor(actor).addConnector(NpConnectorType::eBvh, bvhMutable, "PxBVH already added to the PxActor!"); } } @@ -281,15 +327,15 @@ bool NpAggregate::removeActor(PxActor& actor) if(!npScene) { NpActor& np = NpActor::getFromPxActor(actor); - Gu::BVH* bvh = NULL; - if(np.getConnectors(NpConnectorType::eBvh, &bvh, 1)) + BVH* bvh = NULL; + if(np.getConnectors(NpConnectorType::eBvh, &bvh, 1)) { np.removeConnector(actor, NpConnectorType::eBvh, bvh, "PxBVH connector could not have been removed!"); bvh->decRefCount(); } } - OMNI_PVD_REMOVE(aggregate, actors, static_cast(*this), actor); + OMNI_PVD_REMOVE(PxAggregate, actors, static_cast(*this), actor); // PT: there are really 2 cases here: // a) the user just wants to remove the actor from the aggregate, but the actor is still alive so if the aggregate has been added to a scene, @@ -313,7 +359,8 @@ bool NpAggregate::addArticulation(PxArticulationReducedCoordinate& art) if((mNbActors+art.getNbLinks()) > mMaxNbActors) return outputError(__LINE__, "PxAggregate: can't add articulation links, max number of actors reached"); - if((mNbShapes + art.getNbShapes()) > mMaxNbShapes) + const PxU32 numShapes = art.getNbShapes(); + if((mNbShapes + numShapes) > mMaxNbShapes) return outputError(__LINE__, "PxAggregate: can't add articulation, max number of shapes reached"); if(art.getAggregate()) @@ -337,6 +384,8 @@ bool NpAggregate::addArticulation(PxArticulationReducedCoordinate& art) scAddActor(l); } + mNbShapes += numShapes; + // PT: when an object is added to a aggregate at runtime, i.e. when the aggregate has already been added to the scene, // we need to immediately add the newcomer to the scene as well. if(npScene) @@ -485,30 +534,6 @@ void NpAggregate::requiresObjects(PxProcessPxBaseCallback& c) } // ~PX_SERIALIZATION -void NpAggregate::scAddActor(NpActor& actor) -{ - PX_ASSERT(!isAPIWriteForbidden()); - - actor.getActorCore().setAggregateID(mAggregateID); - PvdAttachActorToAggregate( this, &actor ); - PvdUpdateProperties( this ); -} - -void NpAggregate::scRemoveActor(NpActor& actor, bool reinsert) -{ - PX_ASSERT(!isAPIWriteForbidden()); - - Sc::ActorCore& ac = actor.getActorCore(); - ac.setAggregateID(PX_INVALID_U32); - - if(getNpScene() && reinsert) - ac.reinsertShapes(); - - //Update pvd status - PvdDetachActorFromAggregate( this, &actor ); - PvdUpdateProperties( this ); -} - void NpAggregate::incShapeCount() { if(mNbShapes == mMaxNbShapes) @@ -516,6 +541,7 @@ void NpAggregate::incShapeCount() mNbShapes++; } + void NpAggregate::decShapeCount() { PX_ASSERT(mNbShapes > 0); diff --git a/physx/source/physx/src/NpAggregate.h b/physx/source/physx/src/NpAggregate.h index d7dfc0dd1..e65cdad52 100644 --- a/physx/source/physx/src/NpAggregate.h +++ b/physx/source/physx/src/NpAggregate.h @@ -38,12 +38,6 @@ class NpScene; class NpAggregate : public PxAggregate, public NpBase { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpAggregate(PxBaseFlags baseFlags) : PxAggregate(baseFlags), NpBase(PxEmpty) {} @@ -81,13 +75,10 @@ class NpAggregate : public PxAggregate, public NpBase PX_FORCE_INLINE bool getSelfCollideFast() const { return PxGetAggregateSelfCollisionBit(mFilterHint)!=0; } PX_FORCE_INLINE PxAggregateFilterHint getFilterHint() const { return mFilterHint; } - void addActorInternal(PxActor& actor, NpScene& s, const PxBVH* bvh); - void removeAndReinsert(PxActor& actor, bool reinsert); + void scRemoveActor(NpActor& actor, bool reinsert); bool removeActorAndReinsert(PxActor& actor, bool reinsert); bool removeArticulationAndReinsert(PxArticulationReducedCoordinate& art, bool reinsert); - - void scAddActor(NpActor&); - void scRemoveActor(NpActor& actor, bool reinsert); + void addToScene(NpScene& scene); void incShapeCount(); void decShapeCount(); @@ -99,6 +90,10 @@ class NpAggregate : public PxAggregate, public NpBase PxU32 mNbActors; PxU32 mNbShapes; PxActor** mActors; + + void scAddActor(NpActor&); + void removeAndReinsert(PxActor& actor, bool reinsert); + void addActorInternal(PxActor& actor, NpScene& s, const PxBVH* bvh); }; } diff --git a/physx/source/physx/src/NpArticulationJointReducedCoordinate.cpp b/physx/source/physx/src/NpArticulationJointReducedCoordinate.cpp index 134732957..95d7cfb58 100644 --- a/physx/source/physx/src/NpArticulationJointReducedCoordinate.cpp +++ b/physx/source/physx/src/NpArticulationJointReducedCoordinate.cpp @@ -83,10 +83,7 @@ namespace physx } PX_CHECK_AND_RETURN(jointType != PxArticulationJointType::eUNDEFINED, "PxArticulationJointReducedCoordinate::setJointType valid joint type(ePRISMATIC, eREVOLUTE, eREVOLUTE_UNWRAPPED, eSPHERICAL, eFIX) need to be set"); -#if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; - OMNI_PVD_SET(articulationjoint, type, joint, jointType) -#endif + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, type, static_cast(*this), jointType) scSetJointType(jointType); } @@ -170,11 +167,10 @@ namespace physx scSetMotion(axis, motion); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; PxArticulationMotion::Enum motions[6]; for (PxU32 ax = 0; ax < 6; ++ax) motions[ax] = mCore.getMotion(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, motion, joint, motions, sizeof(motions)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, motion, static_cast(*this), motions, sizeof(motions)); #endif static_cast(&getChild().getArticulation())->mTopologyChanged = true; @@ -191,10 +187,7 @@ namespace physx PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationJointReducedCoordinate::setFrictionCoefficient() not allowed while simulation is running. Call will be ignored.") -#if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; - OMNI_PVD_SET(articulationjoint, frictionCoefficient, joint, coefficient); -#endif + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, frictionCoefficient, static_cast(*this), coefficient); scSetFrictionCoefficient(coefficient); } @@ -212,10 +205,7 @@ namespace physx PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationJointReducedCoordinate::setMaxJointVelocity() not allowed while simulation is running. Call will be ignored.") -#if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; - OMNI_PVD_SET(articulationjoint, maxJointVelocity, joint, maxJointV); -#endif + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, maxJointVelocity, static_cast(*this), maxJointV); scSetMaxJointVelocity(maxJointV); } @@ -239,14 +229,14 @@ namespace physx scSetLimit(axis, pair); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; + PxArticulationJointReducedCoordinate& joint = *this; PxReal limits[6]; for (PxU32 ax = 0; ax < 6; ++ax) limits[ax] = mCore.getLimit(static_cast(ax)).low; - OMNI_PVD_SETB(articulationjoint, limitLow, joint, limits, sizeof(limits)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, limitLow, joint, limits, sizeof(limits)); for (PxU32 ax = 0; ax < 6; ++ax) limits[ax] = mCore.getLimit(static_cast(ax)).high; - OMNI_PVD_SETB(articulationjoint, limitHigh, joint, limits, sizeof(limits)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, limitHigh, joint, limits, sizeof(limits)); #endif } @@ -265,23 +255,23 @@ namespace physx scSetDrive(axis, drive); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; + PxArticulationJointReducedCoordinate& joint = *this; PxReal stiffnesss[6]; for (PxU32 ax = 0; ax < 6; ++ax) stiffnesss[ax] = mCore.getDrive(static_cast(ax)).stiffness; - OMNI_PVD_SETB(articulationjoint, driveStiffness, joint, stiffnesss, sizeof(stiffnesss)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveStiffness, joint, stiffnesss, sizeof(stiffnesss)); PxReal dampings[6]; for (PxU32 ax = 0; ax < 6; ++ax) dampings[ax] = mCore.getDrive(static_cast(ax)).damping; - OMNI_PVD_SETB(articulationjoint, driveDamping, joint, dampings, sizeof(dampings)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveDamping, joint, dampings, sizeof(dampings)); PxReal maxforces[6]; for (PxU32 ax = 0; ax < 6; ++ax) maxforces[ax] = mCore.getDrive(static_cast(ax)).maxForce; - OMNI_PVD_SETB(articulationjoint, driveMaxForce, joint, maxforces, sizeof(maxforces)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveMaxForce, joint, maxforces, sizeof(maxforces)); PxArticulationDriveType::Enum drivetypes[6]; for (PxU32 ax = 0; ax < 6; ++ax) drivetypes[ax] = mCore.getDrive(static_cast(ax)).driveType; - OMNI_PVD_SETB(articulationjoint, driveType, joint, drivetypes, sizeof(drivetypes)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveType, joint, drivetypes, sizeof(drivetypes)); #endif } @@ -309,11 +299,10 @@ namespace physx scSetDriveTarget(axis, target); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; PxReal targets[6]; for (PxU32 ax = 0; ax < 6; ++ax) targets[ax] = mCore.getTargetP(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, driveTarget, joint, targets, sizeof(targets)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveTarget, static_cast(*this), targets, sizeof(targets)); #endif } @@ -332,11 +321,10 @@ namespace physx scSetDriveVelocity(axis, targetVel); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; PxReal velocitys[6]; for (PxU32 ax = 0; ax < 6; ++ax) velocitys[ax] = mCore.getTargetV(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, driveVelocity, joint, velocitys, sizeof(velocitys)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveVelocity, static_cast(*this), velocitys, sizeof(velocitys)); #endif } @@ -363,11 +351,10 @@ namespace physx scSetArmature(axis, armature); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; PxReal armatures[6]; for (PxU32 ax = 0; ax < 6; ++ax) armatures[ax] = mCore.getArmature(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, armature, joint, armatures, sizeof(armatures)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, armature, static_cast(*this), armatures, sizeof(armatures)); #endif } @@ -380,6 +367,7 @@ namespace physx PxTransform NpArticulationJointReducedCoordinate::getParentPose() const { NP_READ_CHECK(getNpScene()); + // PT:: tag: scalar transform*transform return mParent->getCMassLocalPose().transform(mCore.getParentPose()); } @@ -391,9 +379,9 @@ namespace physx PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationJointReducedCoordinate::setParentPose() not allowed while simulation is running. Call will be ignored.") #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; - OMNI_PVD_SET(articulationjoint, parentTranslation, joint, t.p) - OMNI_PVD_SET(articulationjoint, parentRotation, joint, t.q) + PxArticulationJointReducedCoordinate& joint = *this; + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, parentTranslation, joint, t.p) + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, parentRotation, joint, t.q) #endif if (mParent == NULL) @@ -406,6 +394,7 @@ namespace physx { NP_READ_CHECK(getNpScene()); + // PT:: tag: scalar transform*transform return mChild->getCMassLocalPose().transform(mCore.getChildPose()); } @@ -417,9 +406,9 @@ namespace physx PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationJointReducedCoordinate::setChildPose() not allowed while simulation is running. Call will be ignored.") #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; - OMNI_PVD_SET(articulationjoint, childTranslation, joint, t.p) - OMNI_PVD_SET(articulationjoint, childRotation, joint, t.q) + PxArticulationJointReducedCoordinate& joint = *this; + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, childTranslation, joint, t.p) + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, childRotation, joint, t.q) #endif scSetChildPose(mChild->getCMassLocalPose().transformInv(t.getNormalized())); @@ -437,11 +426,10 @@ namespace physx scSetJointPosition(axis, jointPos); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; PxReal positions[6]; for (PxU32 ax = 0; ax < 6; ++ax) positions[ax] = mCore.getJointPosition(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, jointPosition, joint, positions, sizeof(positions)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, jointPosition, static_cast(*this), positions, sizeof(positions)); #endif } @@ -464,11 +452,10 @@ namespace physx scSetJointVelocity(axis, jointVel); #if PX_SUPPORT_OMNI_PVD - PxArticulationJointReducedCoordinate & joint = *this; PxReal velocitys[6]; for (PxU32 ax = 0; ax < 6; ++ax) velocitys[ax] = mCore.getJointVelocity(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, jointVelocity, joint, velocitys, sizeof(velocitys)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, jointVelocity, static_cast(*this), velocitys, sizeof(velocitys)); #endif } diff --git a/physx/source/physx/src/NpArticulationJointReducedCoordinate.h b/physx/source/physx/src/NpArticulationJointReducedCoordinate.h index ea7ca7ed7..e45a49f75 100644 --- a/physx/source/physx/src/NpArticulationJointReducedCoordinate.h +++ b/physx/source/physx/src/NpArticulationJointReducedCoordinate.h @@ -47,12 +47,6 @@ namespace physx class NpArticulationJointReducedCoordinate : public PxArticulationJointReducedCoordinate, public NpBase { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION NpArticulationJointReducedCoordinate(PxBaseFlags baseFlags) diff --git a/physx/source/physx/src/NpArticulationLink.cpp b/physx/source/physx/src/NpArticulationLink.cpp index 33ee35807..7ad9663e8 100644 --- a/physx/source/physx/src/NpArticulationLink.cpp +++ b/physx/source/physx/src/NpArticulationLink.cpp @@ -26,13 +26,7 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#include "NpArticulationLink.h" -#include "NpArticulationJointReducedCoordinate.h" #include "NpArticulationReducedCoordinate.h" -#include "NpCheck.h" -#include "CmVisualization.h" -#include "CmConeLimitHelper.h" -#include "CmUtils.h" #include "NpRigidActorTemplateInternal.h" using namespace physx; @@ -145,6 +139,7 @@ PxTransform NpArticulationLink::getGlobalPose() const PX_CHECK_SCENE_API_READ_FORBIDDEN_EXCEPT_COLLIDE_AND_RETURN_VAL(getNpScene(), "PxArticulationLink::getGlobalPose() not allowed while simulation is running (except during PxScene::collide()).", PxTransform(PxIdentity)); + // PT:: tag: scalar transform*transform return mCore.getBody2World() * mCore.getBody2Actor().getInverse(); } @@ -204,9 +199,9 @@ void NpArticulationLink::setCMassLocalPose(const PxTransform& pose) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationLink::setCMassLocalPose() not allowed while simulation is running. Call will be ignored.") - if (getNpScene() && getNpScene()->getFlags() & PxSceneFlag::eSUPPRESS_READBACK) + if (getNpScene() && getNpScene()->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxArticulationLink::setCMassLocalPose() : it is illegal to call this method if PxSceneFlag::eSUPPRESS_ARTICULATION_READBACK is enabled!"); + PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxArticulationLink::setCMassLocalPose() : it is illegal to call this method if PxSceneFlag::eENABLE_DIRECT_GPU_API is enabled!"); } const PxTransform p = pose.getNormalized(); @@ -218,12 +213,14 @@ void NpArticulationLink::setCMassLocalPose(const PxTransform& pose) if(mInboundJoint) { NpArticulationJointReducedCoordinate* j =static_cast(mInboundJoint); + // PT:: tag: scalar transform*transform j->scSetChildPose(comShift.transform(j->getCore().getChildPose())); } for(PxU32 i=0; i(mChildLinks[i]->getInboundJoint()); + // PT:: tag: scalar transform*transform j->scSetParentPose(comShift.transform(j->getCore().getParentPose())); } } @@ -296,7 +293,7 @@ void NpArticulationLink::setCfmScale(const PxReal cfmScale) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationLink::setCfmScale() not allowed while simulation is running. Call will be ignored.") mCore.getCore().cfmScale = cfmScale; - OMNI_PVD_SET(actor, CFMScale, static_cast(*this), cfmScale); // @@@ + OMNI_PVD_SET(PxArticulationLink, CFMScale, static_cast(*this), cfmScale); // @@@ } PxReal NpArticulationLink::getCfmScale() const @@ -320,6 +317,7 @@ void NpArticulationLink::setGlobalPoseInternal(const PxTransform& pose, bool aut const PxTransform newPose = pose.getNormalized(); //AM: added to fix 1461 where users read and write orientations for no reason. + // PT:: tag: scalar transform*transform const PxTransform body2World = newPose * mCore.getBody2Actor(); scSetBody2World(body2World); @@ -330,11 +328,11 @@ void NpArticulationLink::setGlobalPoseInternal(const PxTransform& pose, bool aut static_cast(mRoot)->setGlobalPose(); } -void NpArticulationLink::setKinematicLink(const bool value) +void NpArticulationLink::setFixedBaseLink(bool value) { NP_WRITE_CHECK(getNpScene()); - mCore.setKinematicLink(value); + mCore.setFixedBaseLink(value); } PxU32 physx::NpArticulationGetShapes(NpArticulationLink& actor, NpShape* const*& shapes, bool* isCompound) @@ -346,168 +344,3 @@ PxU32 physx::NpArticulationGetShapes(NpArticulationLink& actor, NpShape* const*& return sm.getNbShapes(); } -#if PX_ENABLE_DEBUG_VISUALIZATION -void NpArticulationLink::visualize(PxRenderOutput& out, NpScene& scene, float scale) const -{ - PX_ASSERT(scale!=0.0f); // Else we shouldn't have been called - if(!(mCore.getActorFlags() & PxActorFlag::eVISUALIZATION)) - return; - - NpArticulationLinkT::visualize(out, scene, scale); - - const Sc::Scene& scScene = scene.getScScene(); - - // PT: TODO: can we share this with the PxRigidDynamic version? - const PxReal massAxes = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eBODY_MASS_AXES); - if(massAxes != 0) - { - PxU32 color = 0xff; - color = (color<<16 | color<<8 | color); - PxVec3 dims = invertDiagInertia(mCore.getInverseInertia()); - dims = getDimsFromBodyInertia(dims, 1.0f / mCore.getInverseMass()); - out << color << mCore.getBody2World(); - const PxVec3 extents = dims * 0.5f; - renderOutputDebugBox(out, PxBounds3(-extents, extents)); - } - - const PxReal frameScale = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eJOINT_LOCAL_FRAMES); - const PxReal limitScale = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eJOINT_LIMITS); - if(frameScale != 0.0f || limitScale != 0.0f) - { - ConstraintImmediateVisualizer viz(frameScale, limitScale, out); - visualizeJoint(viz); - } -} - -static PX_FORCE_INLINE PxReal computePhi(const PxQuat& q) -{ - PxQuat twist = q; - twist.normalize(); - - PxReal angle = twist.getAngle(); - if (twist.x<0.0f) - angle = -angle; - return angle; -} - -// PT: TODO: don't duplicate this, it should be available in MathUtils or something -static PX_FORCE_INLINE float computeSwingAngle(float swingYZ, float swingW) -{ - return 4.0f * PxAtan2(swingYZ, 1.0f + swingW); // tan (t/2) = sin(t)/(1+cos t), so this is the quarter angle -} - -static PX_FORCE_INLINE void separateSwingTwist(const PxQuat& q, PxQuat& twist, PxQuat& swing1, PxQuat& swing2) -{ - twist = q.x != 0.0f ? PxQuat(q.x, 0, 0, q.w).getNormalized() : PxQuat(PxIdentity); - PxQuat swing = q * twist.getConjugate(); - swing1 = swing.y != 0.f ? PxQuat(0.f, swing.y, 0.f, swing.w).getNormalized() : PxQuat(PxIdentity); - swing = swing * swing1.getConjugate(); - swing2 = swing.z != 0.f ? PxQuat(0.f, 0.f, swing.z, swing.w).getNormalized() : PxQuat(PxIdentity); -} - -void NpArticulationLink::visualizeJoint(PxConstraintVisualizer& jointViz) const -{ - const NpArticulationLink* parent = getParent(); - if(parent) - { - PxTransform cA2w = getGlobalPose().transform(mInboundJoint->getChildPose()); - PxTransform cB2w = parent->getGlobalPose().transform(mInboundJoint->getParentPose()); - - jointViz.visualizeJointFrames(cA2w, cB2w); - - NpArticulationJointReducedCoordinate* impl = static_cast(mInboundJoint); - - PX_ASSERT(getArticulation().getConcreteType() == PxConcreteType::eARTICULATION_REDUCED_COORDINATE); - //(1) visualize any angular dofs/limits... - - const PxMat33 cA2w_m(cA2w.q), cB2w_m(cB2w.q); - - PxTransform parentFrame = cB2w; - - if (cA2w.q.dot(cB2w.q) < 0) - cB2w.q = -cB2w.q; - - //const PxTransform cB2cA = cA2w.transformInv(cB2w); - - const PxTransform cA2cB = cB2w.transformInv(cA2w); - - Sc::ArticulationJointCore& joint = impl->getCore(); - - PxQuat swing1, swing2, twist; - separateSwingTwist(cA2cB.q, twist, swing1, swing2); - - const PxReal pad = 0.01f; - - if(joint.getMotion(PxArticulationAxis::eTWIST)) - { - PxArticulationLimit pair; - - const PxReal angle = computePhi(twist); - pair = joint.getLimit(PxArticulationAxis::Enum(PxArticulationAxis::eTWIST)); - - bool active = (angle-pad) < pair.low || (angle+pad) > pair.high; - - PxTransform tmp = parentFrame; - - jointViz.visualizeAngularLimit(tmp, pair.low, pair.high, active); - } - - if (joint.getMotion(PxArticulationAxis::eSWING1)) - { - PxArticulationLimit pair; - - pair = joint.getLimit(PxArticulationAxis::Enum(PxArticulationAxis::eSWING1)); - - const PxReal angle = computeSwingAngle(swing1.y, swing1.w); - - bool active = (angle - pad) < pair.low || (angle + pad) > pair.high; - - PxTransform tmp = parentFrame; - tmp.q = tmp.q * PxQuat(-PxPiDivTwo, PxVec3(0.f, 0.f, 1.f)); - - - jointViz.visualizeAngularLimit(tmp, -pair.high, -pair.low, active); - } - - if (joint.getMotion(PxArticulationAxis::eSWING2)) - { - PxArticulationLimit pair; - - pair= joint.getLimit(PxArticulationAxis::Enum(PxArticulationAxis::eSWING2)); - - const PxReal angle = computeSwingAngle(swing2.z, swing2.w); - - bool active = (angle - pad) < pair.low || (angle + pad) > pair.high; - - PxTransform tmp = parentFrame; - tmp.q = tmp.q * PxQuat(PxPiDivTwo, PxVec3(0.f, 1.f, 0.f)); - - jointViz.visualizeAngularLimit(tmp, -pair.high, -pair.low, active); - } - - for (PxU32 i = PxArticulationAxis::eX; i <= PxArticulationAxis::eZ; ++i) - { - if (joint.getMotion(PxArticulationAxis::Enum(i)) == PxArticulationMotion::eLIMITED) - { - - PxArticulationLimit pair; - - PxU32 index = i - PxArticulationAxis::eX; - - pair = joint.getLimit(PxArticulationAxis::Enum(i)); - PxReal ordinate = cA2cB.p[index]; - PxVec3 origin = cB2w.p; - PxVec3 axis = cA2w_m[index]; - const bool active = ordinate < pair.low || ordinate > pair.high; - const PxVec3 p0 = origin + axis * pair.low; - const PxVec3 p1 = origin + axis * pair.high; - jointViz.visualizeLine(p0, p1, active ? 0xff0000u : 0xffffffu); - } - } - - } -} - -#else - PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION -#endif diff --git a/physx/source/physx/src/NpArticulationLink.h b/physx/source/physx/src/NpArticulationLink.h index 1a6bcaf98..069aeb668 100644 --- a/physx/source/physx/src/NpArticulationLink.h +++ b/physx/source/physx/src/NpArticulationLink.h @@ -49,12 +49,6 @@ typedef NpRigidBodyTemplate NpArticulationLinkT; class NpArticulationLinkArray : public PxInlineArray //!!!AL TODO: check if default of 4 elements makes sense { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpArticulationLinkArray(const PxEMPTY) : PxInlineArray (PxEmpty) {} @@ -65,12 +59,6 @@ class NpArticulationLinkArray : public PxInlineArray // class NpArticulationLink : public NpArticulationLinkT { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpArticulationLink(PxBaseFlags baseFlags) : NpArticulationLinkT(baseFlags), mChildLinks(PxEmpty) {} @@ -141,7 +129,7 @@ class NpArticulationLink : public NpArticulationLinkT public: PX_INLINE NpArticulationLink* const* getChildren() { return mChildLinks.empty() ? NULL : &mChildLinks.front(); } - void setKinematicLink(const bool value); + void setFixedBaseLink(bool value); #if PX_ENABLE_DEBUG_VISUALIZATION void visualize(PxRenderOutput& out, NpScene& scene, float scale) const; diff --git a/physx/source/physx/src/NpArticulationReducedCoordinate.cpp b/physx/source/physx/src/NpArticulationReducedCoordinate.cpp index 53b5ceb5f..ceb36814f 100644 --- a/physx/source/physx/src/NpArticulationReducedCoordinate.cpp +++ b/physx/source/physx/src/NpArticulationReducedCoordinate.cpp @@ -86,7 +86,7 @@ void NpArticulationReducedCoordinate::setArticulationFlags(PxArticulationFlags f scSetArticulationFlags(flags); - OMNI_PVD_SET(articulation, articulationFlags, static_cast(*this), flags); + OMNI_PVD_SET(PxArticulationReducedCoordinate, articulationFlags, static_cast(*this), flags); } void NpArticulationReducedCoordinate::setArticulationFlag(PxArticulationFlag::Enum flag, bool value) @@ -104,7 +104,7 @@ void NpArticulationReducedCoordinate::setArticulationFlag(PxArticulationFlag::En scSetArticulationFlags(flags); - OMNI_PVD_SET(articulation, articulationFlags, static_cast(*this), flags); + OMNI_PVD_SET(PxArticulationReducedCoordinate, articulationFlags, static_cast(*this), flags); } PxArticulationFlags NpArticulationReducedCoordinate::getArticulationFlags() const @@ -155,7 +155,7 @@ void NpArticulationReducedCoordinate::applyCache(PxArticulationCache& cache, con PX_CHECK_AND_RETURN(cache.version == mCacheVersion, "PxArticulationReducedCoordinate::applyCache: cache is invalid, articulation configuration has changed! "); - PX_CHECK_AND_RETURN(!(getScene()->getFlags() & PxSceneFlag::eSUPPRESS_READBACK), "PxArticulationReducedCoordinate::applyCache : it is illegal to call this method if PxSceneFlag::eSUPPRESS_ARTICULATION_READBACK is enabled!"); + PX_CHECK_AND_RETURN(!(getScene()->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API), "PxArticulationReducedCoordinate::applyCache : it is illegal to call this method if PxSceneFlag::eENABLE_DIRECT_GPU_API is enabled!"); //if we try to do a bulk op when sim is running, return with error if (getNpScene()->getSimulationStage() != Sc::SimulationStage::eCOMPLETE) @@ -165,7 +165,7 @@ void NpArticulationReducedCoordinate::applyCache(PxArticulationCache& cache, con return; } - if (!(getScene()->getFlags() & PxSceneFlag::eSUPPRESS_READBACK)) + if (!(getScene()->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API)) { const bool forceWake = mCore.applyCache(cache, flags); @@ -195,7 +195,11 @@ void NpArticulationReducedCoordinate::copyInternalStateToCache(PxArticulationCac PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxArticulationReducedCoordinate::copyInternalStateToCache() not allowed while simulation is running. Call will be ignored."); - mCore.copyInternalStateToCache(cache, flags); + PX_CHECK_AND_RETURN(!(getScene()->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API), "PxArticulationReducedCoordinate::copyInternalStateToCache : it is illegal to call this method if PxSceneFlag::eENABLE_DIRECT_GPU_API is enabled!"); + + const bool isGpuSimEnabled = getNpScene()->getFlags() & PxSceneFlag::eENABLE_GPU_DYNAMICS; + + mCore.copyInternalStateToCache(cache, flags, isGpuSimEnabled); } void NpArticulationReducedCoordinate::packJointData(const PxReal* maximum, PxReal* reduced) const @@ -503,7 +507,9 @@ PxSpatialVelocity NpArticulationReducedCoordinate::getLinkAcceleration(const PxU PX_CHECK_SCENE_API_READ_FORBIDDEN_EXCEPT_COLLIDE_AND_RETURN_VAL(getNpScene(), "PxArticulationReducedCoordinate::getLinkAcceleration() not allowed while simulation is running, except in a split simulation during PxScene::collide() and up to PxScene::advance().", PxSpatialVelocity()); - return mCore.getLinkAcceleration(linkId); + const bool isGpuSimEnabled = (getNpScene()->getFlags() & PxSceneFlag::eENABLE_GPU_DYNAMICS) ? true : false; + + return mCore.getLinkAcceleration(linkId, isGpuSimEnabled); } PxU32 NpArticulationReducedCoordinate::getGpuArticulationIndex() @@ -511,7 +517,7 @@ PxU32 NpArticulationReducedCoordinate::getGpuArticulationIndex() NP_READ_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(getNpScene(), "PxArticulationReducedCoordinate::getGpuArticulationIndex: Articulation must be in a scene.", 0xffffffff); - if (getScene()->getFlags() & PxSceneFlag::eSUPPRESS_READBACK) + if (getScene()->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) return mCore.getGpuArticulationIndex(); return 0xffffffff; } @@ -919,8 +925,8 @@ void NpArticulationReducedCoordinate::setSolverIterationCounts(PxU32 positionIte scSetSolverIterationCounts((velocityIters & 0xff) << 8 | (positionIters & 0xff)); - OMNI_PVD_SET(articulation, positionIterations, static_cast(*this), positionIters); - OMNI_PVD_SET(articulation, velocityIterations, static_cast(*this), velocityIters); + OMNI_PVD_SET(PxArticulationReducedCoordinate, positionIterations, static_cast(*this), positionIters); + OMNI_PVD_SET(PxArticulationReducedCoordinate, velocityIterations, static_cast(*this), velocityIters); } void NpArticulationReducedCoordinate::getSolverIterationCounts(PxU32& positionIters, PxU32& velocityIters) const @@ -975,7 +981,7 @@ void NpArticulationReducedCoordinate::setSleepThreshold(PxReal threshold) scSetSleepThreshold(threshold); - OMNI_PVD_SET(articulation, sleepThreshold, static_cast(*this), threshold); + OMNI_PVD_SET(PxArticulationReducedCoordinate, sleepThreshold, static_cast(*this), threshold); } PxReal NpArticulationReducedCoordinate::getSleepThreshold() const @@ -992,7 +998,7 @@ void NpArticulationReducedCoordinate::setStabilizationThreshold(PxReal threshold scSetFreezeThreshold(threshold); - OMNI_PVD_SET(articulation, stabilizationThreshold, static_cast(*this), threshold); + OMNI_PVD_SET(PxArticulationReducedCoordinate, stabilizationThreshold, static_cast(*this), threshold); } PxReal NpArticulationReducedCoordinate::getStabilizationThreshold() const @@ -1014,7 +1020,7 @@ void NpArticulationReducedCoordinate::setWakeCounter(PxReal wakeCounterValue) scSetWakeCounter(wakeCounterValue); - OMNI_PVD_SET(articulation, wakeCounter, static_cast(*this), wakeCounterValue); + OMNI_PVD_SET(PxArticulationReducedCoordinate, wakeCounter, static_cast(*this), wakeCounterValue); } PxReal NpArticulationReducedCoordinate::getWakeCounter() const @@ -1109,7 +1115,7 @@ void NpArticulationReducedCoordinate::setMaxCOMLinearVelocity(const PxReal maxLi scSetMaxLinearVelocity(maxLinearVelocity); - OMNI_PVD_SET(articulation, maxLinVelocity, static_cast(*this), maxLinearVelocity); + OMNI_PVD_SET(PxArticulationReducedCoordinate, maxLinearVelocity, static_cast(*this), maxLinearVelocity); } PxReal NpArticulationReducedCoordinate::getMaxCOMLinearVelocity() const @@ -1126,7 +1132,7 @@ void NpArticulationReducedCoordinate::setMaxCOMAngularVelocity(const PxReal maxA scSetMaxAngularVelocity(maxAngularVelocity); - OMNI_PVD_SET(articulation, maxAngVelocity, static_cast(*this), maxAngularVelocity); + OMNI_PVD_SET(PxArticulationReducedCoordinate, maxAngularVelocity, static_cast(*this), maxAngularVelocity); } PxReal NpArticulationReducedCoordinate::getMaxCOMAngularVelocity() const @@ -1191,17 +1197,6 @@ const char* NpArticulationReducedCoordinate::getName() const return mName; } -#if PX_ENABLE_DEBUG_VISUALIZATION -void NpArticulationReducedCoordinate::visualize(PxRenderOutput& out, NpScene& scene, float scale) const -{ - const PxU32 nbLinks = mArticulationLinks.size(); - for (PxU32 i = 0; i < nbLinks; i++) - mArticulationLinks[i]->visualize(out, scene, scale); -} -#else - PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION -#endif - NpArticulationLink* NpArticulationReducedCoordinate::getRoot() { if (!mArticulationLinks.size()) diff --git a/physx/source/physx/src/NpArticulationReducedCoordinate.h b/physx/source/physx/src/NpArticulationReducedCoordinate.h index 756e84b75..029482e30 100644 --- a/physx/source/physx/src/NpArticulationReducedCoordinate.h +++ b/physx/source/physx/src/NpArticulationReducedCoordinate.h @@ -54,12 +54,6 @@ namespace physx class NpArticulationReducedCoordinate : public PxArticulationReducedCoordinate, public NpBase { - //= 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. - //================================================================================================== public: virtual ~NpArticulationReducedCoordinate(); diff --git a/physx/source/physx/src/NpArticulationTendon.h b/physx/source/physx/src/NpArticulationTendon.h index 8601f9d57..a744724cf 100644 --- a/physx/source/physx/src/NpArticulationTendon.h +++ b/physx/source/physx/src/NpArticulationTendon.h @@ -53,12 +53,6 @@ class NpArticulationFixedTendon; class NpArticulationAttachmentArray : public PxInlineArray //!!!AL TODO: check if default of 4 elements makes sense { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION NpArticulationAttachmentArray(const PxEMPTY) : PxInlineArray(PxEmpty) {} @@ -69,12 +63,6 @@ class NpArticulationAttachmentArray : public PxInlineArray //!!!AL TODO: check if default of 4 elements makes sense { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION NpArticulationTendonJointArray(const PxEMPTY) : PxInlineArray(PxEmpty) {} diff --git a/physx/source/physx/src/NpBase.h b/physx/source/physx/src/NpBase.h index 5cdd20737..86cc16694 100644 --- a/physx/source/physx/src/NpBase.h +++ b/physx/source/physx/src/NpBase.h @@ -152,7 +152,6 @@ namespace physx ePBD_PARTICLESYSTEM, eFLIP_PARTICLESYSTEM, eMPM_PARTICLESYSTEM, - eCUSTOM_PARTICLESYSTEM, eHAIRSYSTEM, eTYPE_COUNT, diff --git a/physx/source/physx/src/NpConnector.h b/physx/source/physx/src/NpConnector.h index d5f861eac..83064205a 100644 --- a/physx/source/physx/src/NpConnector.h +++ b/physx/source/physx/src/NpConnector.h @@ -49,15 +49,8 @@ struct NpConnectorType }; }; - class NpConnector { -//= 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. -//================================================================================================== public: NpConnector() : mType(NpConnectorType::eInvalid), mObject(NULL) {} NpConnector(NpConnectorType::Enum type, PxBase* object) : mType(PxTo8(type)), mObject(object) {} @@ -107,15 +100,8 @@ class NpConnectorIterator NpConnectorType::Enum mType; }; - class NpConnectorArray: public PxInlineArray { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpConnectorArray(const PxEMPTY) : PxInlineArray (PxEmpty) {} diff --git a/physx/source/physx/src/NpConstraint.h b/physx/source/physx/src/NpConstraint.h index 1a92c88e4..55d652687 100644 --- a/physx/source/physx/src/NpConstraint.h +++ b/physx/source/physx/src/NpConstraint.h @@ -41,12 +41,6 @@ class NpScene; class NpConstraint : public PxConstraint, public NpBase { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpConstraint(PxBaseFlags baseFlags) : PxConstraint(baseFlags), NpBase(PxEmpty), mCore(PxEmpty) {} diff --git a/physx/source/physx/src/NpDebugViz.cpp b/physx/source/physx/src/NpDebugViz.cpp index 35c0f5137..e42eca4eb 100644 --- a/physx/source/physx/src/NpDebugViz.cpp +++ b/physx/source/physx/src/NpDebugViz.cpp @@ -327,77 +327,113 @@ static bool visualizeSDF(PxRenderOutput& out, const Gu::SDF& sdf, const PxMat34& { bool dataReductionActive = false; - PxU32 subgridSize; - PxReal sdfSpacing; - PxU32 NbTargetSamples = limitNumberOfVisualizedSamples ? 128 : 4096; - PxU32 nbX, nbY, nbZ; + PxU32 upperByteLimit = 512u * 512u * 512u * sizeof(PxDebugPoint); //2GB - sizeof(PxDebugPoint)=16bytes + + bool repeat = true; + + PxReal low = 0.0f, high = 0.0f; + PxU32 count = 0; + PxU32 upperLimit = limitNumberOfVisualizedSamples ? 128 : 4096; + PxReal sdfSpacing = 0.0f; + PxU32 strideX = 0; + PxU32 strideY = 0; + PxU32 strideZ = 0; + PxU32 nbX = 0, nbY = 0, nbZ = 0; + PxU32 subgridSize = 0; PxU32 subgridStride = 1; - if (sdf.mSubgridSize == 0) - { - subgridSize = 1; - sdfSpacing = sdf.mSpacing; - nbX = sdf.mDims.x; - nbY = sdf.mDims.y; - nbZ = sdf.mDims.z; - } - else + + while (repeat) { - subgridSize = sdf.mSubgridSize; - sdfSpacing = subgridSize * sdf.mSpacing; - nbX = sdf.mDims.x / subgridSize + 1; - nbY = sdf.mDims.y / subgridSize + 1; - nbZ = sdf.mDims.z / subgridSize + 1; - //Limit the max number of visualized sparse grid samples - if (limitNumberOfVisualizedSamples && subgridSize > 4) + repeat = false; + + PxU32 nbTargetSamplesPerAxis = upperLimit; + subgridStride = 1; + if (sdf.mSubgridSize == 0) { - subgridStride = (subgridSize + 3) / 4; - dataReductionActive = true; + subgridSize = 1; + sdfSpacing = sdf.mSpacing; + nbX = sdf.mDims.x; + nbY = sdf.mDims.y; + nbZ = sdf.mDims.z; + } + else + { + subgridSize = sdf.mSubgridSize; + sdfSpacing = subgridSize * sdf.mSpacing; + nbX = sdf.mDims.x / subgridSize + 1; + nbY = sdf.mDims.y / subgridSize + 1; + nbZ = sdf.mDims.z / subgridSize + 1; + //Limit the max number of visualized sparse grid samples + if (limitNumberOfVisualizedSamples && subgridSize > 4) + { + subgridStride = (subgridSize + 3) / 4; + dataReductionActive = true; + } } - } - - //KS - a bit arbitrary, but let's limit how many points we churn out - - const PxU32 strideX = (nbX + NbTargetSamples - 1) / NbTargetSamples; - const PxU32 strideY = (nbY + NbTargetSamples - 1) / NbTargetSamples; - const PxU32 strideZ = (nbZ + NbTargetSamples - 1) / NbTargetSamples; - if (strideX != 1 || strideY != 1 || strideZ != 1) - dataReductionActive = true; - - PxReal low = PX_MAX_F32; - PxReal high = -PX_MAX_F32; - PxU32 count = 0; + //KS - a bit arbitrary, but let's limit how many points we churn out + strideX = (nbX + nbTargetSamplesPerAxis - 1) / nbTargetSamplesPerAxis; + strideY = (nbY + nbTargetSamplesPerAxis - 1) / nbTargetSamplesPerAxis; + strideZ = (nbZ + nbTargetSamplesPerAxis - 1) / nbTargetSamplesPerAxis; + if (strideX != 1 || strideY != 1 || strideZ != 1) + dataReductionActive = true; - - for (PxU32 k = 0; k < nbZ; k += strideZ) - for(PxU32 j = 0; j < nbY; j += strideY) - for (PxU32 i = 0; i < nbX; i += strideX) - { - PxReal v = sdf.mSdf[k*nbX*nbY + j*nbX + i]; - count++; - - low = PxMin(low, v); - high = PxMax(high, v); + low = PX_MAX_F32; + high = -PX_MAX_F32; - if (sdf.mSubgridSize > 0 && k < nbZ - 1 && j < nbY - 1 && i < nbX - 1) + count = 0; + + + + for (PxU32 k = 0; k < nbZ; k += strideZ) + { + for (PxU32 j = 0; j < nbY; j += strideY) + { + for (PxU32 i = 0; i < nbX; i += strideX) { - PxU32 startId = sdf.mSubgridStartSlots[k*(nbX-1)*(nbY-1) + j * (nbX-1) + i]; - if (startId != 0xFFFFFFFFu) + PxReal v = sdf.mSdf[k*nbX*nbY + j * nbX + i]; + count++; + + low = PxMin(low, v); + high = PxMax(high, v); + + if (sdf.mSubgridSize > 0 && k < nbZ - 1 && j < nbY - 1 && i < nbX - 1) { - PxU32 xBase, yBase, zBase; - decodeTriple(startId, xBase, yBase, zBase); - - PX_ASSERT(xBase < sdf.mSdfSubgrids3DTexBlockDim.x); - PX_ASSERT(yBase < sdf.mSdfSubgrids3DTexBlockDim.y); - PX_ASSERT(zBase < sdf.mSdfSubgrids3DTexBlockDim.z); + PxU32 startId = sdf.mSubgridStartSlots[k*(nbX - 1)*(nbY - 1) + j * (nbX - 1) + i]; + if (startId != 0xFFFFFFFFu) + { + PxU32 xBase, yBase, zBase; + decodeTriple(startId, xBase, yBase, zBase); + + PX_ASSERT(xBase < sdf.mSdfSubgrids3DTexBlockDim.x); + PX_ASSERT(yBase < sdf.mSdfSubgrids3DTexBlockDim.y); + PX_ASSERT(zBase < sdf.mSdfSubgrids3DTexBlockDim.z); - PxU32 localCount = subgridSize / subgridStride + 1; - count += localCount * localCount * localCount; + PxU32 localCount = subgridSize / subgridStride + 1; + count += localCount * localCount * localCount; + } } + + if (count * sizeof(PxDebugPoint) > upperByteLimit) + break; } + if (count * sizeof(PxDebugPoint) > upperByteLimit) + break; } + if (count * sizeof(PxDebugPoint) > upperByteLimit) + break; + } + if (count * sizeof(PxDebugPoint) > upperByteLimit) + { + upperLimit /= 2; + repeat = true; + + if (upperLimit == 1) + return true; + } + } const PxReal range0 = high; const PxReal range1 = low; @@ -743,13 +779,16 @@ void NpShapeManager::visualize(PxRenderOutput& out, NpScene& scene, const PxRigi const PxReal collisionAxes = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eCOLLISION_AXES); const PxReal fscale = scale * fNormals; - const PxTransform actorPose = actor.getGlobalPose(); + const PxTransform32 actorPose(actor.getGlobalPose()); PxBounds3 compoundBounds(PxBounds3::empty()); for(PxU32 i=0;i(absPose, actorPose, npShape.getCore().getShape2Actor()); + const PxGeometry& geom = npShape.getCore().getGeometry(); const bool shapeDebugVizEnabled = npShape.getCore().getFlags() & PxShapeFlag::eVISUALIZATION; @@ -832,6 +871,19 @@ void physx::visualizeRigidBody(PxRenderOutput& out, NpScene& scene, const PxRigi out << 0x000000 << PxMat44(PxIdentity); Cm::renderOutputDebugArrow(out, PxDebugArrow(body2World.p, core.getAngularVelocity() * angVelocity, 0.2f * angVelocity)); } + + const PxReal massAxes = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eBODY_MASS_AXES); + if(massAxes != 0.0f) + { + const PxReal sleepTime = core.getWakeCounter() / scene.getWakeCounterResetValueInternal(); + PxU32 color = PxU32(0xff * (sleepTime>1.0f ? 1.0f : sleepTime)); + color = core.isSleeping() ? 0xff0000 : (color<<16 | color<<8 | color); + PxVec3 dims = invertDiagInertia(core.getInverseInertia()); + dims = getDimsFromBodyInertia(dims, 1.0f / core.getInverseMass()); + out << color << core.getBody2World(); + const PxVec3 extents = dims * 0.5f; + Cm::renderOutputDebugBox(out, PxBounds3(-extents, extents)); + } } void NpRigidStatic::visualize(PxRenderOutput& out, NpScene& scene, float scale) const @@ -852,24 +904,110 @@ void NpRigidDynamic::visualize(PxRenderOutput& out, NpScene& scene, float scale) return; NpRigidDynamicT::visualize(out, scene, scale); +} + +void NpArticulationLink::visualize(PxRenderOutput& out, NpScene& scene, float scale) const +{ + PX_ASSERT(scale!=0.0f); // Else we shouldn't have been called + if(!(mCore.getActorFlags() & PxActorFlag::eVISUALIZATION)) + return; + + NpArticulationLinkT::visualize(out, scene, scale); const Sc::Scene& scScene = scene.getScScene(); - // PT: TODO: why is this not in visualizeRigidBody ? - const PxReal massAxes = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eBODY_MASS_AXES); - if(massAxes != 0.0f) + const PxReal frameScale = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eJOINT_LOCAL_FRAMES); + const PxReal limitScale = scale * scScene.getVisualizationParameter(PxVisualizationParameter::eJOINT_LIMITS); + if(frameScale != 0.0f || limitScale != 0.0f) { - const PxReal sleepTime = mCore.getWakeCounter() / scene.getWakeCounterResetValueInternal(); - PxU32 color = PxU32(0xff * (sleepTime>1.0f ? 1.0f : sleepTime)); - color = mCore.isSleeping() ? 0xff0000 : (color<<16 | color<<8 | color); - PxVec3 dims = invertDiagInertia(mCore.getInverseInertia()); - dims = getDimsFromBodyInertia(dims, 1.0f / mCore.getInverseMass()); - out << color << mCore.getBody2World(); - const PxVec3 extents = dims * 0.5f; - Cm::renderOutputDebugBox(out, PxBounds3(-extents, extents)); + ConstraintImmediateVisualizer viz(frameScale, limitScale, out); + visualizeJoint(viz); } } +void NpArticulationLink::visualizeJoint(PxConstraintVisualizer& jointViz) const +{ + const NpArticulationLink* parent = getParent(); + if(parent) + { + // PT:: tag: scalar transform*transform + PxTransform cA2w = getGlobalPose().transform(mInboundJoint->getChildPose()); + // PT:: tag: scalar transform*transform + PxTransform cB2w = parent->getGlobalPose().transform(mInboundJoint->getParentPose()); + + jointViz.visualizeJointFrames(cA2w, cB2w); + + NpArticulationJointReducedCoordinate* impl = static_cast(mInboundJoint); + + PX_ASSERT(getArticulation().getConcreteType() == PxConcreteType::eARTICULATION_REDUCED_COORDINATE); + //(1) visualize any angular dofs/limits... + + const PxMat33 cA2w_m(cA2w.q), cB2w_m(cB2w.q); + + PxTransform parentFrame = cB2w; + + if (cA2w.q.dot(cB2w.q) < 0) + cB2w.q = -cB2w.q; + + //const PxTransform cB2cA = cA2w.transformInv(cB2w); + + const PxTransform cA2cB = cB2w.transformInv(cA2w); + + Sc::ArticulationJointCore& joint = impl->getCore(); + + if(joint.getMotion(PxArticulationAxis::eTWIST)) + { + const PxArticulationLimit pair = joint.getLimit(PxArticulationAxis::Enum(PxArticulationAxis::eTWIST)); + + jointViz.visualizeAngularLimit(parentFrame, pair.low, pair.high); + } + + if (joint.getMotion(PxArticulationAxis::eSWING1)) + { + const PxArticulationLimit pair = joint.getLimit(PxArticulationAxis::Enum(PxArticulationAxis::eSWING1)); + + PxTransform tmp = parentFrame; + tmp.q = tmp.q * PxQuat(-PxPiDivTwo, PxVec3(0.f, 0.f, 1.f)); + + jointViz.visualizeAngularLimit(tmp, -pair.high, -pair.low); + } + + if (joint.getMotion(PxArticulationAxis::eSWING2)) + { + const PxArticulationLimit pair = joint.getLimit(PxArticulationAxis::Enum(PxArticulationAxis::eSWING2)); + + PxTransform tmp = parentFrame; + tmp.q = tmp.q * PxQuat(PxPiDivTwo, PxVec3(0.f, 1.f, 0.f)); + + jointViz.visualizeAngularLimit(tmp, -pair.high, -pair.low); + } + + for (PxU32 i = PxArticulationAxis::eX; i <= PxArticulationAxis::eZ; ++i) + { + if (joint.getMotion(PxArticulationAxis::Enum(i)) == PxArticulationMotion::eLIMITED) + { + const PxU32 index = i - PxArticulationAxis::eX; + + const PxArticulationLimit pair = joint.getLimit(PxArticulationAxis::Enum(i)); + const PxReal ordinate = cA2cB.p[index]; + const PxVec3& origin = cB2w.p; + const PxVec3& axis = cA2w_m[index]; + const bool active = ordinate < pair.low || ordinate > pair.high; + const PxVec3 p0 = origin + axis * pair.low; + const PxVec3 p1 = origin + axis * pair.high; + jointViz.visualizeLine(p0, p1, active ? 0xff0000u : 0xffffffu); + } + } + } +} + +void NpArticulationReducedCoordinate::visualize(PxRenderOutput& out, NpScene& scene, float scale) const +{ + const PxU32 nbLinks = mArticulationLinks.size(); + for (PxU32 i = 0; i < nbLinks; i++) + mArticulationLinks[i]->visualize(out, scene, scale); +} + #else PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION #endif @@ -956,9 +1094,7 @@ void NpScene::visualize() const PxU32 particleSystemCount = mPBDParticleSystems.size(); for (PxU32 i = 0; i < particleSystemCount; i++) - { static_cast(particleSystems[i])->visualize(out, *this); - } } #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION @@ -967,10 +1103,7 @@ void NpScene::visualize() const PxU32 particleSystemCount = mFLIPParticleSystems.size(); for (PxU32 i = 0; i < particleSystemCount; i++) - { static_cast(particleSystems[i])->visualize(out, *this); - - } } { @@ -978,19 +1111,7 @@ void NpScene::visualize() const PxU32 particleSystemCount = mMPMParticleSystems.size(); for (PxU32 i = 0; i < particleSystemCount; i++) - { static_cast(particleSystems[i])->visualize(out, *this); - } - } - - { - PxCustomParticleSystem*const* particleSystems = mCustomParticleSystems.getEntries(); - const PxU32 particleSystemCount = mCustomParticleSystems.size(); - - for (PxU32 i = 0; i < particleSystemCount; i++) - { - static_cast(particleSystems[i])->visualize(out, *this); - } } #endif } @@ -1014,9 +1135,7 @@ void NpScene::visualize() const PxU32 hairSystemCount = mHairSystems.size(); for (PxU32 i = 0; i < hairSystemCount; i++) - { static_cast(hairSystems[i])->visualize(out, *this); - } #endif } #endif diff --git a/physx/source/physx/src/NpFEMCloth.cpp b/physx/source/physx/src/NpFEMCloth.cpp index f2c0cbcf4..edcfa9940 100644 --- a/physx/source/physx/src/NpFEMCloth.cpp +++ b/physx/source/physx/src/NpFEMCloth.cpp @@ -110,6 +110,7 @@ namespace physx return mCore.getFlags(); } +#if 0 // disabled until future use. void NpFEMCloth::setDrag(const PxReal drag) { NpScene* npScene = getNpScene(); @@ -174,40 +175,38 @@ namespace physx return mCore.getAirDensity(); } - void NpFEMCloth::setParameter(const PxFEMParameters& paramters) + void NpFEMCloth::setBendingActivationAngle(const PxReal angle) { NpScene* npScene = getNpScene(); NP_WRITE_CHECK(npScene); - PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::setParameter() not allowed while simulation is running. Call will be ignored.") + PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::setBendingActivationAngle() not allowed while simulation is running. Call will be ignored.") - mCore.setParameter(paramters); + mCore.setBendingActivationAngle(angle); UPDATE_PVD_PROPERTY } - PxFEMParameters NpFEMCloth::getParameter() const + PxReal NpFEMCloth::getBendingActivationAngle() const { - NP_READ_CHECK(getNpScene()); - return mCore.getParameter(); + return mCore.getBendingActivationAngle(); } +#endif - void NpFEMCloth::setRestVolumeScale(const PxReal scale) + void NpFEMCloth::setParameter(const PxFEMParameters& paramters) { - // todo: pressure should be mutable during simulation. - NpScene* npScene = getNpScene(); - NP_WRITE_CHECK(npScene); + NpScene* npScene = getNpScene(); + NP_WRITE_CHECK(npScene); - PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::setPressure() not allowed while simulation is running. Call will be ignored.") + PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::setParameter() not allowed while simulation is running. Call will be ignored.") - mCore.setRestVolumeScale(scale); - UPDATE_PVD_PROPERTY + mCore.setParameter(paramters); + UPDATE_PVD_PROPERTY } - PxReal NpFEMCloth::getRestVolumeScale() const + PxFEMParameters NpFEMCloth::getParameter() const { - // todo: is read lock necessary? - NP_READ_CHECK(getNpScene()); - return mCore.getRestVolumeScale(); + NP_READ_CHECK(getNpScene()); + return mCore.getParameter(); } void NpFEMCloth::setBendingScales(const PxReal* const bendingScales, PxU32 nbElements) @@ -249,20 +248,20 @@ namespace physx return mCore.getMaxVelocity(); } - void NpFEMCloth::setBendingActivationAngle(const PxReal angle) - { - NpScene* npScene = getNpScene(); - NP_WRITE_CHECK(npScene); + void NpFEMCloth::setMaxDepenetrationVelocity(const PxReal v) + { + NpScene* npScene = getNpScene(); + NP_WRITE_CHECK(npScene); - PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::setBendingActivationAngle() not allowed while simulation is running. Call will be ignored.") + PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::setMaxDepenetrationVelocity() not allowed while simulation is running. Call will be ignored.") - mCore.setBendingActivationAngle(angle); - UPDATE_PVD_PROPERTY + mCore.setMaxDepenetrationVelocity(v); + UPDATE_PVD_PROPERTY } - PxReal NpFEMCloth::getBendingActivationAngle() const - { - return mCore.getBendingActivationAngle(); + PxReal NpFEMCloth::getMaxDepenetrationVelocity() const + { + return mCore.getMaxDepenetrationVelocity(); } void NpFEMCloth::setNbCollisionPairUpdatesPerTimestep(const PxU32 frequency) @@ -297,64 +296,36 @@ namespace physx return mCore.getNbCollisionSubsteps(); } - PxBuffer* NpFEMCloth::getBufferFromFlag(PxFEMClothData::Enum flags) + PxVec4* NpFEMCloth::getPositionInvMassBufferD() { - PxBuffer* buf = NULL; + PX_CHECK_AND_RETURN_NULL(mShape != NULL, " NpFEMCloth::getPositionInvMassBufferD: FEM cloth does not have a shape, attach shape first."); + Dy::FEMClothCore& core = mCore.getCore(); - PX_UNUSED(core); - switch (flags) - { - case PxFEMClothData::ePOSITION_INVMASS: - buf = core.mClothPositionInvMass; - break; - case PxFEMClothData::eVELOCITY: - buf = core.mClothVelocity; - break; - case PxFEMClothData::eREST_POSITION: - buf = core.mClothRestPosition; - break; - case PxFEMClothData::eNONE: - case PxFEMClothData::eALL: - default: - PX_ASSERT(0); - } - return buf; + return core.mPositionInvMass; } - - - void NpFEMCloth::readData(PxFEMClothData::Enum flags, PxBuffer& buffer) + PxVec4* NpFEMCloth::getVelocityBufferD() { - PxBuffer* targetBuffer = getBufferFromFlag(flags); - if (!targetBuffer) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxFEMCloth::readData, source buffer hasn't been allocated."); - return; - } + PX_CHECK_AND_RETURN_NULL(mShape != NULL, " NpFEMCloth::getVelocityBufferD: FEM cloth does not have a shape, attach shape first."); - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - PX_ASSERT(physxGpu); - physxGpu->addCopyCommand(buffer, *targetBuffer, false); + Dy::FEMClothCore& core = mCore.getCore(); + return core.mVelocity; } - - void NpFEMCloth::writeData(PxFEMClothData::Enum flags, PxBuffer& buffer, bool flush) + PxVec4* NpFEMCloth::getRestPositionBufferD() { - NpScene* npScene = getNpScene(); - NP_WRITE_CHECK(npScene); - - PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxFEMCloth::writeData() not allowed while simulation is running. Call will be ignored.") + PX_CHECK_AND_RETURN_NULL(mShape != NULL, " NpFEMCloth::getRestPositionBufferD: FEM cloth does not have a shape, attach shape first."); + + Dy::FEMClothCore& core = mCore.getCore(); + return core.mRestPosition; + } - PxBuffer* targetBuffer = getBufferFromFlag(flags); - if (!targetBuffer) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "NpFEMCloth::writeData, target buffer hasn't been allocated."); - return; - } + void NpFEMCloth::markDirty(PxFEMClothDataFlags flags) + { + NP_WRITE_CHECK(getNpScene()); - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - PX_ASSERT(physxGpu); - physxGpu->addCopyCommand(*targetBuffer, buffer, flush); + Dy::FEMClothCore& core = mCore.getCore(); + core.mDirtyFlags |= flags; } PxCudaContextManager* NpFEMCloth::getCudaContextManager() const @@ -403,10 +374,16 @@ namespace physx PX_CHECK_AND_RETURN_NULL(npShape->getGeometryTypeFast() == PxGeometryType::eTRIANGLEMESH, "NpFEMCloth::attachShape: Geometry type must be triangle mesh geometry"); PX_CHECK_AND_RETURN_NULL(mShape == NULL, "NpFEMCloth::attachShape: FEM-cloth can just have one shape"); PX_CHECK_AND_RETURN_NULL(shape.isExclusive(), "NpFEMCloth::attachShape: shape must be exclusive"); -#if PX_CHECK - PxTriangleMeshGeometry geom; - npShape->getTriangleMeshGeometry(geom); + + Dy::FEMClothCore& core = mCore.getCore(); + PX_CHECK_AND_RETURN_NULL(core.mPositionInvMass == NULL, "NpFEMCloth::attachShape: mPositionInvMass already exists, overwrite not allowed, call detachShape first"); + PX_CHECK_AND_RETURN_NULL(core.mVelocity == NULL, "NpFEMCloth::attachShape: mClothVelocity already exists, overwrite not allowed, call detachShape first"); + PX_CHECK_AND_RETURN_NULL(core.mRestPosition == NULL, "NpFEMCloth::attachShape: mClothRestPosition already exists, overwrite not allowed, call detachShape first"); + + const PxTriangleMeshGeometry& geom = static_cast(npShape->getGeometry()); Gu::TriangleMesh* guMesh = static_cast(geom.triangleMesh); + +#if PX_CHECKED const PxU32 triangleReference = guMesh->getNbTriangleReferences(); PX_CHECK_AND_RETURN_NULL(triangleReference > 0, "NpFEMCloth::attachShape: cloth triangle mesh has cooked with eENABLE_VERT_MAPPING"); #endif @@ -418,25 +395,13 @@ namespace physx updateMaterials(); - return true; - } - - void NpFEMCloth::setClothCore(const PxVec4* const positionInvMasses, const PxVec4* const velocityInvMasses) - { - PX_UNUSED(positionInvMasses); - PX_UNUSED(velocityInvMasses); + const PxU32 numVerts = guMesh->getNbVerticesFast(); - const PxTriangleMeshGeometry& triangleGeometry = static_cast(mShape->getGeometry()); - Gu::TriangleMesh* triangleMesh = static_cast(triangleGeometry.triangleMesh); - const PxU32 numVerts = triangleMesh->getNbVerticesFast(); + core.mPositionInvMass = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVerts); + core.mVelocity = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVerts); + core.mRestPosition = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVerts); - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - - Dy::FEMClothCore& core = mCore.getCore(); - - core.mClothPositionInvMass = physxGpu->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); - core.mClothVelocity = physxGpu->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); - core.mClothRestPosition = physxGpu->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); + return true; } void NpFEMCloth::addRigidFilter(PxRigidActor* actor, PxU32 vertId) @@ -465,11 +430,12 @@ namespace physx mCore.removeRigidFilter(core, vertId); } - PxU32 NpFEMCloth::addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* params) + PxU32 NpFEMCloth::addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint) { NP_WRITE_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "NpFEMCloth::addRigidAttachment: cloth must be inserted into the scene.", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL((actor == NULL || actor->getScene() != NULL), "NpFEMCloth::addRigidAttachment: actor must be inserted into the scene.", 0xFFFFFFFF); + PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "NpFEMCloth::addRigidAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF); PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "NpFEMCloth::addRigidAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF); @@ -482,7 +448,7 @@ namespace physx aPose = stat->getGlobalPose().transform(aPose); } - return mCore.addRigidAttachment(core, vertId, aPose, params); + return mCore.addRigidAttachment(core, vertId, aPose, constraint); } void NpFEMCloth::removeRigidAttachment(PxRigidActor* actor, PxU32 handle) @@ -529,6 +495,7 @@ namespace physx NP_WRITE_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "NpFEMCloth::addTriRigidAttachment: cloth must be inserted into the scene.", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL((actor == NULL || actor->getScene() != NULL), "NpFEMCloth::addTriRigidAttachment: actor must be inserted into the scene.", 0xFFFFFFFF); + PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "NpFEMCloth::addTriRigidAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF); PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "NpFEMCloth::addTriRigidAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF); @@ -617,6 +584,26 @@ namespace physx void NpFEMCloth::detachShape() { + Dy::FEMClothCore& core = mCore.getCore(); + + if (core.mPositionInvMass) + { + PX_DEVICE_FREE(mCudaContextManager, core.mPositionInvMass); + core.mPositionInvMass = NULL; + } + + if (core.mVelocity) + { + PX_DEVICE_FREE(mCudaContextManager, core.mVelocity); + core.mVelocity = NULL; + } + + if (core.mRestPosition) + { + PX_DEVICE_FREE(mCudaContextManager, core.mRestPosition); + core.mRestPosition = NULL; + } + if (mShape) mShape->onActorDetach(); mShape = NULL; diff --git a/physx/source/physx/src/NpFEMCloth.h b/physx/source/physx/src/NpFEMCloth.h index 120b11d74..341535ed6 100644 --- a/physx/source/physx/src/NpFEMCloth.h +++ b/physx/source/physx/src/NpFEMCloth.h @@ -29,6 +29,8 @@ #ifndef PX_PHYSICS_NP_FEMCLOTH #define PX_PHYSICS_NP_FEMCLOTH +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION #include "PxFEMCloth.h" #endif @@ -59,6 +61,7 @@ namespace physx virtual void setFEMClothFlags(PxFEMClothFlags flags); virtual PxFEMClothFlags getFEMClothFlag() const; +#if 0 // disabled until future use. virtual void setDrag(const PxReal drag); virtual PxReal getDrag() const; @@ -71,12 +74,13 @@ namespace physx virtual void setAirDensity(const PxReal wind); virtual PxReal getAirDensity() const; + virtual void setBendingActivationAngle(const PxReal angle); + virtual PxReal getBendingActivationAngle() const; +#endif + virtual void setParameter(const PxFEMParameters& paramters); virtual PxFEMParameters getParameter() const; - virtual void setRestVolumeScale(const PxReal scale); - virtual PxReal getRestVolumeScale() const; - virtual void setBendingScales(const PxReal* const bendingScale, PxU32 nbElements); virtual const PxReal* getBendingScales() const; virtual PxU32 getNbBendingScales() const; @@ -84,8 +88,8 @@ namespace physx virtual void setMaxVelocity(const PxReal v); virtual PxReal getMaxVelocity() const; - virtual void setBendingActivationAngle(const PxReal angle); - virtual PxReal getBendingActivationAngle() const; + virtual void setMaxDepenetrationVelocity(const PxReal v); + virtual PxReal getMaxDepenetrationVelocity() const; virtual void setNbCollisionPairUpdatesPerTimestep(const PxU32 frequency); virtual PxU32 getNbCollisionPairUpdatesPerTimestep() const; @@ -93,10 +97,16 @@ namespace physx virtual void setNbCollisionSubsteps(const PxU32 frequency); virtual PxU32 getNbCollisionSubsteps() const; + virtual PxVec4* getPositionInvMassBufferD(); + virtual PxVec4* getVelocityBufferD(); + virtual PxVec4* getRestPositionBufferD(); + + virtual void markDirty(PxFEMClothDataFlags flags); + virtual void addRigidFilter(PxRigidActor* actor, PxU32 vertId); virtual void removeRigidFilter(PxRigidActor* actor, PxU32 vertId); - virtual PxU32 addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* params); + virtual PxU32 addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); virtual void removeRigidAttachment(PxRigidActor* actor, PxU32 handle); virtual void addTriRigidFilter(PxRigidActor* actor, PxU32 triangleId); @@ -111,10 +121,6 @@ namespace physx virtual PxU32 addClothAttachment(PxFEMCloth* otherCloth, PxU32 otherTriIdx, const PxVec4& otherTriBarycentric, PxU32 triIdx, const PxVec4& triBarycentric); virtual void removeClothAttachment(PxFEMCloth* otherCloth, PxU32 handle); - virtual void readData(PxFEMClothData::Enum flags, PxBuffer& buffer); - - virtual void writeData(PxFEMClothData::Enum flags, PxBuffer& buffer, bool flush); - virtual PxCudaContextManager* getCudaContextManager() const; virtual void setCudaContextManager(PxCudaContextManager*); @@ -126,8 +132,6 @@ namespace physx virtual bool attachShape(PxShape& shape); - virtual void setClothCore(const PxVec4* const positionInvMass, const PxVec4* const velocityInvMass); - virtual void detachShape(); virtual void release(); @@ -149,8 +153,6 @@ namespace physx private: - PxBuffer* getBufferFromFlag(PxFEMClothData::Enum flags); - NpShape* mShape; Sc::FEMClothCore mCore; PxCudaContextManager* mCudaContextManager; @@ -158,3 +160,5 @@ namespace physx #endif } #endif + +#endif diff --git a/physx/source/physx/src/NpFEMClothMaterial.cpp b/physx/source/physx/src/NpFEMClothMaterial.cpp index 1cabf5814..8ae68b036 100644 --- a/physx/source/physx/src/NpFEMClothMaterial.cpp +++ b/physx/source/physx/src/NpFEMClothMaterial.cpp @@ -45,7 +45,7 @@ NpFEMClothMaterial::NpFEMClothMaterial(const PxsFEMClothMaterialCore& desc) : NpFEMClothMaterial::~NpFEMClothMaterial() { - NpPhysics::getInstance().removeFEMClothMaterialFromTable(*this); + NpPhysics::getInstance().removeMaterialFromTable(*this); } // PX_SERIALIZATION @@ -103,7 +103,7 @@ PxU32 NpFEMClothMaterial::getReferenceCount() const PX_INLINE void NpFEMClothMaterial::updateMaterial() { - NpPhysics::getInstance().updateFEMClothMaterial(*this); + NpPhysics::getInstance().updateMaterial(*this); } /////////////////////////////////////////////////////////////////////////////// @@ -167,37 +167,7 @@ PxReal NpFEMClothMaterial::getThickness() const return mMaterial.thickness; } -/////////////////////////////////////////////////////////////////////////////// - -void NpFEMClothMaterial::setElasticityDamping(PxReal x) -{ - PX_CHECK_AND_RETURN(PxIsFinite(x), "PxFEMClothMaterial::setElasticityDamping: invalid float"); - - mMaterial.elasticityDamping = x; - - updateMaterial(); -} - -PxReal NpFEMClothMaterial::getElasticityDamping() const -{ - return mMaterial.elasticityDamping; -} - -/////////////////////////////////////////////////////////////////////////////// - -void NpFEMClothMaterial::setBendingDamping(PxReal x) -{ - PX_CHECK_AND_RETURN(PxIsFinite(x), "PxFEMClothMaterial::setBendingDamping: invalid float"); - - mMaterial.bendingDamping = x; - - updateMaterial(); -} - -PxReal NpFEMClothMaterial::getBendingDamping() const -{ - return mMaterial.bendingDamping; -} +////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// #endif diff --git a/physx/source/physx/src/NpFEMClothMaterial.h b/physx/source/physx/src/NpFEMClothMaterial.h index 0d54e84e7..b10ea32cd 100644 --- a/physx/source/physx/src/NpFEMClothMaterial.h +++ b/physx/source/physx/src/NpFEMClothMaterial.h @@ -45,12 +45,6 @@ namespace physx class NpFEMClothMaterial : public PxFEMClothMaterial, 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. - //================================================================================================== public: // PX_SERIALIZATION NpFEMClothMaterial(PxBaseFlags baseFlags) : PxFEMClothMaterial(baseFlags), mMaterial(PxEmpty) {} @@ -88,10 +82,6 @@ namespace physx // PxFEMClothMaterial virtual void setThickness(PxReal thickness) PX_OVERRIDE; virtual PxReal getThickness() const PX_OVERRIDE; - virtual void setElasticityDamping(PxReal damping) PX_OVERRIDE; - virtual PxReal getElasticityDamping() const PX_OVERRIDE; - virtual void setBendingDamping(PxReal damping) PX_OVERRIDE; - virtual PxReal getBendingDamping() const PX_OVERRIDE; //~PxFEMClothMaterial PX_FORCE_INLINE static void getMaterialIndices(PxFEMClothMaterial*const* materials, PxU16* materialIndices, PxU32 materialCount); diff --git a/physx/source/physx/src/NpFEMSoftBodyMaterial.cpp b/physx/source/physx/src/NpFEMSoftBodyMaterial.cpp index 0cb3ee1f9..52f5333d1 100644 --- a/physx/source/physx/src/NpFEMSoftBodyMaterial.cpp +++ b/physx/source/physx/src/NpFEMSoftBodyMaterial.cpp @@ -43,7 +43,7 @@ NpFEMSoftBodyMaterial::NpFEMSoftBodyMaterial(const PxsFEMSoftBodyMaterialCore& d NpFEMSoftBodyMaterial::~NpFEMSoftBodyMaterial() { - NpPhysics::getInstance().removeFEMSoftBodyMaterialFromTable(*this); + NpPhysics::getInstance().removeMaterialFromTable(*this); } // PX_SERIALIZATION @@ -56,7 +56,7 @@ void NpFEMSoftBodyMaterial::resolveReferences(PxDeserializationContext&) // Maybe not the best place to do it but it has to be done before the shapes resolve material indices // since the material index translation table is needed there. This requires that the materials have // been added to the table already. - NpPhysics::getInstance().addFEMMaterial(this); + NpPhysics::getInstance().addMaterial(this); } void NpFEMSoftBodyMaterial::onRefCountZero() @@ -100,7 +100,7 @@ PxU32 NpFEMSoftBodyMaterial::getReferenceCount() const PX_INLINE void NpFEMSoftBodyMaterial::updateMaterial() { - NpPhysics::getInstance().updateFEMSoftBodyMaterial(*this); + NpPhysics::getInstance().updateMaterial(*this); } /////////////////////////////////////////////////////////////////////////////// @@ -168,15 +168,29 @@ PxReal NpFEMSoftBodyMaterial::getDamping() const void NpFEMSoftBodyMaterial::setDampingScale(PxReal x) { - PX_CHECK_AND_RETURN(x >= 0.f && x<= 1.f, "PxMaterial::setDampingScale: invalid float"); - mMaterial.dampingScale = x; + PX_CHECK_AND_RETURN(x >= 0.f && x<= 1.f, "PxMaterial::setDampingScale: invalid float, must be in [0.0, 1.0] range."); + mMaterial.dampingScale = toUniformU16(x); updateMaterial(); } PxReal NpFEMSoftBodyMaterial::getDampingScale() const { - return mMaterial.dampingScale; + return toUniformReal(mMaterial.dampingScale); +} + +/////////////////////////////////////////////////////////////////////////////// + +void NpFEMSoftBodyMaterial::setMaterialModel(PxFEMSoftBodyMaterialModel::Enum model) +{ + mMaterial.materialModel = PxU16(model); + + updateMaterial(); +} + +PxFEMSoftBodyMaterialModel::Enum NpFEMSoftBodyMaterial::getMaterialModel() const +{ + return PxFEMSoftBodyMaterialModel::Enum(mMaterial.materialModel); } /////////////////////////////////////////////////////////////////////////////// diff --git a/physx/source/physx/src/NpFEMSoftBodyMaterial.h b/physx/source/physx/src/NpFEMSoftBodyMaterial.h index d90ad9d93..d67d7a29d 100644 --- a/physx/source/physx/src/NpFEMSoftBodyMaterial.h +++ b/physx/source/physx/src/NpFEMSoftBodyMaterial.h @@ -44,12 +44,6 @@ namespace physx class NpFEMSoftBodyMaterial : public PxFEMSoftBodyMaterial, 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. - //================================================================================================== public: // PX_SERIALIZATION NpFEMSoftBodyMaterial(PxBaseFlags baseFlags) : PxFEMSoftBodyMaterial(baseFlags), mMaterial(PxEmpty) {} @@ -90,6 +84,8 @@ namespace physx virtual PxReal getDamping() const PX_OVERRIDE; virtual void setDampingScale(PxReal scale); virtual PxReal getDampingScale() const; + virtual void setMaterialModel(PxFEMSoftBodyMaterialModel::Enum model); + virtual PxFEMSoftBodyMaterialModel::Enum getMaterialModel() const; virtual void setDeformThreshold(PxReal threshold); virtual PxReal getDeformThreshold() const; virtual void setDeformLowLimitRatio(PxReal threshold); diff --git a/physx/source/physx/src/NpFLIPMaterial.cpp b/physx/source/physx/src/NpFLIPMaterial.cpp index dd86742a6..628a0ba54 100644 --- a/physx/source/physx/src/NpFLIPMaterial.cpp +++ b/physx/source/physx/src/NpFLIPMaterial.cpp @@ -44,7 +44,7 @@ NpFLIPMaterial::NpFLIPMaterial(const PxsFLIPMaterialCore& desc) : NpFLIPMaterial::~NpFLIPMaterial() { - NpPhysics::getInstance().removeFLIPMaterialFromTable(*this); + NpPhysics::getInstance().removeMaterialFromTable(*this); } // PX_SERIALIZATION @@ -101,7 +101,7 @@ PxU32 NpFLIPMaterial::getReferenceCount() const PX_INLINE void NpFLIPMaterial::updateMaterial() { - NpPhysics::getInstance().updateFLIPMaterial(*this); + NpPhysics::getInstance().updateMaterial(*this); } /////////////////////////////////////////////////////////////////////////////// diff --git a/physx/source/physx/src/NpFLIPMaterial.h b/physx/source/physx/src/NpFLIPMaterial.h index 54b81ae2e..52966f218 100644 --- a/physx/source/physx/src/NpFLIPMaterial.h +++ b/physx/source/physx/src/NpFLIPMaterial.h @@ -46,12 +46,6 @@ namespace physx class NpFLIPMaterial : public PxFLIPMaterial, 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. - //================================================================================================== public: // PX_SERIALIZATION NpFLIPMaterial(PxBaseFlags baseFlags) : PxFLIPMaterial(baseFlags), mMaterial(PxEmpty) {} diff --git a/physx/source/physx/src/NpFactory.cpp b/physx/source/physx/src/NpFactory.cpp index f91f4bd73..aa83d707d 100644 --- a/physx/source/physx/src/NpFactory.cpp +++ b/physx/source/physx/src/NpFactory.cpp @@ -190,6 +190,7 @@ void NpFactory::addArticulation(PxArticulationReducedCoordinate* npArticulation, OMNI_PVD_NOTIFY_ADD(npArticulation); } +#if PX_SUPPORT_GPU_PHYSX void NpFactory::addParticleBuffer(PxParticleBuffer* buffer, bool lock) { addToTracking(mParticleBufferTracking, buffer, mTrackingMutex, lock); @@ -200,63 +201,7 @@ void NpFactory::onParticleBufferReleaseInternal(PxParticleBuffer* buffer) PxMutex::ScopedLock lock(mTrackingMutex); mParticleBufferTracking.erase(buffer); } - -static PxArticulationReducedCoordinate* createArticulationRC() -{ - NpArticulationReducedCoordinate* npArticulation = NpFactory::getInstance().createNpArticulationRC(); - if (!npArticulation) - PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation initialization failed: returned NULL."); - return npArticulation; -} - -static NpArticulationLink* createArticulationLink(NpArticulationReducedCoordinate &root, NpArticulationLink* parent, const PxTransform& pose) -{ - PX_CHECK_AND_RETURN_NULL(pose.isValid(),"Supplied articulation link pose is not valid. Articulation link creation method returns NULL."); - PX_CHECK_AND_RETURN_NULL((!parent || (&parent->getRoot() == &root)), "specified parent link is not part of the destination articulation. Articulation link creation method returns NULL."); - - NpArticulationLink* npArticulationLink = NpFactory::getInstance().createNpArticulationLink(root, parent, pose); - if (!npArticulationLink) - { - PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation link initialization failed: returned NULL."); - return NULL; - } - - PxArticulationJointReducedCoordinate* npArticulationJoint = 0; - if (parent) - { - PxTransform parentPose = parent->getCMassLocalPose().transformInv(pose); - PxTransform childPose = PxTransform(PxIdentity); - - npArticulationJoint = root.createArticulationJoint(*parent, parentPose, *npArticulationLink, childPose); - if (!npArticulationJoint) - { - PX_DELETE(npArticulationLink); - - PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation link initialization failed due to joint creation failure: returned NULL."); - return NULL; - } - - npArticulationLink->setInboundJoint(*npArticulationJoint); - } - - return npArticulationLink; -} - -// pointers to functions above, initialized during subsystem registration -static PxArticulationReducedCoordinate* (*sCreateArticulationRCFn)() = 0; -static NpArticulationLink* (*sCreateArticulationLinkFn)(NpArticulationReducedCoordinate&, NpArticulationLink* parent, const PxTransform& pose) = 0; - -void NpFactory::registerArticulations() -{ - //sCreateArticulationFn = &::createArticulation; - sCreateArticulationLinkFn = &::createArticulationLink; -} - -void NpFactory::registerArticulationRCs() -{ - sCreateArticulationRCFn = &::createArticulationRC; - sCreateArticulationLinkFn = &::createArticulationLink; -} +#endif void NpFactory::releaseArticulationToPool(PxArticulationReducedCoordinate& articulation) { @@ -269,17 +214,14 @@ void NpFactory::releaseArticulationToPool(PxArticulationReducedCoordinate& artic PxArticulationReducedCoordinate* NpFactory::createArticulationRC() { - if (!sCreateArticulationRCFn) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Articulations not registered: returned NULL."); - return NULL; - } - - PxArticulationReducedCoordinate* npArticulation = (*sCreateArticulationRCFn)(); - if (npArticulation) + NpArticulationReducedCoordinate* npArticulation = NpFactory::getInstance().createNpArticulationRC(); + if(npArticulation) addArticulation(npArticulation); + else + PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation initialization failed: returned NULL."); + // OMNI_PVD_CREATE() - return static_cast(npArticulation); + return npArticulation; } NpArticulationReducedCoordinate* NpFactory::createNpArticulationRC() @@ -316,13 +258,35 @@ void NpFactory::releaseArticulationLinkToPool(NpArticulationLink& articulationLi PxArticulationLink* NpFactory::createArticulationLink(NpArticulationReducedCoordinate& root, NpArticulationLink* parent, const PxTransform& pose) { - if(!sCreateArticulationLinkFn) + PX_CHECK_AND_RETURN_NULL(pose.isValid(),"Supplied articulation link pose is not valid. Articulation link creation method returns NULL."); + PX_CHECK_AND_RETURN_NULL((!parent || (&parent->getRoot() == &root)), "specified parent link is not part of the destination articulation. Articulation link creation method returns NULL."); + + NpArticulationLink* npArticulationLink = NpFactory::getInstance().createNpArticulationLink(root, parent, pose); + if (!npArticulationLink) { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "Articulations not registered: returned NULL."); + PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation link initialization failed: returned NULL."); return NULL; } - return (*sCreateArticulationLinkFn)(root, parent, pose); + PxArticulationJointReducedCoordinate* npArticulationJoint = 0; + if (parent) + { + PxTransform parentPose = parent->getCMassLocalPose().transformInv(pose); + PxTransform childPose = PxTransform(PxIdentity); + + npArticulationJoint = root.createArticulationJoint(*parent, parentPose, *npArticulationLink, childPose); + if (!npArticulationJoint) + { + PX_DELETE(npArticulationLink); + + PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation link initialization failed due to joint creation failure: returned NULL."); + return NULL; + } + + npArticulationLink->setInboundJoint(*npArticulationJoint); + } + + return npArticulationLink; } NpArticulationJointReducedCoordinate* NpFactory::createNpArticulationJointRC(NpArticulationLink& parent, const PxTransform& parentFrame, NpArticulationLink& child, const PxTransform& childFrame) @@ -346,31 +310,22 @@ void NpFactory::releaseArticulationJointRCToPool(NpArticulationJointReducedCoord /////////////////////////////////////////////////////////////////////////////// soft body +#if PX_SUPPORT_GPU_PHYSX PxSoftBody* NpFactory::createSoftBody(PxCudaContextManager& cudaContextManager) { -#if PX_SUPPORT_GPU_PHYSX NpSoftBody* sb; { PxMutex::ScopedLock lock(mSoftBodyPoolLock); sb = mSoftBodyPool.construct(cudaContextManager); } OMNI_PVD_NOTIFY_ADD(sb); return sb; -#else - PX_UNUSED(cudaContextManager); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxSoftBody is not supported on this platform."); - return NULL; -#endif } void NpFactory::releaseSoftBodyToPool(PxSoftBody& softBody) { -#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(softBody.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); OMNI_PVD_NOTIFY_REMOVE(&softBody); PxMutex::ScopedLock lock(mSoftBodyPoolLock); mSoftBodyPool.destroy(static_cast(&softBody)); -#else - PX_UNUSED(softBody); -#endif } /////////////////////////////////////////////////////////////////////////////// FEM cloth @@ -378,25 +333,15 @@ void NpFactory::releaseSoftBodyToPool(PxSoftBody& softBody) #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxFEMCloth* NpFactory::createFEMCloth(PxCudaContextManager& cudaContextManager) { -#if PX_SUPPORT_GPU_PHYSX PxMutex::ScopedLock lock(mFEMClothPoolLock); return mFEMClothPool.construct(cudaContextManager); -#else - PX_UNUSED(cudaContextManager); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxFEMCloth is not supported on this platform."); - return NULL; -#endif } void NpFactory::releaseFEMClothToPool(PxFEMCloth& femCloth) { -#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(femCloth.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); PxMutex::ScopedLock lock(mFEMClothPoolLock); mFEMClothPool.destroy(static_cast(&femCloth)); -#else - PX_UNUSED(femCloth); -#endif } #endif @@ -404,110 +349,51 @@ void NpFactory::releaseFEMClothToPool(PxFEMCloth& femCloth) PxPBDParticleSystem* NpFactory::createPBDParticleSystem(PxU32 maxNeighborhood, PxCudaContextManager& cudaContextManager) { -#if PX_SUPPORT_GPU_PHYSX PxMutex::ScopedLock lock(mPBDParticleSystemPoolLock); //PX_CHECK_MSG(NpPBDParticleSystem::getNumAvailableSystems() > 0, "Max. number of concurrent PxParticleSystem is 256."); return mPBDParticleSystemPool.construct(maxNeighborhood, cudaContextManager); -#else - PX_UNUSED(maxNeighborhood); - PX_UNUSED(cudaContextManager); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxPBDParticleSystem is not supported on this platform."); - return NULL; -#endif } void NpFactory::releasePBDParticleSystemToPool(PxPBDParticleSystem& particleSystem) { -#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(particleSystem.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); PxMutex::ScopedLock lock(mPBDParticleSystemPoolLock); mPBDParticleSystemPool.destroy(static_cast(&particleSystem)); -#else - PX_UNUSED(particleSystem); -#endif } #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxFLIPParticleSystem* NpFactory::createFLIPParticleSystem(PxCudaContextManager& cudaContextManager) { -#if PX_SUPPORT_GPU_PHYSX PxMutex::ScopedLock lock(mFLIPParticleSystemPoolLock); //PX_CHECK_MSG(NpFLIPParticleSystem::getNumAvailableSystems() > 0, "Max. number of concurrent PxParticleSystem is 256."); return mFLIPParticleSystemPool.construct(cudaContextManager); -#else - PX_UNUSED(cudaContextManager); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxParticleSystem is not supported on this platform."); - return NULL; -#endif } void NpFactory::releaseFLIPParticleSystemToPool(PxFLIPParticleSystem& particleSystem) { -#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(particleSystem.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); PxMutex::ScopedLock lock(mFLIPParticleSystemPoolLock); mFLIPParticleSystemPool.destroy(static_cast(&particleSystem)); -#else - PX_UNUSED(particleSystem); -#endif } PxMPMParticleSystem* NpFactory::createMPMParticleSystem(PxCudaContextManager& cudaContextManager) { -#if PX_SUPPORT_GPU_PHYSX PxMutex::ScopedLock lock(mMPMParticleSystemPoolLock); //PX_CHECK_MSG(NpMPMParticleSystem::getNumAvailableSystems() > 0, "Max. number of concurrent PxParticleSystem is 256."); return mMPMParticleSystemPool.construct(cudaContextManager); -#else - PX_UNUSED(cudaContextManager); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxMPMParticleSystem is not supported on this platform."); - return NULL; -#endif } void NpFactory::releaseMPMParticleSystemToPool(PxMPMParticleSystem& particleSystem) { -#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(particleSystem.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); PxMutex::ScopedLock lock(mMPMParticleSystemPoolLock); mMPMParticleSystemPool.destroy(static_cast(&particleSystem)); -#else - PX_UNUSED(particleSystem); -#endif -} - -PxCustomParticleSystem* NpFactory::createCustomParticleSystem(PxCudaContextManager& cudaContextManager, PxU32 maxNeighborhood) -{ -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mMPMParticleSystemPoolLock); - - //PX_CHECK_MSG(NpMPMParticleSystem::getNumAvailableSystems() > 0, "Max. number of concurrent PxParticleSystem is 256."); - - return mCustomParticleSystemPool.construct(cudaContextManager, maxNeighborhood); -#else - PX_UNUSED(cudaContextManager); - PX_UNUSED(maxNeighborhood); - - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxCustomParticleSystem is not supported on this platform."); - return NULL; -#endif -} - -void NpFactory::releaseCustomParticleSystemToPool(PxCustomParticleSystem& particleSystem) -{ -#if PX_SUPPORT_GPU_PHYSX - PX_ASSERT(particleSystem.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); - PxMutex::ScopedLock lock(mCustomParticleSystemPoolLock); - mCustomParticleSystemPool.destroy(static_cast(&particleSystem)); -#else - PX_UNUSED(particleSystem); -#endif } #endif @@ -518,19 +404,12 @@ PxParticleBuffer* NpFactory::createParticleBuffer(PxU32 maxParticles, PxU32 maxV if(!cudaContextManager) return NULL; -#if PX_SUPPORT_GPU_PHYSX PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); PX_ASSERT(physxGpu); PxParticleBuffer* buffer = physxGpu->createParticleBuffer(maxParticles, maxVolumes, cudaContextManager, &mGpuMemStat, NpFactory::onParticleBufferRelease); addParticleBuffer(buffer); return buffer; -#else - PX_UNUSED(maxParticles); - PX_UNUSED(maxVolumes); - PX_UNUSED(cudaContextManager); - return NULL; -#endif } PxParticleAndDiffuseBuffer* NpFactory::createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContextManager) @@ -538,20 +417,12 @@ PxParticleAndDiffuseBuffer* NpFactory::createParticleAndDiffuseBuffer(PxU32 maxP if(!cudaContextManager) return NULL; -#if PX_SUPPORT_GPU_PHYSX PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); PX_ASSERT(physxGpu); PxParticleAndDiffuseBuffer* diffuseBuffer = physxGpu->createParticleAndDiffuseBuffer(maxParticles, maxVolumes, maxDiffuseParticles, cudaContextManager, &mGpuMemStat, NpFactory::onParticleBufferRelease); addParticleBuffer(diffuseBuffer); return diffuseBuffer; -#else - PX_UNUSED(maxParticles); - PX_UNUSED(maxVolumes); - PX_UNUSED(maxDiffuseParticles); - PX_UNUSED(cudaContextManager); - return NULL; -#endif } PxParticleClothBuffer* NpFactory::createParticleClothBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContextManager) @@ -559,22 +430,12 @@ PxParticleClothBuffer* NpFactory::createParticleClothBuffer(PxU32 maxParticles, if(!cudaContextManager) return NULL; -#if PX_SUPPORT_GPU_PHYSX PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); PX_ASSERT(physxGpu); PxParticleClothBuffer* clothBuffer = physxGpu->createParticleClothBuffer(maxParticles, maxNumVolumes, maxNumCloths, maxNumTriangles, maxNumSprings, cudaContextManager, &mGpuMemStat, NpFactory::onParticleBufferRelease); addParticleBuffer(clothBuffer); return clothBuffer; -#else - PX_UNUSED(maxParticles); - PX_UNUSED(maxNumVolumes); - PX_UNUSED(maxNumCloths); - PX_UNUSED(maxNumTriangles); - PX_UNUSED(maxNumSprings); - PX_UNUSED(cudaContextManager); - return NULL; -#endif } PxParticleRigidBuffer* NpFactory::createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContextManager) @@ -582,20 +443,12 @@ PxParticleRigidBuffer* NpFactory::createParticleRigidBuffer(PxU32 maxParticles, if(!cudaContextManager) return NULL; -#if PX_SUPPORT_GPU_PHYSX PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); PX_ASSERT(physxGpu); PxParticleRigidBuffer* rigidBuffer = physxGpu->createParticleRigidBuffer(maxParticles, maxNumVolumes, maxNumRigids, cudaContextManager, &mGpuMemStat, NpFactory::onParticleBufferRelease); addParticleBuffer(rigidBuffer); return rigidBuffer; -#else - PX_UNUSED(maxParticles); - PX_UNUSED(maxNumVolumes); - PX_UNUSED(maxNumRigids); - PX_UNUSED(cudaContextManager); - return NULL; -#endif } void NpFactory::onParticleBufferRelease(PxParticleBuffer* buffer) @@ -608,27 +461,18 @@ void NpFactory::onParticleBufferRelease(PxParticleBuffer* buffer) #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxHairSystem* NpFactory::createHairSystem(PxCudaContextManager& cudaContextManager) { -#if PX_SUPPORT_GPU_PHYSX PxMutex::ScopedLock lock(mHairSystemPoolLock); return mHairSystemPool.construct(cudaContextManager); -#else - PX_UNUSED(cudaContextManager); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxHairSystem is not supported on this platform."); - return NULL; -#endif } void NpFactory::releaseHairSystemToPool(PxHairSystem& hairSystem) { -#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(hairSystem.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); PxMutex::ScopedLock lock(mHairSystemPoolLock); mHairSystemPool.destroy(static_cast(&hairSystem)); -#else - PX_UNUSED(hairSystem); -#endif } #endif +#endif /////////////////////////////////////////////////////////////////////////////// constraint @@ -728,6 +572,7 @@ void NpFactory::releaseMaterialToPool(NpMaterial& material) /////////////////////////////////////////////////////////////////////////////// +#if PX_SUPPORT_GPU_PHYSX PxFEMSoftBodyMaterial* NpFactory::createFEMSoftBodyMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) { #if PX_SUPPORT_GPU_PHYSX @@ -740,7 +585,8 @@ PxFEMSoftBodyMaterial* NpFactory::createFEMSoftBodyMaterial(PxReal youngs, PxRea materialData.poissons = poissons; materialData.dynamicFriction = dynamicFriction; materialData.damping = 0.f; - materialData.dampingScale = 1.f; + materialData.dampingScale = toUniformU16(1.f); + materialData.materialModel = PxFEMSoftBodyMaterialModel::eCO_ROTATIONAL; materialData.deformThreshold = PX_MAX_F32; materialData.deformLowLimitRatio = 1.f; materialData.deformHighLimitRatio = 1.f; @@ -788,8 +634,6 @@ PxFEMClothMaterial* NpFactory::createFEMClothMaterial(PxReal youngs, PxReal pois materialData.poissons = poissons; materialData.dynamicFriction = dynamicFriction; materialData.thickness = 0.f; - materialData.elasticityDamping = 0.f; - materialData.bendingDamping = 0.f; NpFEMClothMaterial* npMaterial = NULL; { @@ -993,40 +837,8 @@ void NpFactory::releaseMPMMaterialToPool(PxMPMMaterial& material_) #endif } -/////////////////////////////////////////////////////////////////////////////// - -PxCustomMaterial* NpFactory::createCustomMaterial(void* gpuBuffer) -{ -#if PX_SUPPORT_GPU_PHYSX - PxsCustomMaterialData materialData; - materialData.userData = gpuBuffer; - materialData.gravityScale = 1.f; - - NpCustomMaterial* npMaterial; - { - PxMutex::ScopedLock lock(mCustomMaterialPoolLock); - npMaterial = mCustomMaterialPool.construct(materialData); - } - return npMaterial; -#else - PX_UNUSED(gpuBuffer); - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxCustomMaterial is not supported on this platform."); - return NULL; -#endif -} - -void NpFactory::releaseCustomMaterialToPool(PxCustomMaterial& material_) -{ -#if PX_SUPPORT_GPU_PHYSX - NpCustomMaterial& material = static_cast(material_); - PX_ASSERT(material.getBaseFlags() & PxBaseFlag::eOWNS_MEMORY); - PxMutex::ScopedLock lock(mMPMMaterialPoolLock); - mCustomMaterialPool.destroy(&material); -#else - PX_UNUSED(material_); -#endif -} -#endif +#endif // PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#endif // PX_SUPPORT_GPU_PHYSX /////////////////////////////////////////////////////////////////////////////// @@ -1066,10 +878,7 @@ NpShape* NpFactory::createShapeInternal(const PxGeometry& geometry, if(!checkShape(geometry, "Supplied PxGeometry is not valid. Shape creation method returns NULL.")) return NULL; - // // Check for invalid material table setups - // - if(!NpShape::checkMaterialSetup(geometry, "Shape creation", materials, materialCount)) return NULL; #endif @@ -1107,7 +916,7 @@ NpShape* NpFactory::createShape(const PxGeometry& geometry, PxMaterial*const* materials, PxU16 materialCount, bool isExclusive) -{ +{ return createShapeInternal(geometry, shapeFlags, materials, materialCount, isExclusive, PxShapeCoreFlag::Enum(0)); } @@ -1125,19 +934,14 @@ NpShape* NpFactory::createShape(const PxGeometry& geometry, #endif } -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX NpShape* NpFactory::createShape(const PxGeometry& geometry, PxShapeFlags shapeFlags, PxFEMClothMaterial*const* materials, PxU16 materialCount, bool isExclusive) { -#if PX_SUPPORT_GPU_PHYSX return createShapeInternal(geometry, shapeFlags, materials, materialCount, isExclusive, PxShapeCoreFlag::eCLOTH_SHAPE); -#else - PX_UNUSED(geometry); PX_UNUSED(shapeFlags); PX_UNUSED(materials); PX_UNUSED(materialCount); PX_UNUSED(isExclusive); - return NULL; -#endif } #endif @@ -1385,13 +1189,6 @@ static PX_FORCE_INLINE void releaseToPool(NpMPMParticleSystem* np) } #endif -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -static PX_FORCE_INLINE void releaseToPool(NpCustomParticleSystem* np) -{ - NpFactory::getInstance().releaseCustomParticleSystemToPool(*np); -} -#endif - #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION static PX_FORCE_INLINE void releaseToPool(NpHairSystem* np) { @@ -1430,7 +1227,6 @@ void physx::NpDestroyParticleSystem(NpPBDParticleSystem* np) { NpDestroy(np #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION void physx::NpDestroyParticleSystem(NpFLIPParticleSystem* np) { NpDestroy(np); } void physx::NpDestroyParticleSystem(NpMPMParticleSystem* np) { NpDestroy(np); } -void physx::NpDestroyParticleSystem(NpCustomParticleSystem* np) { NpDestroy(np); } void physx::NpDestroyHairSystem(NpHairSystem* np) { NpDestroy(np); } #endif #endif diff --git a/physx/source/physx/src/NpFactory.h b/physx/source/physx/src/NpFactory.h index dc22130a7..5572fe2fe 100644 --- a/physx/source/physx/src/NpFactory.h +++ b/physx/source/physx/src/NpFactory.h @@ -37,7 +37,7 @@ #include "PxPhysXConfig.h" #include "PxShape.h" #include "PxAggregate.h" - +#include "PxvGeometry.h" #include "NpFEMCloth.h" // to be deleted @@ -79,7 +79,6 @@ class NpFEMCloth; class NpPBDParticleSystem; class NpFLIPParticleSystem; class NpMPMParticleSystem; -class NpCustomParticSystem; class NpHairSystem; class NpFEMSoftBodyMaterial; @@ -87,7 +86,6 @@ class NpFEMClothMaterial; class NpPBDMaterial; class NpFLIPMaterial; class NpMPMMaterial; -class NpCustomMaterial; #endif class PxMaterial; @@ -131,8 +129,6 @@ class NpFactory : public Gu::MeshFactory public: static void createInstance(); static void destroyInstance(); - static void registerArticulations(); - static void registerArticulationRCs(); static void onParticleBufferRelease(PxParticleBuffer* buffer); void release(); @@ -160,7 +156,7 @@ class NpFactory : public Gu::MeshFactory // Shapes NpShape* createShape(const PxGeometry& geometry, PxShapeFlags shapeFlags, PxMaterial*const* materials, PxU16 materialCount, bool isExclusive); NpShape* createShape(const PxGeometry& geometry, PxShapeFlags shapeFlags, PxFEMSoftBodyMaterial*const* materials, PxU16 materialCount, bool isExclusive); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX NpShape* createShape(const PxGeometry& geometry, PxShapeFlags shapeFlags, PxFEMClothMaterial*const* materials, PxU16 materialCount, bool isExclusive); #endif void addShape(PxShape*, bool lock=true); @@ -190,34 +186,29 @@ class NpFactory : public Gu::MeshFactory NpArticulationJointReducedCoordinate* createNpArticulationJointRC(NpArticulationLink& parent, const PxTransform& parentFrame, NpArticulationLink& child, const PxTransform& childFrame); void releaseArticulationJointRCToPool(NpArticulationJointReducedCoordinate& articulationJoint); +#if PX_SUPPORT_GPU_PHYSX //Soft bodys PxSoftBody* createSoftBody(PxCudaContextManager& cudaContextManager); void releaseSoftBodyToPool(PxSoftBody& softBody); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION // FEMCloth PxFEMCloth* createFEMCloth(PxCudaContextManager& cudaContextManager); void releaseFEMClothToPool(PxFEMCloth& femCloth); -#endif - + #endif //Particle systems - PxPBDParticleSystem* createPBDParticleSystem(PxU32 maxNeighborhood, PxCudaContextManager& cudaContexManager); + PxPBDParticleSystem* createPBDParticleSystem(PxU32 maxNeighborhood, PxCudaContextManager& cudaContextManager); void releasePBDParticleSystemToPool(PxPBDParticleSystem& particleSystem); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION //Particle systems - PxFLIPParticleSystem* createFLIPParticleSystem(PxCudaContextManager& cudaContexManager); + PxFLIPParticleSystem* createFLIPParticleSystem(PxCudaContextManager& cudaContextManager); void releaseFLIPParticleSystemToPool(PxFLIPParticleSystem& particleSystem); //Particle systems - PxMPMParticleSystem* createMPMParticleSystem(PxCudaContextManager& cudaContexManager); + PxMPMParticleSystem* createMPMParticleSystem(PxCudaContextManager& cudaContextManager); void releaseMPMParticleSystemToPool(PxMPMParticleSystem& particleSystem); - - //Particle systems - PxCustomParticleSystem* createCustomParticleSystem(PxCudaContextManager& cudaContexManager, PxU32 maxNeighborhood); - void releaseCustomParticleSystemToPool(PxCustomParticleSystem& particleSystem); -#endif - + #endif //Particle buffers PxParticleBuffer* createParticleBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContextManager); @@ -230,12 +221,12 @@ class NpFactory : public Gu::MeshFactory //Particle rigid buffers PxParticleRigidBuffer* createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContextManager); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION // HairSystem PxHairSystem* createHairSystem(PxCudaContextManager& cudaContextManager); void releaseHairSystemToPool(PxHairSystem& hairSystem); + #endif #endif - // Aggregates PxAggregate* createAggregate(PxU32 maxActors, PxU32 maxShapes, PxAggregateFilterHint filterHint); void addAggregate(PxAggregate*, bool lock=true); @@ -248,6 +239,7 @@ class NpFactory : public Gu::MeshFactory PxMaterial* createMaterial(PxReal staticFriction, PxReal dynamicFriction, PxReal restitution); void releaseMaterialToPool(NpMaterial& material); +#if PX_SUPPORT_GPU_PHYSX PxFEMSoftBodyMaterial* createFEMSoftBodyMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction); void releaseFEMMaterialToPool(PxFEMSoftBodyMaterial& material); @@ -257,17 +249,13 @@ class NpFactory : public Gu::MeshFactory PxPBDMaterial* createPBDMaterial(PxReal friction, PxReal damping, PxReal adhesion, PxReal viscosity, PxReal vorticityConfinement, PxReal surfaceTension, PxReal cohesion, PxReal lift, PxReal drag, PxReal cflCoefficient, PxReal gravityScale); void releasePBDMaterialToPool(PxPBDMaterial& material); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxFLIPMaterial* createFLIPMaterial(PxReal friction, PxReal damping, PxReal adhesion, PxReal viscosity, PxReal gravityScale); void releaseFLIPMaterialToPool(PxFLIPMaterial& material); -#endif - + #endif 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); void releaseMPMMaterialToPool(PxMPMMaterial& material); - - PxCustomMaterial* createCustomMaterial(void* gpuBuffer); - void releaseCustomMaterialToPool(PxCustomMaterial& material); - +#endif // It's easiest to track these uninvasively, so it's OK to use the Px pointers void onActorRelease(PxActor*); void onConstraintRelease(PxConstraint*); @@ -275,9 +263,10 @@ class NpFactory : public Gu::MeshFactory void onArticulationRelease(PxArticulationReducedCoordinate*); void onShapeRelease(PxShape*); +#if PX_SUPPORT_GPU_PHYSX void addParticleBuffer(PxParticleBuffer* buffer, bool lock = true); void onParticleBufferReleaseInternal(PxParticleBuffer* buffer); - +#endif NpConnectorArray* acquireConnectorArray(); void releaseConnectorArray(NpConnectorArray*); @@ -288,8 +277,6 @@ class NpFactory : public Gu::MeshFactory #endif private: - void releaseExclusiveShapeUserReferences(); - PxPool mConnectorArrayPool; PxMutex mConnectorArrayPoolLock; @@ -300,8 +287,9 @@ class NpFactory : public Gu::MeshFactory PxHashSet mConstraintTracking; PxHashSet mActorTracking; PxCoalescedHashSet mShapeTracking; +#if PX_SUPPORT_GPU_PHYSX PxHashSet mParticleBufferTracking; - +#endif PxPool2 mRigidDynamicPool; PxMutex mRigidDynamicPoolLock; @@ -326,7 +314,6 @@ class NpFactory : public Gu::MeshFactory PxPool2 mArticulationLinkPool; PxMutex mArticulationLinkPoolLock; - PxPool2 mArticulationRCJointPool; PxMutex mArticulationJointRCPoolLock; @@ -334,48 +321,41 @@ class NpFactory : public Gu::MeshFactory PxPool2 mSoftBodyPool; PxMutex mSoftBodyPoolLock; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxPool2 mFEMClothPool; PxMutex mFEMClothPoolLock; -#endif - + #endif PxPool2 mPBDParticleSystemPool; PxMutex mPBDParticleSystemPoolLock; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxPool2 mFLIPParticleSystemPool; PxMutex mFLIPParticleSystemPoolLock; PxPool2 mMPMParticleSystemPool; PxMutex mMPMParticleSystemPoolLock; - - PxPool2 mCustomParticleSystemPool; - PxMutex mCustomParticleSystemPoolLock; -#endif - + #endif PxPool2 mFEMMaterialPool; PxMutex mFEMMaterialPoolLock; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxPool2 mFEMClothMaterialPool; PxMutex mFEMClothMaterialPoolLock; -#endif + #endif PxPool2 mPBDMaterialPool; PxMutex mPBDMaterialPoolLock; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxPool2 mFLIPMaterialPool; PxMutex mFLIPMaterialPoolLock; PxPool2 mMPMMaterialPool; PxMutex mMPMMaterialPoolLock; - PxPool2 mCustomMaterialPool; - PxMutex mCustomMaterialPoolLock; /*PxPool2 mFEMMaterialPool; PxMutex mFEMMaterialPoolLock;*/ PxPool2 mHairSystemPool; PxMutex mHairSystemPoolLock; -#endif + #endif #endif static NpFactory* mInstance; @@ -401,7 +381,6 @@ class NpFactory : public Gu::MeshFactory void NpDestroyParticleSystem(NpPBDParticleSystem* particleSystem); void NpDestroyParticleSystem(NpFLIPParticleSystem* particleSystem); void NpDestroyParticleSystem(NpMPMParticleSystem* particleSystem); - void NpDestroyParticleSystem(NpCustomParticleSystem* particleSystem); void NpDestroyHairSystem(NpHairSystem* hairSystem); #endif } diff --git a/physx/source/physx/src/NpHairSystem.cpp b/physx/source/physx/src/NpHairSystem.cpp index 72146135e..dbb021feb 100644 --- a/physx/source/physx/src/NpHairSystem.cpp +++ b/physx/source/physx/src/NpHairSystem.cpp @@ -39,11 +39,13 @@ #include "ScBodySim.h" #include "geometry/PxHairSystemDesc.h" #include "PxsMemoryManager.h" +#include "NpSoftBody.h" #include "PxPhysXGpu.h" #include "PxvGlobals.h" #include "cudamanager/PxCudaContextManager.h" #include "cudamanager/PxCudaContext.h" +#include "GuTetrahedronMeshUtils.h" using namespace physx; @@ -58,7 +60,7 @@ namespace physx mDeviceMemoryAllocator(NULL), mRestPositionActor(NULL) { - mCore.getShapeCore().createBuffers(&cudaContextManager); + init(); } @@ -70,7 +72,7 @@ namespace physx mDeviceMemoryAllocator(NULL), mRestPositionActor(NULL) { - mCore.getShapeCore().createBuffers(&cudaContextManager); + init(); } NpHairSystem::~NpHairSystem() @@ -78,6 +80,14 @@ namespace physx releaseAllocator(); } + void NpHairSystem::init() + { + mCore.getShapeCore().createBuffers(mCudaContextManager); + createAllocator(); + + mSoftbodyAttachments.getAllocator().setCallback(mHostMemoryAllocator); + } + void NpHairSystem::releaseAllocator() { // destroy internal buffers if they exist before destroying allocators @@ -98,6 +108,8 @@ namespace physx mCore.getShapeCore().getLLCore().mRestPositionsTransform = NULL; } + mSoftbodyAttachments.reset(); + if (mMemoryManager != NULL) { mMemoryManager->~PxsMemoryManager(); @@ -336,7 +348,23 @@ namespace physx if(mRestPositionActor) { - removeRigidAttachment(mRestPositionActor); + // Careful: If the restPositionActor is already destroyed, we must not call removeRigidAttachment + PxU32 numActors = npScene->getNbActors(PxActorTypeFlag::eRIGID_STATIC | PxActorTypeFlag::eRIGID_DYNAMIC); + PxArray userBuffer(numActors); + numActors = npScene->getActors(PxActorTypeFlag::eRIGID_STATIC | PxActorTypeFlag::eRIGID_DYNAMIC, &userBuffer[0], userBuffer.size(), 0); + + for(PxU32 i = 0; i < numActors; i++) + { + if(userBuffer[i]->getType() == PxActorType::eRIGID_STATIC || userBuffer[i]->getType() == PxActorType::eRIGID_DYNAMIC) + { + const PxRigidActor* rigidActor = static_cast(userBuffer[i]); + if(rigidActor == mRestPositionActor) + { + removeRigidAttachment(mRestPositionActor); + break; + } + } + } mRestPositionActor = NULL; } @@ -364,42 +392,24 @@ namespace physx PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxHairSystem::addRigidAttachment: Illegal to call while simulation is running."); - const Sc::BodyCore* attachmentBodyCore = NULL; - const PxActorType::Enum actorType = actor->getType(); - switch (actorType) - { - case PxActorType::eRIGID_STATIC: + if(actor->getConcreteType() == PxConcreteType::eRIGID_STATIC) { PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxHairSystem::addRigidAttachment does not support attachments to static actors. Use attachment to world (NULL) instead."); - break; - } - case PxActorType::eRIGID_DYNAMIC: - { - const NpRigidDynamic* dyn = static_cast(actor); - attachmentBodyCore = &dyn->getCore(); - break; - } - case PxActorType::eARTICULATION_LINK: - { - const NpArticulationLink* link = static_cast(actor); - attachmentBodyCore = &link->getCore(); - break; - } - default: - { - PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, - "PxHairSystem::addRigidAttachment Unknown actor type. Must be a rigid dynamic or an articulation link"); - } + return; } + const Sc::BodyCore* attachmentBodyCore = getBodyCore(actor); + PX_CHECK_AND_RETURN(attachmentBodyCore != NULL, "PxHairSystem::addRigidAttachment: Attachment body must be rigid dynamic or articulation."); if(attachmentBodyCore != NULL) { - mCore.addRigidAttachment(attachmentBodyCore); + const Sc::BodySim* bodySim = attachmentBodyCore->getSim(); + if(bodySim) + mCore.addAttachment(*bodySim); } -} + } void NpHairSystem::removeRigidAttachment(const PxRigidActor* actor) { @@ -409,32 +419,12 @@ namespace physx PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxHairSystem::removeRigidAttachment: Illegal to call while simulation is running."); - const Sc::BodyCore* attachmentBodyCore = NULL; - const PxActorType::Enum actorType = actor->getType(); - switch (actorType) - { - case PxActorType::eRIGID_DYNAMIC: - { - const NpRigidDynamic* dyn = static_cast(actor); - attachmentBodyCore = &dyn->getCore(); - break; - } - case PxActorType::eARTICULATION_LINK: - { - const NpArticulationLink* link = static_cast(actor); - attachmentBodyCore = &link->getCore(); - break; - } - default: - { - PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, - "PxHairSystem::removeRigidAttachment Invalid actor type"); - } - } - + const Sc::BodyCore* attachmentBodyCore = getBodyCore(actor); if(attachmentBodyCore != NULL) { - mCore.removeRigidAttachment(attachmentBodyCore); + const Sc::BodySim* bodySim = attachmentBodyCore->getSim(); + if(bodySim) + mCore.removeAttachment(*bodySim); } } @@ -453,7 +443,6 @@ namespace physx { // create fresh buffer mParticleRigidAttachmentsInternal.reset(); - createAllocator(); mParticleRigidAttachmentsInternal.setAllocatorCallback(mDeviceMemoryAllocator); mParticleRigidAttachmentsInternal.allocate(numAttachments); llCore.mRigidAttachments = mParticleRigidAttachmentsInternal.begin(); @@ -473,7 +462,7 @@ namespace physx } // Don't clear mParticleRigidAttachmentsInternal if isGpuPtr==true and user has passed in the same pointer again - llCore.mDirtyFlags |= Dy::HairSystemDirtyFlag::eATTACHMENT; + llCore.mDirtyFlags |= Dy::HairSystemDirtyFlag::eRIGID_ATTACHMENTS; } PxParticleRigidAttachment* NpHairSystem::getRigidAttachmentsGpu(PxU32* numAttachments) @@ -486,6 +475,122 @@ namespace physx return llCore.mRigidAttachments; } + PxU32 NpHairSystem::addSoftbodyAttachment(const PxSoftBody& softbody, const PxU32* tetIds, + const PxVec4* tetmeshBarycentrics, const PxU32* hairVertices, PxU32 numAttachments) + { + NP_WRITE_CHECK(getNpScene()); + PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "PxHairSystem::addSoftbodyAttachment: Illegal to call while simulation is running.", 0xffFFffFF); + PX_CHECK_AND_RETURN_VAL(tetIds != NULL, "PxHairSystem::addSoftbodyAttachment: tetIds must not be null.", 0xffFFffFF); + PX_CHECK_AND_RETURN_VAL(tetmeshBarycentrics != NULL, "PxHairSystem::addSoftbodyAttachment: tetmeshBarycentrics must not be null.", 0xffFFffFF); + PX_CHECK_AND_RETURN_VAL(hairVertices != NULL, "PxHairSystem::addSoftbodyAttachment: hairVertices must not be null.", 0xffFFffFF); + PX_CHECK_AND_RETURN_VAL(softbody.getScene() != NULL, "PxHairSystem::addSoftbodyAttachment: Softbody must be inserted into the scene.", 0xffFFffFF); + PX_CHECK_AND_RETURN_VAL(getScene() == softbody.getScene(), "PxHairSystem::addSoftbodyAttachment: Softbody and hair must be part of the same scene.", 0xffFFffFF); + + if(numAttachments == 0) + return 0xffFFffFF; + + Dy::HairSystemCore& llCore = mCore.getShapeCore().getLLCore(); + + const NpSoftBody& npSoftbody = static_cast(softbody); + const PxU32 softbodyIdx = npSoftbody.getCore().getGpuSoftBodyIndex(); + + const PxTetrahedronMesh& simMesh = *softbody.getSimulationMesh(); + + const PxSoftBodyAuxData* auxData = softbody.getSoftBodyAuxData(); + PX_CHECK_AND_RETURN_VAL(auxData->getConcreteType() == PxConcreteType::eSOFT_BODY_STATE, "PxHairSystem::addSoftbodyAttachment: The softbodies aux data must be of type Gu::SoftBodyAuxData.", 0xffFFffFF); + const Gu::SoftBodyAuxData* guAuxData = static_cast(auxData); + + // Gu::BVTetrahedronMesh does not have a concrete type + const PxTetrahedronMesh* collisionMesh = softbody.getCollisionMesh(); + // PX_CHECK_AND_RETURN_VAL(collisionMesh->getConcreteType() == ???, "PxHairSystem::addSoftbodyAttachment: The softbodies collision mesh must be of type Gu::BVTetrahedronMesh.", 0xffFFffFF); + const Gu::BVTetrahedronMesh* bvCollisionMesh = static_cast(collisionMesh); + + // assign handle by finding the first nonexistent key in the hashmap + PxU32 handle = PX_MAX_U32; + for(PxU32 i = 0; i < PX_MAX_U32; i++) + { + if(mSoftbodyAttachmentsOffsets.find(i) == NULL) + { + handle = i; + break; + } + } + PX_ASSERT(handle != PX_MAX_U32); + + // new attachments will be added to the end of the contiguous array + mSoftbodyAttachmentsOffsets[handle] = PxPair(mSoftbodyAttachments.size(), numAttachments); + + mSoftbodyAttachments.reserve(mSoftbodyAttachments.size() + numAttachments); + for(PxU32 i=0; i>* handleOffsetSize = mSoftbodyAttachmentsOffsets.find(handle); + PX_ASSERT(handleOffsetSize != NULL); + if(handleOffsetSize == NULL) + return; + + PX_ASSERT(handle == handleOffsetSize->first); + const PxU32 offset = handleOffsetSize->second.first; + const PxU32 numRemoved = handleOffsetSize->second.second; + const PxU32 totSize = mSoftbodyAttachments.size(); + + // shift all subsequent elements in the attachment array to the left + for(PxU32 i=offset; i + numRemoved < totSize; i++) + { + mSoftbodyAttachments[i] = mSoftbodyAttachments[i+numRemoved]; + } + mSoftbodyAttachments.resize(mSoftbodyAttachments.size() - numRemoved); + + // correct all offsets of the still existing attachments and delete the current handle + mSoftbodyAttachmentsOffsets.erase(handle); + + for(PxHashMap>::Iterator it = mSoftbodyAttachmentsOffsets.getIterator(); + !it.done(); it++) + { + if(it->second.first > offset) + it->second.first -= numRemoved; + } + + const NpSoftBody& npSoftbody = static_cast(softbody); + mCore.removeAttachment(*npSoftbody.getCore().getSim()); // remove edge for island generation + + Dy::HairSystemCore& llCore = mCore.getShapeCore().getLLCore(); + llCore.mSoftbodyAttachments = mSoftbodyAttachments.begin(); + llCore.mNumSoftbodyAttachments = mSoftbodyAttachments.size(); + + llCore.mDirtyFlags |= Dy::HairSystemDirtyFlag::eSOFTBODY_ATTACHMENTS; + } + + void NpHairSystem::setRestPositions(PxVec4* restPos, bool isGpuPtr, const PxTransform& transf, const PxRigidBody* actor) { NP_WRITE_CHECK(getNpScene()); @@ -502,7 +607,6 @@ namespace physx { // create fresh buffer mRestPositionsInternal.reset(); - createAllocator(); mRestPositionsInternal.setAllocatorCallback(mDeviceMemoryAllocator); mRestPositionsInternal.allocate(llCore.mNumVertices); llCore.mRestPositions = mRestPositionsInternal.begin(); @@ -524,7 +628,6 @@ namespace physx if(llCore.mRestPositionsTransform == NULL) { - createAllocator(); mRestPositionTransformPinnedBuf.setAllocatorCallback(mHostMemoryAllocator); mRestPositionTransformPinnedBuf.allocate(1); llCore.mRestPositionsTransform = mRestPositionTransformPinnedBuf.begin(); @@ -560,19 +663,34 @@ namespace physx void NpHairSystem::setLlGridSize(const PxBounds3& bounds) { - // give system some space to expand: create a grid twice the initial size + // give system some space to expand: create a grid to accomodate at least 1.5 times the initial size Dy::HairSystemCore& llCore = mCore.getShapeCore().getLLCore(); const PxVec3 dimensions = bounds.getDimensions(); const PxReal maxXZ = PxMax(dimensions.x, dimensions.z); // rotations in plane perpendicular to gravity are very likely const PxReal cellSize = llCore.mParams.getCellSize(); - llCore.mParams.mGridSize[0] = 2 * PxNextPowerOfTwo(1u + static_cast(maxXZ / cellSize)); - llCore.mParams.mGridSize[1] = 2 * PxNextPowerOfTwo(1u + static_cast(dimensions.y / cellSize)); + + const PxU32 tightGridSizeXZ = static_cast(maxXZ / cellSize) + 1; + const PxU32 tightGridSizeY = static_cast(dimensions.y / cellSize) + 1; + + PxU32 gridSizeXZ = PxNextPowerOfTwo(tightGridSizeXZ); + PxU32 gridSizeY = PxNextPowerOfTwo(tightGridSizeY); + + if(gridSizeXZ < 1.5f * tightGridSizeXZ) + gridSizeXZ *= 2; + if(gridSizeY < 1.5f * tightGridSizeY) + gridSizeY *= 2; + + llCore.mParams.mGridSize[0] = gridSizeXZ; + llCore.mParams.mGridSize[1] = gridSizeY; llCore.mParams.mGridSize[2] = llCore.mParams.mGridSize[0]; if (static_cast(dimensions.maxElement() / cellSize) > 512) PxGetFoundation().error(physx::PxErrorCode::eDEBUG_WARNING, __FILE__, __LINE__, - "Grid of hair system appears very large. Double check ratio of segment" - " length to extent of the hair system defined by the vertices."); + "Grid of hair system appears very large (%i by %i by %i). Double check ratio of segment" + " length (%f) to extent of the hair system defined by the vertices (%f, %f, %f).", + llCore.mParams.mGridSize[0], llCore.mParams.mGridSize[1], llCore.mParams.mGridSize[2], + static_cast(llCore.mParams.mSegmentLength), static_cast(dimensions.x), + static_cast(dimensions.y), static_cast(dimensions.z)); } void NpHairSystem::createAllocator() @@ -606,7 +724,6 @@ namespace physx mVelInternal.reset(); // create internal buffers - createAllocator(); if (desc.flags.isSet(PxHairSystemDescFlag::eDEVICE_MEMORY)) { mPosInvMassInternal.setAllocatorCallback(mDeviceMemoryAllocator); diff --git a/physx/source/physx/src/NpHairSystem.h b/physx/source/physx/src/NpHairSystem.h index cd5c84e24..496c4c27f 100644 --- a/physx/source/physx/src/NpHairSystem.h +++ b/physx/source/physx/src/NpHairSystem.h @@ -28,6 +28,7 @@ #define NP_HAIR_SYSTEM_H #include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION #include "PxHairSystem.h" #include "ScHairSystemCore.h" @@ -179,6 +180,10 @@ namespace physx virtual void setRigidAttachments(PxParticleRigidAttachment* attachments, PxU32 numAttachments, bool isGpuPtr) PX_OVERRIDE; virtual PxParticleRigidAttachment* getRigidAttachmentsGpu(PxU32* numAttachments = NULL) PX_OVERRIDE; + virtual PxU32 addSoftbodyAttachment(const PxSoftBody& softbody, const PxU32* tetIds, const PxVec4* tetmeshBarycentrics, + const PxU32* hairVertices, PxU32 numAttachments) PX_OVERRIDE; + virtual void removeSoftbodyAttachment(const PxSoftBody& softbody, PxU32 handle) PX_OVERRIDE; + virtual void initFromDesc(const PxHairSystemDesc& desc) PX_OVERRIDE; virtual void setTopology(PxVec4* vertexPositionsInvMass, PxVec4* vertexVelocities, @@ -239,6 +244,7 @@ namespace physx const char* getName() const; private: + void init(); void setLlGridSize(const PxBounds3& bounds); void createAllocator(); void releaseAllocator(); @@ -266,10 +272,13 @@ namespace physx PxArray mLodProportionOfStrands; PxArray mLodProportionOfVertices; + PxHashMap> mSoftbodyAttachmentsOffsets; // map from handle to {offset, size} + PxPinnedArray mSoftbodyAttachments; + const PxRigidActor* mRestPositionActor; }; } #endif - +#endif #endif diff --git a/physx/source/physx/src/NpMPMMaterial.cpp b/physx/source/physx/src/NpMPMMaterial.cpp index 366af88a9..d45e7ec82 100644 --- a/physx/source/physx/src/NpMPMMaterial.cpp +++ b/physx/source/physx/src/NpMPMMaterial.cpp @@ -44,7 +44,7 @@ NpMPMMaterial::NpMPMMaterial(const PxsMPMMaterialCore& desc) : NpMPMMaterial::~NpMPMMaterial() { - NpPhysics::getInstance().removeMPMMaterialFromTable(*this); + NpPhysics::getInstance().removeMaterialFromTable(*this); } // PX_SERIALIZATION @@ -101,7 +101,7 @@ PxU32 NpMPMMaterial::getReferenceCount() const PX_INLINE void NpMPMMaterial::updateMaterial() { - NpPhysics::getInstance().updateMPMMaterial(*this); + NpPhysics::getInstance().updateMaterial(*this); } /////////////////////////////////////////////////////////////////////////////// diff --git a/physx/source/physx/src/NpMPMMaterial.h b/physx/source/physx/src/NpMPMMaterial.h index b007810f3..61a98c358 100644 --- a/physx/source/physx/src/NpMPMMaterial.h +++ b/physx/source/physx/src/NpMPMMaterial.h @@ -46,12 +46,6 @@ namespace physx class NpMPMMaterial : public PxMPMMaterial, 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. - //================================================================================================== public: // PX_SERIALIZATION NpMPMMaterial(PxBaseFlags baseFlags) : PxMPMMaterial(baseFlags), mMaterial(PxEmpty) {} diff --git a/physx/source/physx/src/NpMaterial.cpp b/physx/source/physx/src/NpMaterial.cpp index 7995e411c..d0f90399e 100644 --- a/physx/source/physx/src/NpMaterial.cpp +++ b/physx/source/physx/src/NpMaterial.cpp @@ -43,7 +43,7 @@ NpMaterial::NpMaterial(const PxsMaterialCore& desc) : NpMaterial::~NpMaterial() { - OMNI_PVD_DESTROY(material, static_cast(*this)) + OMNI_PVD_DESTROY(PxMaterial, static_cast(*this)) NpPhysics::getInstance().removeMaterialFromTable(*this); } @@ -110,7 +110,7 @@ void NpMaterial::setDynamicFriction(PxReal x) PX_CHECK_AND_RETURN(PxIsFinite(x), "PxMaterial::setDynamicFriction: invalid float"); mMaterial.dynamicFriction = x; updateMaterial(); - OMNI_PVD_SET(material, dynamicFriction, static_cast(*this), x) + OMNI_PVD_SET(PxMaterial, dynamicFriction, static_cast(*this), x) } PxReal NpMaterial::getDynamicFriction() const @@ -125,7 +125,7 @@ void NpMaterial::setStaticFriction(PxReal x) PX_CHECK_AND_RETURN(PxIsFinite(x), "PxMaterial::setStaticFriction: invalid float"); mMaterial.staticFriction = x; updateMaterial(); - OMNI_PVD_SET(material, staticFriction, static_cast(*this), x) + OMNI_PVD_SET(PxMaterial, staticFriction, static_cast(*this), x) } PxReal NpMaterial::getStaticFriction() const @@ -146,7 +146,7 @@ void NpMaterial::setRestitution(PxReal x) } mMaterial.restitution = x; updateMaterial(); - OMNI_PVD_SET(material, restitution, static_cast(*this), x) + OMNI_PVD_SET(PxMaterial, restitution, static_cast(*this), x) } PxReal NpMaterial::getRestitution() const @@ -167,7 +167,7 @@ void NpMaterial::setDamping(PxReal x) } mMaterial.damping = x; updateMaterial(); - OMNI_PVD_SET(material, damping, static_cast(*this), x) + OMNI_PVD_SET(PxMaterial, damping, static_cast(*this), x) } PxReal NpMaterial::getDamping() const @@ -184,14 +184,14 @@ void NpMaterial::setFlag(PxMaterialFlag::Enum flag, bool value) else mMaterial.flags &= ~PxMaterialFlags(flag); updateMaterial(); - OMNI_PVD_SET(material, flags, static_cast(*this), mMaterial.flags) + OMNI_PVD_SET(PxMaterial, flags, static_cast(*this), mMaterial.flags) } void NpMaterial::setFlags(PxMaterialFlags inFlags) { mMaterial.flags = inFlags; updateMaterial(); - OMNI_PVD_SET(material, flags, static_cast(*this), mMaterial.flags) + OMNI_PVD_SET(PxMaterial, flags, static_cast(*this), mMaterial.flags) } PxMaterialFlags NpMaterial::getFlags() const @@ -205,7 +205,7 @@ void NpMaterial::setFrictionCombineMode(PxCombineMode::Enum x) { mMaterial.setFrictionCombineMode(x); updateMaterial(); - OMNI_PVD_SET(material, frictionCombineMode, static_cast(*this), x) + OMNI_PVD_SET(PxMaterial, frictionCombineMode, static_cast(*this), x) } PxCombineMode::Enum NpMaterial::getFrictionCombineMode() const @@ -219,7 +219,7 @@ void NpMaterial::setRestitutionCombineMode(PxCombineMode::Enum x) { mMaterial.setRestitutionCombineMode(x); updateMaterial(); - OMNI_PVD_SET(material, restitutionCombineMode, static_cast(*this), x) + OMNI_PVD_SET(PxMaterial, restitutionCombineMode, static_cast(*this), x) } PxCombineMode::Enum NpMaterial::getRestitutionCombineMode() const diff --git a/physx/source/physx/src/NpMaterial.h b/physx/source/physx/src/NpMaterial.h index 9ab223b55..a91fc4065 100644 --- a/physx/source/physx/src/NpMaterial.h +++ b/physx/source/physx/src/NpMaterial.h @@ -44,12 +44,6 @@ namespace physx class NpMaterial : public PxMaterial, 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. -//================================================================================================== public: // PX_SERIALIZATION NpMaterial(PxBaseFlags baseFlags) : PxMaterial(baseFlags), mMaterial(PxEmpty) {} diff --git a/physx/source/physx/src/NpMetaData.cpp b/physx/source/physx/src/NpMetaData.cpp index b42c4ad7c..b3e91b5d4 100644 --- a/physx/source/physx/src/NpMetaData.cpp +++ b/physx/source/physx/src/NpMetaData.cpp @@ -114,6 +114,13 @@ static void getBinaryMetaData_PxTransform(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, PxTransform, PxVec3, p, 0) } +static void getBinaryMetaData_PxTransform32(PxOutputStream& stream) +{ + PX_DEF_BIN_METADATA_CLASS(stream, PxTransform32) + PX_DEF_BIN_METADATA_BASE_CLASS(stream, PxTransform32, PxTransform) + PX_DEF_BIN_METADATA_ITEM(stream, PxTransform32, PxU32, padding, 0) +} + static void getBinaryMetaData_PxMat33(PxOutputStream& stream) { PX_DEF_BIN_METADATA_CLASS(stream, PxMat33) @@ -247,16 +254,6 @@ void NpPBDMaterial::getBinaryMetaData(PxOutputStream& stream) /////////////////////////////////////////////////////////////////////////////// #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -void NpCustomMaterial::getBinaryMetaData(PxOutputStream& stream) -{ - PX_DEF_BIN_METADATA_VCLASS(stream, NpCustomMaterial) - PX_DEF_BIN_METADATA_BASE_CLASS(stream, NpCustomMaterial, PxBase) - - PX_DEF_BIN_METADATA_ITEM(stream, NpCustomMaterial, void, userData, PxMetaDataFlag::ePTR) - PX_DEF_BIN_METADATA_ITEM(stream, NpCustomMaterial, PxsCustomMaterialCore, mMaterial, 0) -} - -/////////////////////////////////////////////////////////////////////////////// void NpFLIPMaterial::getBinaryMetaData(PxOutputStream& stream) { @@ -314,12 +311,12 @@ void NpShape::getBinaryMetaData(PxOutputStream& stream) PX_DEF_BIN_METADATA_BASE_CLASS(stream, NpShape, NpBase) // PxShape - PX_DEF_BIN_METADATA_ITEM(stream, NpShape, void, userData, PxMetaDataFlag::ePTR) + PX_DEF_BIN_METADATA_ITEM(stream, NpShape, void, userData, PxMetaDataFlag::ePTR) // NpShape - PX_DEF_BIN_METADATA_ITEM(stream, NpShape, PxRigidActor, mActor, PxMetaDataFlag::ePTR) - PX_DEF_BIN_METADATA_ITEM(stream, NpShape, ShapeCore, mCore, 0) - PX_DEF_BIN_METADATA_ITEM(stream, NpShape, PxFilterData, mQueryFilterData, 0) + PX_DEF_BIN_METADATA_ITEM(stream, NpShape, PxRigidActor, mExclusiveShapeActor, PxMetaDataFlag::ePTR) + PX_DEF_BIN_METADATA_ITEM(stream, NpShape, ShapeCore, mCore, 0) + PX_DEF_BIN_METADATA_ITEM(stream, NpShape, PxFilterData, mQueryFilterData, 0) } /////////////////////////////////////////////////////////////////////////////// @@ -742,6 +739,7 @@ static void getFoundationMetaData(PxOutputStream& stream) getBinaryMetaData_PxQuat(stream); getBinaryMetaData_PxBounds3(stream); getBinaryMetaData_PxTransform(stream); + getBinaryMetaData_PxTransform32(stream); getBinaryMetaData_PxMat33(stream); getBinaryMetaData_SpatialVectorF(stream); getBinaryMetaData_BitMap(stream); @@ -761,7 +759,6 @@ template<> void PxsMaterialCore::getBinaryMetaData(PxOutputStream& stream); template<> void PxsFEMSoftBodyMaterialCore::getBinaryMetaData(PxOutputStream& stream); template<> void PxsFEMClothMaterialCore::getBinaryMetaData(PxOutputStream& stream); template<> void PxsPBDMaterialCore::getBinaryMetaData(PxOutputStream& stream); -template<> void PxsCustomMaterialCore::getBinaryMetaData(PxOutputStream& stream); template<> void PxsFLIPMaterialCore::getBinaryMetaData(PxOutputStream& stream); template<> void PxsMPMMaterialCore::getBinaryMetaData(PxOutputStream& stream); } @@ -781,7 +778,6 @@ void PxGetPhysicsBinaryMetaData(PxOutputStream& stream) PxsFEMSoftBodyMaterialCore::getBinaryMetaData(stream); PxsFEMClothMaterialCore::getBinaryMetaData(stream); PxsPBDMaterialCore::getBinaryMetaData(stream); - PxsCustomMaterialCore::getBinaryMetaData(stream); PxsFLIPMaterialCore::getBinaryMetaData(stream); PxsMPMMaterialCore::getBinaryMetaData(stream); @@ -813,7 +809,6 @@ void PxGetPhysicsBinaryMetaData(PxOutputStream& stream) #endif NpPBDMaterial::getBinaryMetaData(stream); #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpCustomMaterial::getBinaryMetaData(stream); NpFLIPMaterial::getBinaryMetaData(stream); NpMPMMaterial::getBinaryMetaData(stream); #endif diff --git a/physx/source/physx/src/NpPBDMaterial.cpp b/physx/source/physx/src/NpPBDMaterial.cpp index 136063148..b528898e1 100644 --- a/physx/source/physx/src/NpPBDMaterial.cpp +++ b/physx/source/physx/src/NpPBDMaterial.cpp @@ -43,7 +43,7 @@ NpPBDMaterial::NpPBDMaterial(const PxsPBDMaterialCore& desc) : NpPBDMaterial::~NpPBDMaterial() { - NpPhysics::getInstance().removePBDMaterialFromTable(*this); + NpPhysics::getInstance().removeMaterialFromTable(*this); } // PX_SERIALIZATION @@ -100,7 +100,7 @@ PxU32 NpPBDMaterial::getReferenceCount() const PX_INLINE void NpPBDMaterial::updateMaterial() { - NpPhysics::getInstance().updatePBDMaterial(*this); + NpPhysics::getInstance().updateMaterial(*this); } /////////////////////////////////////////////////////////////////////////////// @@ -275,143 +275,6 @@ PxReal NpPBDMaterial::getGravityScale() const return mMaterial.gravityScale; } -/////////////////////////////////////////////////////////////////////////////// -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -NpCustomMaterial::NpCustomMaterial(const PxsCustomMaterialCore& desc) : - PxCustomMaterial(PxConcreteType::eCUSTOM_MATERIAL, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), - mMaterial(desc) -{ - mMaterial.mMaterial = this; // back-reference -} - -NpCustomMaterial::~NpCustomMaterial() -{ - NpPhysics::getInstance().removeCustomMaterialFromTable(*this); -} - -// PX_SERIALIZATION -void NpCustomMaterial::resolveReferences(PxDeserializationContext&) -{ - // ### this one could be automated if NpMaterial would inherit from MaterialCore - // ### well actually in that case the pointer would not even be needed.... - mMaterial.mMaterial = this; // Resolve MaterialCore::mMaterial - - // Maybe not the best place to do it but it has to be done before the shapes resolve material indices - // since the material index translation table is needed there. This requires that the materials have - // been added to the table already. - // PT: TODO: missing line here? -} - -void NpCustomMaterial::onRefCountZero() -{ - void* ud = userData; - - if (getBaseFlags() & PxBaseFlag::eOWNS_MEMORY) - { - NpFactory::getInstance().releaseCustomMaterialToPool(*this); - } - else - this->~NpCustomMaterial(); - - NpPhysics::getInstance().notifyDeletionListenersMemRelease(this, ud); -} - -NpCustomMaterial* NpCustomMaterial::createObject(PxU8*& address, PxDeserializationContext& context) -{ - NpCustomMaterial* obj = PX_PLACEMENT_NEW(address, NpCustomMaterial(PxBaseFlag::eIS_RELEASABLE)); - address += sizeof(NpCustomMaterial); - obj->importExtraData(context); - obj->resolveReferences(context); - return obj; -} -//~PX_SERIALIZATION - -void NpCustomMaterial::release() -{ - RefCountable_decRefCount(*this); -} - -void NpCustomMaterial::acquireReference() -{ - RefCountable_incRefCount(*this); -} - -PxU32 NpCustomMaterial::getReferenceCount() const -{ - return RefCountable_getRefCount(*this); -} - -PX_INLINE void NpCustomMaterial::updateMaterial() -{ - NpPhysics::getInstance().updateCustomMaterial(*this); -} - -void NpCustomMaterial::setFriction(PxReal x) -{ - PX_UNUSED(x); -} - -PxReal NpCustomMaterial::getFriction() const -{ - return 0.0f; -} - -void NpCustomMaterial::setDamping(PxReal x) -{ - PX_UNUSED(x); -} - -PxReal NpCustomMaterial::getDamping() const -{ - return 0.0f; -} - - -/////////////////////////////////////////////////////////////////////////////// - -void NpCustomMaterial::setAdhesion(PxReal x) -{ - PX_CHECK_AND_RETURN(x >= 0.f, "PxCustomMaterial::setAdhesion: invalid float"); - mMaterial.adhesion = x; - - updateMaterial(); -} - -PxReal NpCustomMaterial::getAdhesion() const -{ - return mMaterial.adhesion; -} - -/////////////////////////////////////////////////////////////////////////////// - -void NpCustomMaterial::setGravityScale(PxReal x) -{ - PX_CHECK_AND_RETURN(PxIsFinite(x), "PxCustomMaterial::setAdhesion: invalid float"); - mMaterial.gravityScale = x; - - updateMaterial(); -} - -PxReal NpCustomMaterial::getGravityScale() const -{ - return mMaterial.gravityScale; -} - -/////////////////////////////////////////////////////////////////////////////// - -void NpCustomMaterial::setAdhesionRadiusScale(PxReal x) -{ - PX_CHECK_AND_RETURN(x >= 0.f , "PxCustomMaterial::setAdhesionRadiusScale: scale must be positive"); - mMaterial.adhesionRadiusScale = x; - - updateMaterial(); -} -PxReal NpCustomMaterial::getAdhesionRadiusScale() const -{ - return mMaterial.adhesionRadiusScale; -} -#endif - ////////////////////////////////////////////////////////////////////////////// void NpPBDMaterial::setAdhesionRadiusScale(PxReal x) diff --git a/physx/source/physx/src/NpPBDMaterial.h b/physx/source/physx/src/NpPBDMaterial.h index 5d53c47ca..a54d2924f 100644 --- a/physx/source/physx/src/NpPBDMaterial.h +++ b/physx/source/physx/src/NpPBDMaterial.h @@ -45,12 +45,6 @@ namespace physx class NpPBDMaterial : public PxPBDMaterial, 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. - //================================================================================================== public: // PX_SERIALIZATION NpPBDMaterial(PxBaseFlags baseFlags) : PxPBDMaterial(baseFlags), mMaterial(PxEmpty) {} @@ -126,72 +120,6 @@ namespace physx for (PxU32 i = 0; i < materialCount; i++) materialIndices[i] = static_cast(materials[i])->mMaterial.mMaterialIndex; } - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - class NpCustomMaterial : public PxCustomMaterial, 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. - //================================================================================================== - public: - // PX_SERIALIZATION - NpCustomMaterial(PxBaseFlags baseFlags) : PxCustomMaterial(baseFlags), mMaterial(PxEmpty) {} - virtual void resolveReferences(PxDeserializationContext& context); - static NpCustomMaterial* createObject(PxU8*& address, PxDeserializationContext& context); - static void getBinaryMetaData(PxOutputStream& stream); - - // PxBase - virtual void onRefCountZero(); - //~PxBase - - void preExportDataReset() { Cm::RefCountable_preExportDataReset(*this); } - void exportExtraData(PxSerializationContext&) {} - void importExtraData(PxDeserializationContext&) {} - virtual void requiresObjects(PxProcessPxBaseCallback&) {} - //~PX_SERIALIZATION - NpCustomMaterial(const PxsCustomMaterialCore& desc); - virtual ~NpCustomMaterial(); - - virtual void release(); - - // PxRefCounted - virtual void acquireReference(); - virtual PxU32 getReferenceCount() const; - //~PxRefCounted - - // PxParticleMaterial - virtual void setFriction(PxReal friction) PX_OVERRIDE; - virtual PxReal getFriction() const PX_OVERRIDE; - virtual void setDamping(PxReal damping) PX_OVERRIDE; - virtual PxReal getDamping() const PX_OVERRIDE; - virtual void setAdhesion(PxReal adhesion) PX_OVERRIDE; - virtual PxReal getAdhesion() const PX_OVERRIDE; - virtual void setGravityScale(PxReal scale) PX_OVERRIDE; - virtual PxReal getGravityScale() const PX_OVERRIDE; - virtual void setAdhesionRadiusScale(PxReal scale) PX_OVERRIDE; - virtual PxReal getAdhesionRadiusScale() const PX_OVERRIDE; - //~PxParticleMaterial - - PX_FORCE_INLINE static void getMaterialIndices(NpCustomMaterial*const* materials, PxU16* materialIndices, PxU32 materialCount); - - private: - PX_INLINE void updateMaterial(); - - // PX_SERIALIZATION - public: - //~PX_SERIALIZATION - PxsCustomMaterialCore mMaterial; - }; - - PX_FORCE_INLINE void NpCustomMaterial::getMaterialIndices(NpCustomMaterial*const* materials, PxU16* materialIndices, PxU32 materialCount) - { - for (PxU32 i = 0; i < materialCount; i++) - materialIndices[i] = static_cast(materials[i])->mMaterial.mMaterialIndex; - } -#endif } #endif diff --git a/physx/source/physx/src/NpParticleSystem.cpp b/physx/source/physx/src/NpParticleSystem.cpp index 51a63f696..ee1ba047b 100644 --- a/physx/source/physx/src/NpParticleSystem.cpp +++ b/physx/source/physx/src/NpParticleSystem.cpp @@ -1033,131 +1033,6 @@ namespace physx internalRemoveRigidAttachment(actor, mCore); } - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - NpCustomParticleSystem::NpCustomParticleSystem(PxCudaContextManager& cudaContextManager, PxU32 maxNeighborhood) : - NpParticleSystem(cudaContextManager, PxConcreteType::eCUSTOM_PARTICLESYSTEM, NpType::eCUSTOM_PARTICLESYSTEM, PxActorType::eCUSTOM_PARTICLESYSTEM) - { - //PX_ASSERT(mCudaContextManager); - setSolverType(PxParticleSolverType::eCUSTOM); - mCore.getShapeCore().initializeLLCoreData(maxNeighborhood); - enableCCD(false); - } - - void NpCustomParticleSystem::release() - { - NpScene* npScene = getNpScene(); - NP_WRITE_CHECK(npScene); - - // NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, PxArticulationBase::userData); - - if (npScene) - { - npScene->scRemoveParticleSystem(*this); - npScene->removeFromParticleSystemList(*this); - } - - PX_ASSERT(!isAPIWriteForbidden()); - NpDestroyParticleSystem(this); - } - - void NpCustomParticleSystem::getSparseGridCoord(PxI32& x, PxI32& y, PxI32& z, PxU32 id) - { - const PxI32 iid = static_cast(id); - x = iid % MAX_SPARSEGRID_DIM + MIN_SPARSEGRID_ID; - y = (iid / MAX_SPARSEGRID_DIM) % MAX_SPARSEGRID_DIM + MIN_SPARSEGRID_ID; - z = iid / MAX_SPARSEGRID_DIM / MAX_SPARSEGRID_DIM + MIN_SPARSEGRID_ID; - } - - void* NpCustomParticleSystem::getSparseGridDataPointer(PxSparseGridDataFlag::Enum flags) - { - if ((flags & (PxSparseGridDataFlag::eSUBGRID_MASK | PxSparseGridDataFlag::eSUBGRID_ID - | PxSparseGridDataFlag::eGRIDCELL_SOLID_GRADIENT_AND_SDF | PxSparseGridDataFlag::eGRIDCELL_SOLID_VELOCITY - | PxSparseGridDataFlag::eGRIDCELL_FLUID_SDF | PxSparseGridDataFlag::eGRIDCELL_FLUID_VELOCITY - )) == 0) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, PX_FL, "PxParticleSystem::copySparseGridData, specified data is not available."); - return NULL; - } - - NP_READ_CHECK(getNpScene()); - - NpScene* scene = getNpScene(); - return scene->getSimulationController()->getSparseGridDataPointer(*getCore().getSim()->getLowLevelParticleSystem(), flags, getCore().getSolverType()); - } - -#if PX_ENABLE_DEBUG_VISUALIZATION - void NpCustomParticleSystem::visualize(PxRenderOutput& out, NpScene& npScene) const - { - visualizeParticleSystem(out, npScene, mCore); - } -#else - PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION -#endif - - void NpCustomParticleSystem::addParticleBuffer(PxParticleBuffer* particleBuffer) - { - NP_WRITE_CHECK(getNpScene()); - PX_CHECK_AND_RETURN(getNpScene() != NULL, "NpCustomParticleSystem::addParticleBuffer: this function cannot be called when the particle system is not inserted into the scene!"); - - if (particleBuffer->getConcreteType() == PxConcreteType::ePARTICLE_BUFFER) - { - mCore.getShapeCore().addParticleBuffer(particleBuffer); - } - else - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "NpCustomParticleSystem:addParticleBuffer(): the provided buffer type is not supported by this type of particle system."); - } - } - - void NpCustomParticleSystem::removeParticleBuffer(PxParticleBuffer* particleBuffer) - { - if (particleBuffer->getConcreteType() == PxConcreteType::ePARTICLE_BUFFER) - { - mCore.getShapeCore().removeParticleBuffer(particleBuffer); - } - else - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "NpCustomParticleSystem:addParticleBuffer(): the provided buffer type is not supported by this type of particle system."); - } - } - - PxU32 NpCustomParticleSystem::createPhase(PxParticleMaterial* material, const PxParticlePhaseFlags flags) - { - if (material->getConcreteType() == PxConcreteType::eCUSTOM_MATERIAL) - { - Sc::ParticleSystemShapeCore& shapeCore = mCore.getShapeCore(); - Dy::ParticleSystemCore& core = shapeCore.getLLCore(); - - PxU16 materialHandle = static_cast(material)->mMaterial.mMaterialIndex; - - const PxU32 groupID = mNextPhaseGroupID++; - - core.mPhaseGroupToMaterialHandle.pushBack(materialHandle); - - if (mCore.getSim()) - mCore.getSim()->getLowLevelParticleSystem()->mFlag |= Dy::ParticleSystemFlag::eUPDATE_PHASE; - - return (groupID & PxParticlePhaseFlag::eParticlePhaseGroupMask) - | (PxU32(flags) & PxParticlePhaseFlag::eParticlePhaseFlagsMask); - } - else - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxCustomParticleSystem:createPhase(): the provided material is not supported by this type of particle system."); - return 0; - } - } - - void NpCustomParticleSystem::setCustomParticleCallback(PxCustomParticleSystemSolverCallback* callback) - { - mCore.setParticleSystemSolverCallback(callback); - } - PxCustomParticleSystemSolverCallback* - NpCustomParticleSystem::getCustomParticleCallback() const - { - return mCore.getParticleSystemSolverCallback(); - } #endif } diff --git a/physx/source/physx/src/NpParticleSystem.h b/physx/source/physx/src/NpParticleSystem.h index 55f59932f..664e29bc2 100644 --- a/physx/source/physx/src/NpParticleSystem.h +++ b/physx/source/physx/src/NpParticleSystem.h @@ -58,7 +58,6 @@ #include "ScParticleSystemSim.h" #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -#include "PxCustomParticleSystem.h" #include "PxFLIPParticleSystem.h" #include "PxFLIPMaterial.h" #include "PxMPMParticleSystem.h" @@ -194,12 +193,15 @@ namespace physx flags.raise(flag); else flags.clear(flag); + mCore.setFlags(flags); + scSetDirtyFlag(); } virtual void setParticleFlags(PxParticleFlags flags) { mCore.setFlags(flags); + scSetDirtyFlag(); } virtual PxParticleFlags getParticleFlags() const @@ -218,18 +220,6 @@ namespace physx return shapeCore.getNbMaterialIndices(); } - virtual void setPeriodicBoundary(const PxVec3& boundary) - { - mCore.setPeriodicBoundary(boundary); - scSetDirtyFlag(); - } - - - virtual PxVec3 getPeriodicBoundary() const - { - return mCore.getPeriodicBoundary(); - } - virtual void addParticleBuffer(PxParticleBuffer* userBuffer) = 0; virtual void removeParticleBuffer(PxParticleBuffer* userBuffer) = 0; @@ -238,7 +228,7 @@ namespace physx NP_READ_CHECK(NpBase::getNpScene()); PX_CHECK_AND_RETURN_VAL(NpBase::getNpScene(), "NpParticleSystem::getGpuParticleSystemIndex: particle system must be in a scene.", 0xffffffff); - if (NpBase::getNpScene()->getFlags() & PxSceneFlag::eSUPPRESS_READBACK) + if (NpBase::getNpScene()->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) return mCore.getSim()->getLowLevelParticleSystem()->getGpuRemapId(); return 0xffffffff; } @@ -584,46 +574,6 @@ namespace physx //UPDATE_PVD_PROPERTY } }; - - class NpCustomParticleSystem : public NpParticleSystem - { - public: - - NpCustomParticleSystem(PxCudaContextManager& contextManager, PxU32 maxNeighborhood); - - virtual ~NpCustomParticleSystem() {} - - virtual void release(); - - - - virtual void setSparseGridParams(const PxSparseGridParams& params) { scSetSparseGridParams(params); } - virtual PxSparseGridParams getSparseGridParams() const { return mCore.getSparseGridParams(); } - - virtual void* getSparseGridDataPointer(PxSparseGridDataFlag::Enum flags); - - virtual void getSparseGridCoord(PxI32& x, PxI32& y, PxI32& z, PxU32 id); - - virtual PxU32 createPhase(PxParticleMaterial* material, PxParticlePhaseFlags flags) PX_OVERRIDE; - -#if PX_ENABLE_DEBUG_VISUALIZATION - virtual void visualize(PxRenderOutput& out, NpScene& npScene) const; -#else - PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION -#endif - - virtual void addParticleBuffer(PxParticleBuffer* particleBuffer); - virtual void removeParticleBuffer(PxParticleBuffer* particleBuffer); - - virtual void addRigidAttachment(PxRigidActor* /*actor*/) {} - virtual void removeRigidAttachment(PxRigidActor* /*actor*/) {} - - //external API - virtual PxActorType::Enum getType() const { return PxActorType::eCUSTOM_PARTICLESYSTEM; } - - virtual void setCustomParticleCallback(PxCustomParticleSystemSolverCallback* callback); - virtual PxCustomParticleSystemSolverCallback* getCustomParticleCallback() const; - }; #endif } diff --git a/physx/source/physx/src/NpPhysics.cpp b/physx/source/physx/src/NpPhysics.cpp index 8c7ef78a7..d874793e8 100644 --- a/physx/source/physx/src/NpPhysics.cpp +++ b/physx/source/physx/src/NpPhysics.cpp @@ -90,10 +90,6 @@ bool NpPhysics::apiReentryLock = false; NpPhysics* NpPhysics::mInstance = NULL; PxU32 NpPhysics::mRefCount = 0; -#if PX_CHECKED -bool NpPhysics::mHeightFieldsRegistered = false; //just for error checking -#endif - NpPhysics::NpPhysics(const PxTolerancesScale& scale, const PxvOffsetTable& pxvOffsetTable, bool trackOutstandingAllocations, pvdsdk::PsPvd* pvd, PxFoundation& foundation, PxOmniPvd* omniPvd) : mSceneArray ("physicsSceneArray"), mPhysics (scale, pxvOffsetTable), @@ -189,15 +185,14 @@ NpPhysics::~NpPhysics() //mMasterMaterialTable.clear(); mMasterMaterialManager.releaseMaterials(); +#if PX_SUPPORT_GPU_PHYSX mMasterFEMSoftBodyMaterialManager.releaseMaterials(); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - mMasterFEMClothMaterialManager.releaseMaterials(); -#endif mMasterPBDMaterialManager.releaseMaterials(); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + mMasterFEMClothMaterialManager.releaseMaterials(); mMasterFLIPMaterialManager.releaseMaterials(); mMasterMPMMaterialManager.releaseMaterials(); - mMasterCustomMaterialManager.releaseMaterials(); + #endif #endif #if PX_SUPPORT_PVD @@ -221,13 +216,19 @@ NpPhysics::~NpPhysics() mDeletionListenerMap.clear(); #if PX_SUPPORT_OMNI_PVD - OMNI_PVD_DESTROY(physics, static_cast(*this)) + OMNI_PVD_DESTROY(PxPhysics, static_cast(*this)) PX_DELETE(mOmniPvdSampler); if (mOmniPvd) { NpOmniPvd::decRefCount(); } #endif + +#if PX_SUPPORT_GPU_PHYSX + PxPhysXGpu* gpu = PxvGetPhysXGpu(false); + if (gpu) + PxvReleasePhysXGpu(gpu); +#endif } PxOmniPvd* NpPhysics::getOmniPvd() @@ -244,23 +245,22 @@ void NpPhysics::initOffsetTables(PxvOffsetTable& pxvOffsetTable) // init offset tables for Pxs/Sc/Px conversions { Sc::OffsetTable& offsetTable = Sc::gOffsetTable; - offsetTable.scRigidStatic2PxActor = -ptrdiff_t(NpRigidStatic::getCoreOffset()); - offsetTable.scRigidDynamic2PxActor = -ptrdiff_t(NpRigidDynamic::getCoreOffset()); - offsetTable.scArticulationLink2PxActor = -ptrdiff_t(NpArticulationLink::getCoreOffset()); + offsetTable.scRigidStatic2PxActor = -ptrdiff_t(NpRigidStatic::getCoreOffset()); + offsetTable.scRigidDynamic2PxActor = -ptrdiff_t(NpRigidDynamic::getCoreOffset()); + offsetTable.scArticulationLink2PxActor = -ptrdiff_t(NpArticulationLink::getCoreOffset()); #if PX_SUPPORT_GPU_PHYSX - offsetTable.scSoftBody2PxActor = -ptrdiff_t(NpSoftBody::getCoreOffset()); - offsetTable.scPBDParticleSystem2PxActor = -ptrdiff_t(NpPBDParticleSystem::getCoreOffset()); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - offsetTable.scFLIPParticleSystem2PxActor = -ptrdiff_t(NpFLIPParticleSystem::getCoreOffset()); - offsetTable.scMPMParticleSystem2PxActor = -ptrdiff_t(NpMPMParticleSystem::getCoreOffset()); - offsetTable.scCustomParticleSystem2PxActor = -ptrdiff_t(NpCustomParticleSystem::getCoreOffset()); - offsetTable.scHairSystem2PxActor = -ptrdiff_t(NpHairSystem::getCoreOffset()); -#endif -#endif - offsetTable.scArticulationRC2Px = -ptrdiff_t(NpArticulationReducedCoordinate::getCoreOffset()); - offsetTable.scArticulationJointRC2Px = -ptrdiff_t(NpArticulationJointReducedCoordinate::getCoreOffset()); - offsetTable.scConstraint2Px = -ptrdiff_t(NpConstraint::getCoreOffset()); - offsetTable.scShape2Px = -ptrdiff_t(NpShape::getCoreOffset()); + offsetTable.scSoftBody2PxActor = -ptrdiff_t(NpSoftBody::getCoreOffset()); + offsetTable.scPBDParticleSystem2PxActor = -ptrdiff_t(NpPBDParticleSystem::getCoreOffset()); + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + offsetTable.scFLIPParticleSystem2PxActor = -ptrdiff_t(NpFLIPParticleSystem::getCoreOffset()); + offsetTable.scMPMParticleSystem2PxActor = -ptrdiff_t(NpMPMParticleSystem::getCoreOffset()); + offsetTable.scHairSystem2PxActor = -ptrdiff_t(NpHairSystem::getCoreOffset()); + #endif +#endif + offsetTable.scArticulationRC2Px = -ptrdiff_t(NpArticulationReducedCoordinate::getCoreOffset()); + offsetTable.scArticulationJointRC2Px = -ptrdiff_t(NpArticulationJointReducedCoordinate::getCoreOffset()); + offsetTable.scConstraint2Px = -ptrdiff_t(NpConstraint::getCoreOffset()); + offsetTable.scShape2Px = -ptrdiff_t(NpShape::getCoreOffset()); for(PxU32 i=0;igetTaskManagerFast()) { - mFoundation.error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Unable to create scene. Task manager creation failed."); + mFoundation.error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Unable to create scene. Task manager creation failed."); return NULL; } npScene->loadFromDesc(desc); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_ADD(physics, scenes, static_cast(*this), static_cast(*npScene)) -#endif + OMNI_PVD_ADD(PxPhysics, scenes, static_cast(*this), static_cast(*npScene)) #if PX_SUPPORT_PVD if(mPvd) @@ -405,7 +402,7 @@ PxScene* NpPhysics::createScene(const PxSceneDesc& desc) if (!sendMaterialTable(*npScene) || !npScene->getScScene().isValid()) { PX_DELETE(npScene); - mFoundation.error(PxErrorCode::eOUT_OF_MEMORY, __FILE__, __LINE__, "Unable to create scene."); + mFoundation.error(PxErrorCode::eOUT_OF_MEMORY, PX_FL, "Unable to create scene."); return NULL; } @@ -417,9 +414,7 @@ void NpPhysics::releaseSceneInternal(PxScene& scene) { NpScene* pScene = static_cast(&scene); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_REMOVE(physics, scenes, static_cast(*this), scene) -#endif + OMNI_PVD_REMOVE(PxPhysics, scenes, static_cast(*this), scene) PxMutex::ScopedLock lock(mSceneAndMaterialMutex); for(PxU32 i=0;icreateBuffer(byteSize, bufferType, cudaContexManager, NULL); #else - PX_UNUSED(byteSize); - PX_UNUSED(bufferType); - return NULL; + PxFLIPParticleSystem* NpPhysics::createFLIPParticleSystem(PxCudaContextManager&) { return NULL; } + PxMPMParticleSystem* NpPhysics::createMPMParticleSystem(PxCudaContextManager&) { return NULL; } + PxFEMCloth* NpPhysics::createFEMCloth(PxCudaContextManager&) { return NULL; } + PxHairSystem* NpPhysics::createHairSystem(PxCudaContextManager&) { return NULL; } #endif -} PxAggregate* NpPhysics::createAggregate(PxU32 maxActors, PxU32 maxShapes, PxAggregateFilterHint filterHint) { @@ -609,57 +572,45 @@ PxAggregate* NpPhysics::createAggregate(PxU32 maxActors, PxU32 maxShapes, PxAggr /////////////////////////////////////////////////////////////////////////////// -NpMaterial* NpPhysics::addMaterial(NpMaterial* m) +template +static NpMaterialT* addMaterial( +#if PX_SUPPORT_OMNI_PVD + NpPhysics::OmniPvdListener& mOmniPvdListener, +#endif + NpMaterialT* m, NpMaterialManager& materialManager, PxMutex& mutex, PxArray& sceneArray, const char* error) { if(!m) return NULL; OMNI_PVD_NOTIFY_ADD(m); - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); + PxMutex::ScopedLock lock(mutex); //the handle is set inside the setMaterial method - if(mMasterMaterialManager.setMaterial(*m)) + if(materialManager.setMaterial(*m)) { // Let all scenes know of the new material - for(PxU32 i=0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } + const PxU32 nbScenes = sceneArray.size(); + for(PxU32 i=0; iaddMaterial(*m); return m; } else { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::createMaterial: limit of 64K materials reached."); + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, error); m->release(); return NULL; } } -PxMaterial* NpPhysics::createMaterial(PxReal staticFriction, PxReal dynamicFriction, PxReal restitution) -{ - PxMaterial* m = NpFactory::getInstance().createMaterial(staticFriction, dynamicFriction, restitution); - - if (m) - return addMaterial(static_cast(m)); - else - return NULL; -} - -PxU32 NpPhysics::getNbMaterials() const -{ - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterMaterialManager.getNumMaterials(); -} - -PxU32 NpPhysics::getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const +template +static PxU32 getMaterials(const NpMaterialManager& materialManager, const PxMutex& mutex, PxMaterialT** userBuffer, PxU32 bufferSize, PxU32 startIndex) { - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterMaterialManager); + PxMutex::ScopedLock lock(const_cast(mutex)); + NpMaterialManagerIterator iter(materialManager); PxU32 writeCount =0; PxU32 index = 0; - NpMaterial* mat; + NpMaterialT* mat; while(iter.getNextMaterial(mat)) { if(index++ < startIndex) @@ -671,779 +622,252 @@ PxU32 NpPhysics::getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 s return writeCount; } -void NpPhysics::removeMaterialFromTable(NpMaterial& m) +template +static void removeMaterialFromTable( +#if PX_SUPPORT_OMNI_PVD + NpPhysics::OmniPvdListener& mOmniPvdListener, +#endif + NpMaterialT& m, NpMaterialManager& materialManager, PxMutex& mutex, PxArray& sceneArray) { OMNI_PVD_NOTIFY_REMOVE(&m); - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); + PxMutex::ScopedLock lock(mutex); // Let all scenes know of the deleted material - for(PxU32 i=0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->removeMaterial(m); - } + const PxU32 nbScenes = sceneArray.size(); + for(PxU32 i=0; iremoveMaterial(m); - mMasterMaterialManager.removeMaterial(m); + materialManager.removeMaterial(m); } -void NpPhysics::updateMaterial(NpMaterial& m) +template +static void updateMaterial(NpMaterialT& m, NpMaterialManager& materialManager, PxMutex& mutex, PxArray& sceneArray) { - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); + PxMutex::ScopedLock lock(mutex); // Let all scenes know of the updated material - for(PxU32 i=0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->updateMaterial(m); - } - mMasterMaterialManager.updateMaterial(m); + const PxU32 nbScenes = sceneArray.size(); + for(PxU32 i=0; iupdateMaterial(m); + + materialManager.updateMaterial(m); +} + +#if PX_SUPPORT_OMNI_PVD + #define _addMaterial(p0, p1, p2, p3, p4) ::addMaterial(mOmniPvdListener, p0, p1, p2, p3, p4) + #define _removeMaterialFromTable(p0, p1, p2, p3) ::removeMaterialFromTable(mOmniPvdListener, p0, p1, p2, p3) +#else + #define _addMaterial(p0, p1, p2, p3, p4) ::addMaterial(p0, p1, p2, p3, p4) + #define _removeMaterialFromTable(p0, p1, p2, p3) ::removeMaterialFromTable(p0, p1, p2, p3) +#endif + +#define IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpMaterialT, manager, errorMsg) \ +NpMaterialT* NpPhysics::addMaterial(NpMaterialT* m) \ +{ \ + return _addMaterial(m, manager, mSceneAndMaterialMutex, mSceneArray, errorMsg); \ +} \ +void NpPhysics::removeMaterialFromTable(NpMaterialT& m) \ +{ \ + _removeMaterialFromTable(m, manager, mSceneAndMaterialMutex, mSceneArray); \ +} \ +void NpPhysics::updateMaterial(NpMaterialT& m) \ +{ \ + ::updateMaterial(m, manager, mSceneAndMaterialMutex, mSceneArray); \ +} + +/////////////////////////////////////////////////////////////////////////////// + +template +static void sendMaterialTable(NpScene& scene, const NpMaterialManager& materialManager) +{ + NpMaterialManagerIterator iter(materialManager); + NpMaterialT* mat; + while(iter.getNextMaterial(mat)) + scene.addMaterial(*mat); } bool NpPhysics::sendMaterialTable(NpScene& scene) { // note: no lock here because this method gets only called at scene creation and there we do lock - NpMaterialManagerIterator iter(mMasterMaterialManager); - NpMaterial* mat; - while(iter.getNextMaterial(mat)) - scene.addMaterial(*mat); + ::sendMaterialTable(scene, mMasterMaterialManager); #if PX_SUPPORT_GPU_PHYSX - - NpMaterialManagerIterator iterSoftBody(mMasterFEMSoftBodyMaterialManager); - NpFEMSoftBodyMaterial* softmat; - while (iterSoftBody.getNextMaterial(softmat)) - scene.addMaterial(*softmat); - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpMaterialManagerIterator iterCloth(mMasterFEMClothMaterialManager); - NpFEMClothMaterial* clothmat; - while (iterCloth.getNextMaterial(clothmat)) - scene.addMaterial(*clothmat); -#endif + ::sendMaterialTable(scene, mMasterFEMSoftBodyMaterialManager); + ::sendMaterialTable(scene, mMasterPBDMaterialManager); - NpMaterialManagerIterator iterPBD(mMasterPBDMaterialManager); - NpPBDMaterial* pbdmat; - while (iterPBD.getNextMaterial(pbdmat)) - scene.addMaterial(*pbdmat); - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpMaterialManagerIterator iterFLIP(mMasterFLIPMaterialManager); - NpFLIPMaterial* flipmat; - while (iterFLIP.getNextMaterial(flipmat)) - scene.addMaterial(*flipmat); - - NpMaterialManagerIterator iterMPM(mMasterMPMMaterialManager); - NpMPMMaterial* mpmmat; - while (iterMPM.getNextMaterial(mpmmat)) - scene.addMaterial(*mpmmat); - - NpMaterialManagerIterator iterCustom(mMasterCustomMaterialManager); - NpCustomMaterial* custommat; - while (iterCustom.getNextMaterial(custommat)) - scene.addMaterial(*custommat); + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + ::sendMaterialTable(scene, mMasterFEMClothMaterialManager); + ::sendMaterialTable(scene, mMasterFLIPMaterialManager); + ::sendMaterialTable(scene, mMasterMPMMaterialManager); + #endif #endif -#endif //PX_SUPPORT_GPU_PHYSX - return true; } /////////////////////////////////////////////////////////////////////////////// -NpFEMSoftBodyMaterial* NpPhysics::addFEMMaterial(NpFEMSoftBodyMaterial* m) -{ - if (!m) - return NULL; - -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_ADD(m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - //the handle is set inside the setMaterial method - if (mMasterFEMSoftBodyMaterialManager.setMaterial(*m)) - { - // Let all scenes know of the new material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } - return m; - } - else - { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::createMaterial: limit of 64K materials reached."); - m->release(); - return NULL; - } -#else - m->release(); - return NULL; -#endif -} - -PxFEMSoftBodyMaterial* NpPhysics::createFEMSoftBodyMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) +PxMaterial* NpPhysics::createMaterial(PxReal staticFriction, PxReal dynamicFriction, PxReal restitution) { - PxFEMSoftBodyMaterial* m = NpFactory::getInstance().createFEMSoftBodyMaterial(youngs, poissons, dynamicFriction); - return addFEMMaterial(static_cast(m)); + PxMaterial* m = NpFactory::getInstance().createMaterial(staticFriction, dynamicFriction, restitution); + return addMaterial(static_cast(m)); } -PxU32 NpPhysics::getNbFEMSoftBodyMaterials() const +PxU32 NpPhysics::getNbMaterials() const { PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterFEMSoftBodyMaterialManager.getNumMaterials(); + return mMasterMaterialManager.getNumMaterials(); } -PxU32 NpPhysics::getFEMSoftBodyMaterials(PxFEMSoftBodyMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const +PxU32 NpPhysics::getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterFEMSoftBodyMaterialManager); - PxU32 writeCount = 0; - PxU32 index = 0; - NpFEMSoftBodyMaterial* mat; - while (iter.getNextMaterial(mat)) - { - if (index++ < startIndex) - continue; - if (writeCount == bufferSize) - break; - userBuffer[writeCount++] = mat; - } - return writeCount; + return ::getMaterials(mMasterMaterialManager, mSceneAndMaterialMutex, userBuffer, bufferSize, startIndex); } -void NpPhysics::removeFEMSoftBodyMaterialFromTable(NpFEMSoftBodyMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_REMOVE(&m); +IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpMaterial, mMasterMaterialManager, "PxPhysics::createMaterial: limit of 64K materials reached.") - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); +/////////////////////////////////////////////////////////////////////////////// - // Let all scenes know of the deleted material - for (PxU32 i = 0; i < mSceneArray.size(); i++) +// PT: all the virtual functions that are unconditionally defined in the API / virtual interface cannot be compiled away entirely. +// But the internal functions like addXXXX() can. + +#if PX_SUPPORT_GPU_PHYSX + PxFEMSoftBodyMaterial* NpPhysics::createFEMSoftBodyMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) { - NpScene* s = getScene(i); - s->removeMaterial(m); + PxFEMSoftBodyMaterial* m = NpFactory::getInstance().createFEMSoftBodyMaterial(youngs, poissons, dynamicFriction); + return addMaterial(static_cast(m)); } - mMasterFEMSoftBodyMaterialManager.removeMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -void NpPhysics::updateFEMSoftBodyMaterial(NpFEMSoftBodyMaterial& m) -{ - -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); + PxU32 NpPhysics::getNbFEMSoftBodyMaterials() const + { + PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); + return mMasterFEMSoftBodyMaterialManager.getNumMaterials(); + } - // Let all scenes know of the updated material - for (PxU32 i = 0; i < mSceneArray.size(); i++) + PxU32 NpPhysics::getFEMSoftBodyMaterials(PxFEMSoftBodyMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { - NpScene* s = getScene(i); - s->updateMaterial(m); + return ::getMaterials(mMasterFEMSoftBodyMaterialManager, mSceneAndMaterialMutex, userBuffer, bufferSize, startIndex); } - mMasterFEMSoftBodyMaterialManager.updateMaterial(m); + + IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpFEMSoftBodyMaterial, mMasterFEMSoftBodyMaterialManager, "PxPhysics::createFEMSoftBodyMaterial: limit of 64K materials reached.") #else - PX_UNUSED(m); + PxFEMSoftBodyMaterial* NpPhysics::createFEMSoftBodyMaterial(PxReal, PxReal, PxReal) { return NULL; } + PxU32 NpPhysics::getNbFEMSoftBodyMaterials() const { return 0; } + PxU32 NpPhysics::getFEMSoftBodyMaterials(PxFEMSoftBodyMaterial**, PxU32, PxU32) const { return 0; } #endif -} /////////////////////////////////////////////////////////////////////////////// -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -NpFEMClothMaterial* NpPhysics::addFEMClothMaterial(NpFEMClothMaterial* m) -{ - if (!m) - return NULL; - #if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_ADD(m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); + PxPBDMaterial* NpPhysics::createPBDMaterial(PxReal friction, PxReal damping, PxReal adhesion, PxReal viscosity, PxReal vorticityConfinement, PxReal surfaceTension, + PxReal cohesion, PxReal lift, PxReal drag, PxReal cflCoefficient, PxReal gravityScale) + { + PxPBDMaterial* m = NpFactory::getInstance().createPBDMaterial(friction, damping, adhesion, viscosity, vorticityConfinement, surfaceTension, cohesion, lift, drag, cflCoefficient, gravityScale); + return addMaterial(static_cast(m)); + } - //the handle is set inside the setMaterial method - if (mMasterFEMClothMaterialManager.setMaterial(*m)) + PxU32 NpPhysics::getNbPBDMaterials() const { - // Let all scenes know of the new material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } - return m; + PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); + return mMasterPBDMaterialManager.getNumMaterials(); } - else + + PxU32 NpPhysics::getPBDMaterials(PxPBDMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::addFEMClothMaterial: limit of 64K materials reached."); - m->release(); - return NULL; + return ::getMaterials(mMasterPBDMaterialManager, mSceneAndMaterialMutex, userBuffer, bufferSize, startIndex); } -#else - m->release(); - return NULL; -#endif -} -PxFEMClothMaterial* NpPhysics::createFEMClothMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) -{ - PxFEMClothMaterial* m = NpFactory::getInstance().createFEMClothMaterial(youngs, poissons, dynamicFriction); - return addFEMClothMaterial(static_cast(m)); -} + IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpPBDMaterial, mMasterPBDMaterialManager, "PxPhysics::createPBDMaterial: limit of 64K materials reached.") #else -PxFEMClothMaterial* NpPhysics::createFEMClothMaterial(PxReal, PxReal, PxReal) -{ - return NULL; -} + PxPBDMaterial* NpPhysics::createPBDMaterial(PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal) { return NULL; } + PxU32 NpPhysics::getNbPBDMaterials() const { return 0; } + PxU32 NpPhysics::getPBDMaterials(PxPBDMaterial**, PxU32, PxU32) const { return 0; } #endif -PxU32 NpPhysics::getNbFEMClothMaterials() const -{ -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterFEMClothMaterialManager.getNumMaterials(); -#else - return 0; -#endif -} +/////////////////////////////////////////////////////////////////////////////// -PxU32 NpPhysics::getFEMClothMaterials(PxFEMClothMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const -{ -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterFEMClothMaterialManager); - PxU32 writeCount = 0; - PxU32 index = 0; - NpFEMClothMaterial* mat; - while (iter.getNextMaterial(mat)) +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX + PxFEMClothMaterial* NpPhysics::createFEMClothMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) { - if (index++ < startIndex) - continue; - if (writeCount == bufferSize) - break; - userBuffer[writeCount++] = mat; + PxFEMClothMaterial* m = NpFactory::getInstance().createFEMClothMaterial(youngs, poissons, dynamicFriction); + return addMaterial(static_cast(m)); } - return writeCount; -#else - PX_UNUSED(userBuffer); PX_UNUSED(bufferSize); PX_UNUSED(startIndex); - return 0; -#endif -} - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -void NpPhysics::removeFEMClothMaterialFromTable(NpFEMClothMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_REMOVE(&m); - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); + PxU32 NpPhysics::getNbFEMClothMaterials() const + { + PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); + return mMasterFEMClothMaterialManager.getNumMaterials(); + } - // Let all scenes know of the deleted material - for (PxU32 i = 0; i < mSceneArray.size(); i++) + PxU32 NpPhysics::getFEMClothMaterials(PxFEMClothMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { - NpScene* s = getScene(i); - s->removeMaterial(m); + return ::getMaterials(mMasterFEMClothMaterialManager, mSceneAndMaterialMutex, userBuffer, bufferSize, startIndex); } - mMasterFEMClothMaterialManager.removeMaterial(m); + IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpFEMClothMaterial, mMasterFEMClothMaterialManager, "PxPhysics::createFEMClothMaterial: limit of 64K materials reached.") #else - PX_UNUSED(m); + PxFEMClothMaterial* NpPhysics::createFEMClothMaterial(PxReal, PxReal, PxReal) { return NULL; } + PxU32 NpPhysics::getNbFEMClothMaterials() const { return 0; } + PxU32 NpPhysics::getFEMClothMaterials(PxFEMClothMaterial**, PxU32, PxU32) const { return 0; } #endif -} -void NpPhysics::updateFEMClothMaterial(NpFEMClothMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); +/////////////////////////////////////////////////////////////////////////////// - // Let all scenes know of the updated material - for (PxU32 i = 0; i < mSceneArray.size(); i++) +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX + PxFLIPMaterial* NpPhysics::createFLIPMaterial(PxReal friction, PxReal damping, PxReal maxVelocity, PxReal viscosity, PxReal gravityScale) + { + PxFLIPMaterial* m = NpFactory::getInstance().createFLIPMaterial(friction, damping, maxVelocity, viscosity, gravityScale); + return addMaterial(static_cast(m)); + } + + PxU32 NpPhysics::getNbFLIPMaterials() const + { + PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); + return mMasterFLIPMaterialManager.getNumMaterials(); + } + + PxU32 NpPhysics::getFLIPMaterials(PxFLIPMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { - NpScene* s = getScene(i); - s->updateMaterial(m); + return ::getMaterials(mMasterFLIPMaterialManager, mSceneAndMaterialMutex, userBuffer, bufferSize, startIndex); } - mMasterFEMClothMaterialManager.updateMaterial(m); + + IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpFLIPMaterial, mMasterFLIPMaterialManager, "PxPhysics::createFLIPMaterial: limit of 64K materials reached.") #else - PX_UNUSED(m); -#endif -} + PxFLIPMaterial* NpPhysics::createFLIPMaterial(PxReal, PxReal, PxReal, PxReal, PxReal) { return NULL; } + PxU32 NpPhysics::getNbFLIPMaterials() const { return 0; } + PxU32 NpPhysics::getFLIPMaterials(PxFLIPMaterial**, PxU32, PxU32) const { return 0; } #endif /////////////////////////////////////////////////////////////////////////////// -NpPBDMaterial* NpPhysics::addPBDMaterial(NpPBDMaterial* m) -{ - if (!m) - return NULL; - -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_ADD(m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX + PxMPMMaterial* NpPhysics::createMPMMaterial(PxReal friction, PxReal damping, PxReal maxVelocity, bool isPlastic, PxReal youngsModulus, PxReal poissons, PxReal hardening, PxReal criticalCompression, PxReal criticalStretch, PxReal tensileDamageSensitivity, PxReal compressiveDamageSensitivity, PxReal attractiveForceResidual, PxReal gravityScale) + { + PxMPMMaterial* m = NpFactory::getInstance().createMPMMaterial(friction, damping, maxVelocity, isPlastic, youngsModulus, poissons, hardening, criticalCompression, criticalStretch, tensileDamageSensitivity, compressiveDamageSensitivity, attractiveForceResidual, gravityScale); + return addMaterial(static_cast(m)); + } - //the handle is set inside the setMaterial method - if (mMasterPBDMaterialManager.setMaterial(*m)) + PxU32 NpPhysics::getNbMPMMaterials() const { - // Let all scenes know of the new material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } - return m; + PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); + return mMasterMPMMaterialManager.getNumMaterials(); } - else + + PxU32 NpPhysics::getMPMMaterials(PxMPMMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::addPBDMaterial: limit of 64K materials reached."); - m->release(); - return NULL; + return ::getMaterials(mMasterMPMMaterialManager, mSceneAndMaterialMutex, userBuffer, bufferSize, startIndex); } + + IMPLEMENT_INTERNAL_MATERIAL_FUNCTIONS(NpMPMMaterial, mMasterMPMMaterialManager, "PxPhysics::createMPMMaterial: limit of 64K materials reached.") #else - m->release(); - return NULL; + PxMPMMaterial* NpPhysics::createMPMMaterial(PxReal, PxReal, PxReal, bool, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal) { return NULL; } + PxU32 NpPhysics::getNbMPMMaterials() const { return 0; } + PxU32 NpPhysics::getMPMMaterials(PxMPMMaterial**, PxU32, PxU32) const { return 0; } #endif -} -PxPBDMaterial* NpPhysics::createPBDMaterial(PxReal friction, PxReal damping, PxReal adhesion, PxReal viscosity, PxReal vorticityConfinement, PxReal surfaceTension, - PxReal cohesion, PxReal lift, PxReal drag, PxReal cflCoefficient, PxReal gravityScale) -{ - PxPBDMaterial* m = NpFactory::getInstance().createPBDMaterial(friction, damping, adhesion, viscosity, vorticityConfinement, surfaceTension, cohesion, lift, drag, cflCoefficient, gravityScale); - return addPBDMaterial(static_cast(m)); -} - -PxU32 NpPhysics::getNbPBDMaterials() const -{ - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterPBDMaterialManager.getNumMaterials(); -} - -PxU32 NpPhysics::getPBDMaterials(PxPBDMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const -{ - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterPBDMaterialManager); - PxU32 writeCount = 0; - PxU32 index = 0; - NpPBDMaterial* mat; - while (iter.getNextMaterial(mat)) - { - if (index++ < startIndex) - continue; - if (writeCount == bufferSize) - break; - userBuffer[writeCount++] = mat; - } - return writeCount; -} - -void NpPhysics::removePBDMaterialFromTable(NpPBDMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_REMOVE(&m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the deleted material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->removeMaterial(m); - } - - mMasterPBDMaterialManager.removeMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -void NpPhysics::updatePBDMaterial(NpPBDMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the updated material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->updateMaterial(m); - } - mMasterPBDMaterialManager.updateMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -NpFLIPMaterial* NpPhysics::addFLIPMaterial(NpFLIPMaterial* m) -{ - if (!m) - return NULL; - -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_ADD(m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - //the handle is set inside the setMaterial method - if (mMasterFLIPMaterialManager.setMaterial(*m)) - { - // Let all scenes know of the new material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } - return m; - } - else - { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::addFLIPMaterial: limit of 64K materials reached."); - m->release(); - return NULL; - } -#else - m->release(); - return NULL; -#endif -} -#endif - - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -PxFLIPMaterial* NpPhysics::createFLIPMaterial(PxReal friction, PxReal damping, PxReal maxVelocity, PxReal viscosity, PxReal gravityScale) -{ - PxFLIPMaterial* m = NpFactory::getInstance().createFLIPMaterial(friction, damping, maxVelocity, viscosity, gravityScale); - return addFLIPMaterial(static_cast(m)); -} -#else -PxFLIPMaterial* NpPhysics::createFLIPMaterial(PxReal, PxReal, PxReal, PxReal, PxReal) -{ - return NULL; -} -#endif - -PxU32 NpPhysics::getNbFLIPMaterials() const -{ -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterFLIPMaterialManager.getNumMaterials(); -#else - return 0; -#endif -} - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -PxU32 NpPhysics::getFLIPMaterials(PxFLIPMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const -{ - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterFLIPMaterialManager); - PxU32 writeCount = 0; - PxU32 index = 0; - NpFLIPMaterial* mat; - while (iter.getNextMaterial(mat)) - { - if (index++ < startIndex) - continue; - if (writeCount == bufferSize) - break; - userBuffer[writeCount++] = mat; - } - return writeCount; -} -#else -PxU32 NpPhysics::getFLIPMaterials(PxFLIPMaterial** , PxU32, PxU32) const -{ - return 0; -} -#endif - - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -void NpPhysics::removeFLIPMaterialFromTable(NpFLIPMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_REMOVE(&m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the deleted material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->removeMaterial(m); - } - - mMasterFLIPMaterialManager.removeMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -void NpPhysics::updateFLIPMaterial(NpFLIPMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the updated material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->updateMaterial(m); - } - mMasterFLIPMaterialManager.updateMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// - -NpMPMMaterial* NpPhysics::addMPMMaterial(NpMPMMaterial* m) -{ - if (!m) - return NULL; - -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_ADD(m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - //the handle is set inside the setMaterial method - if (mMasterMPMMaterialManager.setMaterial(*m)) - { - // Let all scenes know of the new material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } - return m; - } - else - { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::addMPMMaterial: limit of 64K materials reached."); - m->release(); - return NULL; - } -#else - m->release(); - return NULL; -#endif -} -#endif // PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -PxMPMMaterial* NpPhysics::createMPMMaterial(PxReal friction, PxReal damping, PxReal maxVelocity, bool isPlastic, PxReal youngsModulus, PxReal poissons, PxReal hardening, PxReal criticalCompression, PxReal criticalStretch, PxReal tensileDamageSensitivity, PxReal compressiveDamageSensitivity, PxReal attractiveForceResidual, PxReal gravityScale) -{ - PxMPMMaterial* m = NpFactory::getInstance().createMPMMaterial(friction, damping, maxVelocity, isPlastic, youngsModulus, poissons, hardening, criticalCompression, criticalStretch, tensileDamageSensitivity, compressiveDamageSensitivity, attractiveForceResidual, gravityScale); - return addMPMMaterial(static_cast(m)); -} -#else -PxMPMMaterial* NpPhysics::createMPMMaterial(PxReal, PxReal, PxReal, bool, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal, PxReal) -{ - return NULL; -} -#endif - -PxU32 NpPhysics::getNbMPMMaterials() const -{ -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterMPMMaterialManager.getNumMaterials(); -#else - return 0; -#endif -} - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -PxU32 NpPhysics::getMPMMaterials(PxMPMMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const -{ - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterMPMMaterialManager); - PxU32 writeCount = 0; - PxU32 index = 0; - NpMPMMaterial* mat; - while (iter.getNextMaterial(mat)) - { - if (index++ < startIndex) - continue; - if (writeCount == bufferSize) - break; - userBuffer[writeCount++] = mat; - } - return writeCount; -} -#else -PxU32 NpPhysics::getMPMMaterials(PxMPMMaterial**, PxU32, PxU32) const -{ - return 0; -} -#endif - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -void NpPhysics::removeMPMMaterialFromTable(NpMPMMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - OMNI_PVD_NOTIFY_REMOVE(&m); - - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the deleted material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->removeMaterial(m); - } - - mMasterMPMMaterialManager.removeMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -void NpPhysics::updateMPMMaterial(NpMPMMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the updated material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->updateMaterial(m); - } - mMasterMPMMaterialManager.updateMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -/////////////////////////////////////////////////////////////////////////////// - -NpCustomMaterial* NpPhysics::addCustomMaterial(NpCustomMaterial* m) -{ - if (!m) - return NULL; - -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - //the handle is set inside the setMaterial method - if (mMasterCustomMaterialManager.setMaterial(*m)) - { - // Let all scenes know of the new material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->addMaterial(*m); - } - return m; - } - else - { - mFoundation.error(PxErrorCode::eINVALID_PARAMETER, PX_FL, "PxPhysics::addCustomMaterial: limit of 64K materials reached."); - m->release(); - return NULL; - } -#else - m->release(); - return NULL; -#endif -} -#endif - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -PxCustomMaterial* NpPhysics::createCustomMaterial(void* gpuBuffer) -{ - PxCustomMaterial* m = NpFactory::getInstance().createCustomMaterial(gpuBuffer); - return addCustomMaterial(static_cast(m)); -} -#else -PxCustomMaterial* NpPhysics::createCustomMaterial(void*) -{ - return NULL; -} -#endif - -PxU32 NpPhysics::getNbCustomMaterials() const -{ -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - return mMasterCustomMaterialManager.getNumMaterials(); -#else - return 0; -#endif -} - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -PxU32 NpPhysics::getCustomMaterials(PxCustomMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const -{ - PxMutex::ScopedLock lock(const_cast(mSceneAndMaterialMutex)); - NpMaterialManagerIterator iter(mMasterCustomMaterialManager); - PxU32 writeCount = 0; - PxU32 index = 0; - NpCustomMaterial* mat; - while (iter.getNextMaterial(mat)) - { - if (index++ < startIndex) - continue; - if (writeCount == bufferSize) - break; - userBuffer[writeCount++] = mat; - } - return writeCount; -} -#else -PxU32 NpPhysics::getCustomMaterials(PxCustomMaterial**, PxU32, PxU32) const -{ - return 0; -} -#endif - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -void NpPhysics::removeCustomMaterialFromTable(NpCustomMaterial& m) -{ -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the deleted material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->removeMaterial(m); - } - - mMasterCustomMaterialManager.removeMaterial(m); -#else - PX_UNUSED(m); -#endif -} - -void NpPhysics::updateCustomMaterial(NpCustomMaterial& m) -{ - -#if PX_SUPPORT_GPU_PHYSX - PxMutex::ScopedLock lock(mSceneAndMaterialMutex); - - // Let all scenes know of the updated material - for (PxU32 i = 0; i < mSceneArray.size(); i++) - { - NpScene* s = getScene(i); - s->updateMaterial(m); - } - mMasterCustomMaterialManager.updateMaterial(m); -#else - PX_UNUSED(m); -#endif -} -#endif // PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - -/////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// PxTriangleMesh* NpPhysics::createTriangleMesh(PxInputStream& stream) { @@ -1535,26 +959,48 @@ PxU32 NpPhysics::getBVHs(PxBVH** userBuffer, PxU32 bufferSize, PxU32 startIndex) /////////////////////////////////////////////////////////////////////////////// -PxParticleBuffer* NpPhysics::createParticleBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContexManager) +#if PX_SUPPORT_GPU_PHYSX +PxParticleBuffer* NpPhysics::createParticleBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContextManager) +{ + return NpFactory::getInstance().createParticleBuffer(maxParticles, maxVolumes, cudaContextManager); +} + +PxParticleAndDiffuseBuffer* NpPhysics::createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContextManager) { - return NpFactory::getInstance().createParticleBuffer(maxParticles, maxVolumes, cudaContexManager); + return NpFactory::getInstance().createParticleAndDiffuseBuffer(maxParticles, maxVolumes, maxDiffuseParticles, cudaContextManager); } -PxParticleAndDiffuseBuffer* NpPhysics::createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContexManager) +PxParticleClothBuffer* NpPhysics::createParticleClothBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContextManager) { - return NpFactory::getInstance().createParticleAndDiffuseBuffer(maxParticles, maxVolumes, maxDiffuseParticles, cudaContexManager); + return NpFactory::getInstance().createParticleClothBuffer(maxParticles, maxNumVolumes, maxNumCloths, maxNumTriangles, maxNumSprings, cudaContextManager); } -PxParticleClothBuffer* NpPhysics::createParticleClothBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContexManager) +PxParticleRigidBuffer* NpPhysics::createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContextManager) { - return NpFactory::getInstance().createParticleClothBuffer(maxParticles, maxNumVolumes, maxNumCloths, maxNumTriangles, maxNumSprings, cudaContexManager); + return NpFactory::getInstance().createParticleRigidBuffer(maxParticles, maxNumVolumes, maxNumRigids, cudaContextManager); +} +#else +PxParticleBuffer* NpPhysics::createParticleBuffer(PxU32, PxU32, PxCudaContextManager*) +{ + return NULL; } -PxParticleRigidBuffer* NpPhysics::createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContexManager) +PxParticleAndDiffuseBuffer* NpPhysics::createParticleAndDiffuseBuffer(PxU32, PxU32, PxU32, PxCudaContextManager*) { - return NpFactory::getInstance().createParticleRigidBuffer(maxParticles, maxNumVolumes, maxNumRigids, cudaContexManager); + return NULL; } +PxParticleClothBuffer* NpPhysics::createParticleClothBuffer(PxU32, PxU32, PxU32, PxU32, PxU32, PxCudaContextManager*) +{ + return NULL; +} + +PxParticleRigidBuffer* NpPhysics::createParticleRigidBuffer(PxU32, PxU32, PxU32, PxCudaContextManager*) +{ + return NULL; +} +#endif + /////////////////////////////////////////////////////////////////////////////// PxPruningStructure* NpPhysics::createPruningStructure(PxRigidActor*const* actors, PxU32 nbActors) @@ -1737,37 +1183,11 @@ PxPhysics& PxGetPhysics() return NpPhysics::getInstance(); } -PxPhysics* PxCreateBasePhysics(PxU32 version, PxFoundation& foundation, const PxTolerancesScale& scale, bool trackOutstandingAllocations, PxPvd* pvd, PxOmniPvd* omniPvd) +PxPhysics* PxCreatePhysics(PxU32 version, PxFoundation& foundation, const physx::PxTolerancesScale& scale, bool trackOutstandingAllocations, PxPvd* pvd, PxOmniPvd* omniPvd) { return NpPhysics::createInstance(version, foundation, scale, trackOutstandingAllocations, static_cast(pvd), omniPvd); } -//void PxRegisterArticulations(PxPhysics& physics) -//{ -// PX_UNUSED(&physics); // for the moment -// Dy::PxvRegisterArticulations(); -// NpFactory::registerArticulations(); -//} - -void PxRegisterArticulationsReducedCoordinate(PxPhysics& physics) -{ - PX_UNUSED(&physics); // for the moment - Dy::PxvRegisterArticulationsReducedCoordinate(); - NpFactory::registerArticulationRCs(); -} - -void PxRegisterHeightFields(PxPhysics& physics) -{ - PX_UNUSED(&physics); // for the moment - PX_CHECK_AND_RETURN(NpPhysics::getInstance().getNumScenes() == 0, "PxRegisterHeightFields: it is illegal to call a heightfield registration function after you have a scene."); - - PxvRegisterHeightFields(); - Gu::registerHeightFields(); -#if PX_CHECKED - NpPhysics::heightfieldsAreRegistered(); -#endif -} - void PxAddCollectionToPhysics(const PxCollection& collection) { NpFactory& factory = NpFactory::getInstance(); diff --git a/physx/source/physx/src/NpPhysics.h b/physx/source/physx/src/NpPhysics.h index 1e6bc0ae2..b9b79b45f 100644 --- a/physx/source/physx/src/NpPhysics.h +++ b/physx/source/physx/src/NpPhysics.h @@ -91,8 +91,7 @@ template class NpMaterialAccessor; class NpPhysics : public PxPhysics, public PxUserAllocated { - NpPhysics& operator=(const NpPhysics&); - NpPhysics(const NpPhysics &); + PX_NOCOPY(NpPhysics) struct NpDelListenerEntry : public PxUserAllocated { @@ -142,14 +141,12 @@ class NpPhysics : public PxPhysics, public PxUserAllocated virtual PxRigidDynamic* createRigidDynamic(const PxTransform&) PX_OVERRIDE; virtual PxArticulationReducedCoordinate* createArticulationReducedCoordinate() PX_OVERRIDE; virtual PxSoftBody* createSoftBody(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; - virtual PxHairSystem* createHairSystem(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; - virtual PxFEMCloth* createFEMCloth(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; - virtual PxPBDParticleSystem* createPBDParticleSystem(PxCudaContextManager& cudaContexManager, PxU32 maxNeighborhood) PX_OVERRIDE; - virtual PxFLIPParticleSystem* createFLIPParticleSystem(PxCudaContextManager& cudaContexManager) PX_OVERRIDE; - virtual PxMPMParticleSystem* createMPMParticleSystem(PxCudaContextManager& cudaContexManager) PX_OVERRIDE; - virtual PxCustomParticleSystem* createCustomParticleSystem(PxCudaContextManager& cudaContexManager, PxU32 maxNeighborhood) PX_OVERRIDE; - - virtual PxBuffer* createBuffer(PxU64 byteSize, PxBufferType::Enum bufferType, PxCudaContextManager* cudaContextManager) PX_OVERRIDE; + virtual PxHairSystem* createHairSystem(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; + virtual PxFEMCloth* createFEMCloth(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; + virtual PxPBDParticleSystem* createPBDParticleSystem(PxCudaContextManager& cudaContextManager, PxU32 maxNeighborhood) PX_OVERRIDE; + virtual PxFLIPParticleSystem* createFLIPParticleSystem(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; + virtual PxMPMParticleSystem* createMPMParticleSystem(PxCudaContextManager& cudaContextManager) PX_OVERRIDE; + virtual PxConstraint* createConstraint(PxRigidActor* actor0, PxRigidActor* actor1, PxConstraintConnector& connector, const PxConstraintShaderTable& shaders, PxU32 dataSize) PX_OVERRIDE; virtual PxAggregate* createAggregate(PxU32 maxActors, PxU32 maxShapes, PxAggregateFilterHint filterHint) PX_OVERRIDE; @@ -184,10 +181,6 @@ class NpPhysics : public PxPhysics, public PxUserAllocated virtual PxU32 getNbMPMMaterials() const PX_OVERRIDE; virtual PxU32 getMPMMaterials(PxMPMMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const PX_OVERRIDE; - virtual PxCustomMaterial* createCustomMaterial(void* gpuBuffer) PX_OVERRIDE; - virtual PxU32 getNbCustomMaterials() const PX_OVERRIDE; - virtual PxU32 getCustomMaterials(PxCustomMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const PX_OVERRIDE; - virtual PxTriangleMesh* createTriangleMesh(PxInputStream&) PX_OVERRIDE; virtual PxU32 getNbTriangleMeshes() const PX_OVERRIDE; virtual PxU32 getTriangleMeshes(PxTriangleMesh** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const PX_OVERRIDE; @@ -210,10 +203,10 @@ class NpPhysics : public PxPhysics, public PxUserAllocated virtual PxU32 getNbBVHs() const PX_OVERRIDE; virtual PxU32 getBVHs(PxBVH** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const PX_OVERRIDE; - virtual PxParticleBuffer* createParticleBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContexManager) PX_OVERRIDE; - virtual PxParticleAndDiffuseBuffer* createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContexManager) PX_OVERRIDE; - virtual PxParticleClothBuffer* createParticleClothBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContexManager) PX_OVERRIDE; - virtual PxParticleRigidBuffer* createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContexManager) PX_OVERRIDE; + virtual PxParticleBuffer* createParticleBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContextManager) PX_OVERRIDE; + virtual PxParticleAndDiffuseBuffer* createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContextManager) PX_OVERRIDE; + virtual PxParticleClothBuffer* createParticleClothBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContextManager) PX_OVERRIDE; + virtual PxParticleRigidBuffer* createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContextManager) PX_OVERRIDE; #if PX_SUPPORT_GPU_PHYSX void registerPhysXIndicatorGpuClient(); @@ -231,9 +224,6 @@ class NpPhysics : public PxPhysics, public PxUserAllocated PX_INLINE NpScene* getScene(PxU32 i) const { return mSceneArray[i]; } PX_INLINE PxU32 getNumScenes() const { return mSceneArray.size(); } -#if PX_CHECKED - static PX_INLINE void heightfieldsAreRegistered() { mHeightFieldsRegistered = true; } -#endif virtual void registerDeletionListener(PxDeletionListener& observer, const PxDeletionEventFlags& deletionEvents, bool restrictedObjectSet) PX_OVERRIDE; virtual void unregisterDeletionListener(PxDeletionListener& observer) PX_OVERRIDE; @@ -246,57 +236,44 @@ class NpPhysics : public PxPhysics, public PxUserAllocated virtual PxInsertionCallback& getPhysicsInsertionCallback() PX_OVERRIDE { return mObjectInsertion; } - void removeMaterialFromTable(NpMaterial&); - void updateMaterial(NpMaterial&); bool sendMaterialTable(NpScene&); NpMaterialManager& getMaterialManager() { return mMasterMaterialManager; } - NpMaterialManager& getFEMSoftBodyMaterialManager() { return mMasterFEMSoftBodyMaterialManager; } -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpMaterialManager& getFEMClothMaterialManager() { return mMasterFEMClothMaterialManager; } -#endif - NpMaterialManager& getPBDMaterialManager() { return mMasterPBDMaterialManager; } -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpMaterialManager& getFLIPMaterialManager() { return mMasterFLIPMaterialManager; } - NpMaterialManager& getMPMMaterialManager() { return mMasterMPMMaterialManager; } - NpMaterialManager& getCustomMaterialManager() { return mMasterCustomMaterialManager; } +#if PX_SUPPORT_GPU_PHYSX + NpMaterialManager& getFEMSoftBodyMaterialManager() { return mMasterFEMSoftBodyMaterialManager; } + NpMaterialManager& getPBDMaterialManager() { return mMasterPBDMaterialManager; } + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + NpMaterialManager& getFEMClothMaterialManager() { return mMasterFEMClothMaterialManager; } + NpMaterialManager& getFLIPMaterialManager() { return mMasterFLIPMaterialManager; } + NpMaterialManager& getMPMMaterialManager() { return mMasterMPMMaterialManager; } + #endif #endif - /*template - NpMaterialManager* getMaterialManagerT(); - template <> - NpMaterialManager* getMaterialManagerT() { return &mMasterMaterialManager; } - template <> - NpMaterialManager* getMaterialManagerT() { return &mMasterFEMSoftBodyMaterialManager; } - template <> - NpMaterialManager* getMaterialManagerT() { return &mMasterFEMClothMaterialManager; }*/ - NpMaterial* addMaterial(NpMaterial* np); + void removeMaterialFromTable(NpMaterial&); + void updateMaterial(NpMaterial&); - void removeFEMSoftBodyMaterialFromTable(NpFEMSoftBodyMaterial&); - void updateFEMSoftBodyMaterial(NpFEMSoftBodyMaterial&); - - NpFEMSoftBodyMaterial* addFEMMaterial(NpFEMSoftBodyMaterial* np); - -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - void removeFEMClothMaterialFromTable(NpFEMClothMaterial&); - void updateFEMClothMaterial(NpFEMClothMaterial&); - NpFEMClothMaterial* addFEMClothMaterial(NpFEMClothMaterial* np); -#endif - void removePBDMaterialFromTable(NpPBDMaterial&); - void updatePBDMaterial(NpPBDMaterial&); - NpPBDMaterial* addPBDMaterial(NpPBDMaterial* np); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - void removeFLIPMaterialFromTable(NpFLIPMaterial&); - void updateFLIPMaterial(NpFLIPMaterial&); - NpFLIPMaterial* addFLIPMaterial(NpFLIPMaterial* np); +#if PX_SUPPORT_GPU_PHYSX + NpFEMSoftBodyMaterial* addMaterial(NpFEMSoftBodyMaterial* np); + void removeMaterialFromTable(NpFEMSoftBodyMaterial&); + void updateMaterial(NpFEMSoftBodyMaterial&); + + NpPBDMaterial* addMaterial(NpPBDMaterial* np); + void removeMaterialFromTable(NpPBDMaterial&); + void updateMaterial(NpPBDMaterial&); + + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + NpFEMClothMaterial* addMaterial(NpFEMClothMaterial* np); + void removeMaterialFromTable(NpFEMClothMaterial&); + void updateMaterial(NpFEMClothMaterial&); + + NpFLIPMaterial* addMaterial(NpFLIPMaterial* np); + void removeMaterialFromTable(NpFLIPMaterial&); + void updateMaterial(NpFLIPMaterial&); - void removeMPMMaterialFromTable(NpMPMMaterial&); - void updateMPMMaterial(NpMPMMaterial&); - NpMPMMaterial* addMPMMaterial(NpMPMMaterial* np); - - void removeCustomMaterialFromTable(NpCustomMaterial&); - void updateCustomMaterial(NpCustomMaterial&); - NpCustomMaterial* addCustomMaterial(NpCustomMaterial* np); + NpMPMMaterial* addMaterial(NpMPMMaterial* np); + void removeMaterialFromTable(NpMPMMaterial&); + void updateMaterial(NpMPMMaterial&); + #endif #endif static void initOffsetTables(PxvOffsetTable& pxvOffsetTable); @@ -314,15 +291,9 @@ class NpPhysics : public PxPhysics, public PxUserAllocated Sc::Physics mPhysics; NpMaterialManager mMasterMaterialManager; +#if PX_SUPPORT_GPU_PHYSX NpMaterialManager mMasterFEMSoftBodyMaterialManager; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpMaterialManager mMasterFEMClothMaterialManager; -#endif NpMaterialManager mMasterPBDMaterialManager; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - NpMaterialManager mMasterFLIPMaterialManager; - NpMaterialManager mMasterMPMMaterialManager; - NpMaterialManager mMasterCustomMaterialManager; #endif NpPhysicsInsertionCallback mObjectInsertion; @@ -357,13 +328,10 @@ class NpPhysics : public PxPhysics, public PxUserAllocated static PxU32 mRefCount; static NpPhysics* mInstance; -#if PX_CHECKED - static bool mHeightFieldsRegistered; //just for error checking -#endif - friend class NpCollection; #if PX_SUPPORT_OMNI_PVD + public: class OmniPvdListener : public physx::NpFactoryListener { public: @@ -372,6 +340,18 @@ class NpPhysics : public PxPhysics, public PxUserAllocated virtual void onObjectRemove(const PxBase*); } mOmniPvdListener; + private: +#endif + +// GW: these must be the last defined members for now. Otherwise it appears to mess up the offsets +// expected when linking SDK dlls against unit tests due to differing values of PX_ENABLE_FEATURES_UNDER_CONSTRUCTION... +// this warrants further investigation and hopefully a better solution +#if PX_SUPPORT_GPU_PHYSX +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + NpMaterialManager mMasterFEMClothMaterialManager; + NpMaterialManager mMasterFLIPMaterialManager; + NpMaterialManager mMasterMPMMaterialManager; +#endif #endif }; @@ -384,6 +364,7 @@ template <> class NpMaterialAccessor } }; +#if PX_SUPPORT_GPU_PHYSX template <> class NpMaterialAccessor { public: @@ -393,27 +374,25 @@ template <> class NpMaterialAccessor } }; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -template <> class NpMaterialAccessor +template <> class NpMaterialAccessor { public: - static NpMaterialManager& getMaterialManager(NpPhysics& physics) + static NpMaterialManager& getMaterialManager(NpPhysics& physics) { - return physics.getFEMClothMaterialManager(); + return physics.getPBDMaterialManager(); } }; -#endif -template <> class NpMaterialAccessor +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +template <> class NpMaterialAccessor { public: - static NpMaterialManager& getMaterialManager(NpPhysics& physics) + static NpMaterialManager& getMaterialManager(NpPhysics& physics) { - return physics.getPBDMaterialManager(); + return physics.getFEMClothMaterialManager(); } }; -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION template <> class NpMaterialAccessor { public: @@ -431,15 +410,7 @@ template <> class NpMaterialAccessor return physics.getMPMMaterialManager(); } }; - -template <> class NpMaterialAccessor -{ -public: - static NpMaterialManager& getMaterialManager(NpPhysics& physics) - { - return physics.getCustomMaterialManager(); - } -}; +#endif #endif #if PX_VC diff --git a/physx/source/physx/src/NpPvdSceneClient.cpp b/physx/source/physx/src/NpPvdSceneClient.cpp index 0b3a54657..28328b4ce 100644 --- a/physx/source/physx/src/NpPvdSceneClient.cpp +++ b/physx/source/physx/src/NpPvdSceneClient.cpp @@ -26,6 +26,7 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. +#include "foundation/PxPreprocessor.h" #if PX_SUPPORT_PVD #include "common/PxProfileZone.h" #include "common/PxRenderBuffer.h" @@ -33,7 +34,6 @@ #include "PxPBDParticleSystem.h" //#include "PxFLIPParticleSystem.h" //#include "PxMPMParticleSystem.h" -//#include "PxCustomParticleSystem.h" #include "PxPhysics.h" #include "PxConstraintDesc.h" #include "NpPvdSceneClient.h" @@ -168,7 +168,9 @@ namespace op(*static_cast(actor)); break; case PxActorType::eSOFTBODY: +#if PX_SUPPORT_GPU_PHYSX op(*static_cast(actor)); +#endif break; case PxActorType::eFEMCLOTH: //op(*static_cast(actor)); @@ -182,9 +184,6 @@ namespace case PxActorType::eMPM_PARTICLESYSTEM: //op(*static_cast(actor)); break; - case PxActorType::eCUSTOM_PARTICLESYSTEM: - //op(*static_cast(actor)); - break; case PxActorType::eHAIRSYSTEM: //op(*static_cast(actor)); break; @@ -202,36 +201,38 @@ namespace PX_NOCOPY(PvdConstraintVisualizer) public: physx::pvdsdk::PvdUserRenderer& mRenderer; + PvdConstraintVisualizer(const void* id, physx::pvdsdk::PvdUserRenderer& r) : mRenderer(r) { mRenderer.setInstanceId(id); } - virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) + + virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) PX_OVERRIDE { mRenderer.visualizeJointFrames(parent, child); } - virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value, bool active) + virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value) PX_OVERRIDE { - mRenderer.visualizeLinearLimit(t0, t1, PxF32(value), active); + mRenderer.visualizeLinearLimit(t0, t1, PxF32(value)); } - virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper, bool active) + virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper) PX_OVERRIDE { - mRenderer.visualizeAngularLimit(t0, PxF32(lower), PxF32(upper), active); + mRenderer.visualizeAngularLimit(t0, PxF32(lower), PxF32(upper)); } - virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ, bool active) + virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ) PX_OVERRIDE { - mRenderer.visualizeLimitCone(t, PxF32(tanQSwingY), PxF32(tanQSwingZ), active); + mRenderer.visualizeLimitCone(t, PxF32(tanQSwingY), PxF32(tanQSwingZ)); } - virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle, bool active) + virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle) PX_OVERRIDE { - mRenderer.visualizeDoubleCone(t, PxF32(angle), active); + mRenderer.visualizeDoubleCone(t, PxF32(angle)); } - virtual void visualizeLine( const PxVec3& p0, const PxVec3& p1, PxU32 color) + virtual void visualizeLine( const PxVec3& p0, const PxVec3& p1, PxU32 color) PX_OVERRIDE { const PxDebugLine line(p0, p1, color); mRenderer.drawLines(&line, 1); @@ -736,33 +737,19 @@ void PvdSceneClient::releasePvdInstance(const PxsFEMSoftBodyMaterialCore* materi /////////////////////////////////////////////////////////////////////////////// -void PvdSceneClient::createPvdInstance(const PxsFEMClothMaterialCore* /*materialCore*/) +void PvdSceneClient::createPvdInstance(const PxsFEMClothMaterialCore*) { - // jcarius: Commented-out until FEMCloth is not under construction anymore - PX_ASSERT(0); - - // if (checkPvdDebugFlag()) - // { - // const PxFEMClothMaterial* theMaterial = materialCore->mMaterial; - // if (mPvd->registerObject(theMaterial)) - // mMetaDataBinding.createInstance(*mPvdDataStream, *theMaterial, PxGetPhysics()); - // } + // no PVD support but method is "needed" since macro code is shared among all material types } -void PvdSceneClient::updatePvdProperties(const PxsFEMClothMaterialCore* /*materialCore*/) +void PvdSceneClient::updatePvdProperties(const PxsFEMClothMaterialCore*) { - // jcarius: Commented-out until FEMCloth is not under construction anymore - PX_ASSERT(0); - // if (checkPvdDebugFlag()) - // mMetaDataBinding.sendAllProperties(*mPvdDataStream, *materialCore->mMaterial); + // no PVD support but method is "needed" since macro code is shared among all material types } -void PvdSceneClient::releasePvdInstance(const PxsFEMClothMaterialCore* /*materialCore*/) +void PvdSceneClient::releasePvdInstance(const PxsFEMClothMaterialCore*) { - // jcarius: Commented-out until FEMCloth is not under construction anymore - PX_ASSERT(0); - // if (checkPvdDebugFlag() && mPvd->unRegisterObject(materialCore->mMaterial)) - // mMetaDataBinding.destroyInstance(*mPvdDataStream, *materialCore->mMaterial, PxGetPhysics()); + // no PVD support but method is "needed" since macro code is shared among all material types } /////////////////////////////////////////////////////////////////////////////// @@ -812,21 +799,6 @@ void PvdSceneClient::releasePvdInstance(const PxsMPMMaterialCore* /*materialCore // PX_ASSERT(0); } -void PvdSceneClient::createPvdInstance(const PxsCustomMaterialCore* /*materialCore*/) -{ -// PX_ASSERT(0); -} - -void PvdSceneClient::updatePvdProperties(const PxsCustomMaterialCore* /*materialCore*/) -{ -// PX_ASSERT(0); -} - -void PvdSceneClient::releasePvdInstance(const PxsCustomMaterialCore* /*materialCore*/) -{ -// PX_ASSERT(0); -} - /////////////////////////////////////////////////////////////////////////////// void PvdSceneClient::createPvdInstance(const NpShape* npShape, PxActor& owner) @@ -1173,39 +1145,6 @@ void PvdSceneClient::releasePvdInstance(const NpMPMParticleSystem* particleSyste //Todo } -/////////////////////////////////////////////////////////////////////////////// -void PvdSceneClient::createPvdInstance(const NpCustomParticleSystem* particleSystem) -{ - PX_UNUSED(particleSystem); - //Todo -} - -void PvdSceneClient::updatePvdProperties(const NpCustomParticleSystem* particleSystem) -{ - PX_UNUSED(particleSystem); - //Todo -} - -void PvdSceneClient::attachAggregateActor(const NpCustomParticleSystem* particleSystem, NpActor* actor) -{ - PX_UNUSED(particleSystem); - PX_UNUSED(actor); - //Todo -} - -void PvdSceneClient::detachAggregateActor(const NpCustomParticleSystem* particleSystem, NpActor* actor) -{ - PX_UNUSED(particleSystem); - PX_UNUSED(actor); - //Todo -} - -void PvdSceneClient::releasePvdInstance(const NpCustomParticleSystem* particleSystem) -{ - PX_UNUSED(particleSystem); - //Todo -} - /////////////////////////////////////////////////////////////////////////////// void PvdSceneClient::createPvdInstance(const NpHairSystem* hairSystem) diff --git a/physx/source/physx/src/NpPvdSceneClient.h b/physx/source/physx/src/NpPvdSceneClient.h index fa08e294a..05f2a5f79 100644 --- a/physx/source/physx/src/NpPvdSceneClient.h +++ b/physx/source/physx/src/NpPvdSceneClient.h @@ -75,7 +75,6 @@ class NpFEMCloth; class NpPBDParticleSystem; class NpFLIPParticleSystem; class NpMPMParticleSystem; -class NpCustomParticleSystem; class NpHairSystem; #endif @@ -198,10 +197,6 @@ class PvdSceneClient : public PxPvdSceneClient, public PvdClient, public PvdVisu void updatePvdProperties(const PxsMPMMaterialCore* materialCore); void releasePvdInstance (const PxsMPMMaterialCore* materialCore); - void createPvdInstance (const PxsCustomMaterialCore* materialCore); - void updatePvdProperties(const PxsCustomMaterialCore* materialCore); - void releasePvdInstance (const PxsCustomMaterialCore* materialCore); - /////////////////////////////////////////////////////////////////////////// void createPvdInstance (const NpShape* shape, PxActor& owner); @@ -249,12 +244,6 @@ class PvdSceneClient : public PxPvdSceneClient, public PvdClient, public PvdVisu void detachAggregateActor(const NpMPMParticleSystem* particleSystem, NpActor* actor); void releasePvdInstance(const NpMPMParticleSystem* particleSystem); - void createPvdInstance(const NpCustomParticleSystem* particleSystem); - void updatePvdProperties(const NpCustomParticleSystem* particleSystem); - void attachAggregateActor(const NpCustomParticleSystem* particleSystem, NpActor* actor); - void detachAggregateActor(const NpCustomParticleSystem* particleSystem, NpActor* actor); - void releasePvdInstance(const NpCustomParticleSystem* particleSystem); - void createPvdInstance(const NpHairSystem* hairSystem); void updatePvdProperties(const NpHairSystem* hairSystem); void attachAggregateActor(const NpHairSystem* hairSystem, NpActor* actor); diff --git a/physx/source/physx/src/NpRigidActorTemplate.h b/physx/source/physx/src/NpRigidActorTemplate.h index 2060f5e4d..5747f0b70 100644 --- a/physx/source/physx/src/NpRigidActorTemplate.h +++ b/physx/source/physx/src/NpRigidActorTemplate.h @@ -236,7 +236,7 @@ bool NpRigidActorTemplate::attachShape(PxShape& shape) mShapeManager.attachShape(npShape, *this); - OMNI_PVD_ADD(actor, shapes, static_cast(*this), shape) + OMNI_PVD_ADD(PxRigidActor, shapes, static_cast(*this), shape) return true; } @@ -249,7 +249,7 @@ void NpRigidActorTemplate::detachShape(PxShape& shape, bool wakeOnLost PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidActor::detachShape() not allowed while simulation is running. Call will be ignored.") - OMNI_PVD_REMOVE(actor, shapes, static_cast(*this), shape) //this needs to happen before the actual detach happens below, because that detach might actually delete the shape, which invalidates the shape handle. + OMNI_PVD_REMOVE(PxRigidActor, shapes, static_cast(*this), shape) //this needs to happen before the actual detach happens below, because that detach might actually delete the shape, which invalidates the shape handle. if (mShapeManager.getPruningStructure()) { diff --git a/physx/source/physx/src/NpRigidBodyTemplate.h b/physx/source/physx/src/NpRigidBodyTemplate.h index 9cc7d4c4c..9695b1976 100644 --- a/physx/source/physx/src/NpRigidBodyTemplate.h +++ b/physx/source/physx/src/NpRigidBodyTemplate.h @@ -241,7 +241,7 @@ class NpRigidBodyTemplate : public NpRigidActorTemplate PX_INLINE void scSetFlags(PxRigidBodyFlags f) { PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbidden()); - mCore.setFlags(RigidActorTemplateClass::getNpScene() ? RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool() : NULL, f); + mCore.setFlags(f); UPDATE_PVD_PROPERTY_BODY } @@ -249,7 +249,7 @@ class NpRigidBodyTemplate : public NpRigidActorTemplate { PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim()); - mCore.addSpatialAcceleration(RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool(), linAcc, angAcc); + mCore.addSpatialAcceleration(linAcc, angAcc); //Spatial acceleration isn't sent to PVD. } @@ -257,7 +257,7 @@ class NpRigidBodyTemplate : public NpRigidActorTemplate { PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim()); - mCore.setSpatialAcceleration(RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool(), linAcc, angAcc); + mCore.setSpatialAcceleration(linAcc, angAcc); //Spatial acceleration isn't sent to PVD. } @@ -273,7 +273,7 @@ class NpRigidBodyTemplate : public NpRigidActorTemplate { PX_ASSERT(!RigidActorTemplateClass::isAPIWriteForbiddenExceptSplitSim()); - mCore.addSpatialVelocity(RigidActorTemplateClass::getNpScene()->getScScene().getSimStateDataPool(), linVelDelta, angVelDelta); + mCore.addSpatialVelocity(linVelDelta, angVelDelta); UPDATE_PVD_PROPERTY_BODY } @@ -335,10 +335,11 @@ namespace { PX_FORCE_INLINE static bool hasNegativeMass(const PxShape& shape) { - const PxGeometryType::Enum t = shape.getGeometryType(); + const PxGeometry& geom = shape.getGeometry(); + const PxGeometryType::Enum t = geom.getType(); if (t == PxGeometryType::eTRIANGLEMESH) { - const PxTriangleMeshGeometry& triGeom = static_cast(shape.getGeometry()); + const PxTriangleMeshGeometry& triGeom = static_cast(geom); const Gu::TriangleMesh* mesh = static_cast(triGeom.triangleMesh); return mesh->getSdfDataFast().mSdf != NULL && mesh->getMass() < 0.f; } @@ -354,7 +355,7 @@ namespace PX_FORCE_INLINE static bool isSimGeom(const PxShape& shape) { - const PxGeometryType::Enum t = shape.getGeometryType(); + const PxGeometryType::Enum t = shape.getGeometry().getType(); return t != PxGeometryType::ePLANE && t != PxGeometryType::eHEIGHTFIELD && t != PxGeometryType::eTETRAHEDRONMESH && (t != PxGeometryType::eTRIANGLEMESH || isDynamicMesh(shape.getGeometry())); } @@ -395,10 +396,7 @@ void NpRigidBodyTemplate::setCMassLocalPoseInternal(const PxTransform& RigidActorTemplateClass::updateShaderComs(); -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, cMassLocalPose, *actor, body2Actor) -#endif + OMNI_PVD_SET(PxRigidBody, cMassLocalPose, static_cast(*this), body2Actor) } template @@ -424,10 +422,7 @@ void NpRigidBodyTemplate::setMass(PxReal mass) UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, mass, *actor, mass) -#endif + OMNI_PVD_SET(PxRigidBody, mass, static_cast(*this), mass) } template @@ -461,10 +456,7 @@ void NpRigidBodyTemplate::setMassSpaceInertiaTensor(const PxVec3& m) mCore.setInverseInertia(invertDiagInertia(m)); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, massSpaceInertiaTensor, *actor, m) -#endif + OMNI_PVD_SET(PxRigidBody, massSpaceInertiaTensor, static_cast(*this), m) } template @@ -713,10 +705,8 @@ PX_FORCE_INLINE void NpRigidBodyTemplate::setRigidBodyFlagsInternal(co } scSetFlags(filteredNewFlags); -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, rigidBodyFlags, *actor, filteredNewFlags) -#endif + + OMNI_PVD_SET(PxRigidBody, rigidBodyFlags, static_cast(*this), filteredNewFlags) // PT: the SQ update should be done after the scSetFlags() call if(mustUpdateSQ) @@ -760,10 +750,7 @@ void NpRigidBodyTemplate::setMinCCDAdvanceCoefficient(PxReal minCCDAdv mCore.setCCDAdvanceCoefficient(minCCDAdvanceCoefficient); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, minAdvancedCCDCoefficient, *actor, minCCDAdvanceCoefficient) -#endif + OMNI_PVD_SET(PxRigidBody, minAdvancedCCDCoefficient, static_cast(*this), minCCDAdvanceCoefficient) } @@ -785,10 +772,7 @@ void NpRigidBodyTemplate::setMaxDepenetrationVelocity(PxReal maxDepenV mCore.setMaxPenetrationBias(-maxDepenVel); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, maxDepenetrationVelocity, *actor, maxDepenVel) -#endif + OMNI_PVD_SET(PxRigidBody, maxDepenetrationVelocity, static_cast(*this), maxDepenVel) } template @@ -809,10 +793,7 @@ void NpRigidBodyTemplate::setMaxContactImpulse(const PxReal maxImpulse mCore.setMaxContactImpulse(maxImpulse); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, maxContactImpulse, *actor, maxImpulse) -#endif + OMNI_PVD_SET(PxRigidBody, maxContactImpulse, static_cast(*this), maxImpulse) } template @@ -833,10 +814,7 @@ void NpRigidBodyTemplate::setContactSlopCoefficient(const PxReal conta mCore.setOffsetSlop(contactSlopCoefficient); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, contactSlopCoefficient, *actor, contactSlopCoefficient) -#endif + OMNI_PVD_SET(PxRigidBody, contactSlopCoefficient, static_cast(*this), contactSlopCoefficient) } template @@ -865,10 +843,7 @@ void NpRigidBodyTemplate::setLinearDamping(PxReal linearDamping) mCore.setLinearDamping(linearDamping); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, linearDamping, *actor, linearDamping) -#endif + OMNI_PVD_SET(PxRigidBody, linearDamping, static_cast(*this), linearDamping) } template @@ -891,10 +866,7 @@ void NpRigidBodyTemplate::setAngularDamping(PxReal angularDamping) mCore.setAngularDamping(angularDamping); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, angularDamping, *actor, angularDamping) -#endif + OMNI_PVD_SET(PxRigidBody, angularDamping, static_cast(*this), angularDamping) } template @@ -912,15 +884,12 @@ void NpRigidBodyTemplate::setMaxAngularVelocity(PxReal maxAngularVeloc NP_WRITE_CHECK(npScene); PX_CHECK_AND_RETURN(PxIsFinite(maxAngularVelocity), "PxRigidBody::setMaxAngularVelocity(): invalid float"); PX_CHECK_AND_RETURN(maxAngularVelocity>=0.0f, "PxRigidBody::setMaxAngularVelocity(): threshold must be non-negative!"); - + PX_CHECK_AND_RETURN(maxAngularVelocity <= PxReal(1.00000003e+16f), "PxRigidBody::setMaxAngularVelocity(): maxAngularVelocity*maxAngularVelocity must be less than 1e16"); PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMaxAngularVelocity() not allowed while simulation is running. Call will be ignored.") mCore.setMaxAngVelSq(maxAngularVelocity * maxAngularVelocity); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, maxAngularVelocity, *actor, maxAngularVelocity) -#endif + OMNI_PVD_SET(PxRigidBody, maxAngularVelocity, static_cast(*this), maxAngularVelocity) } template @@ -938,15 +907,13 @@ void NpRigidBodyTemplate::setMaxLinearVelocity(PxReal maxLinearVelocit NP_WRITE_CHECK(npScene); PX_CHECK_AND_RETURN(PxIsFinite(maxLinearVelocity), "PxRigidBody::setMaxLinearVelocity(): invalid float"); PX_CHECK_AND_RETURN(maxLinearVelocity >= 0.0f, "PxRigidBody::setMaxLinearVelocity(): threshold must be non-negative!"); + PX_CHECK_AND_RETURN(maxLinearVelocity <= PxReal(1.00000003e+16), "PxRigidBody::setMaxLinearVelocity(): maxLinearVelocity*maxLinearVelocity must be less than 1e16"); PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidBody::setMaxLinearVelocity() not allowed while simulation is running. Call will be ignored.") mCore.setMaxLinVelSq(maxLinearVelocity * maxLinearVelocity); UPDATE_PVD_PROPERTY_BODY -#if PX_SUPPORT_OMNI_PVD - PxActor* actor = static_cast(this); - OMNI_PVD_SET(actor, maxLinearVelocity, *actor, maxLinearVelocity) -#endif + OMNI_PVD_SET(PxRigidBody, maxLinearVelocity, static_cast(*this), maxLinearVelocity) } template diff --git a/physx/source/physx/src/NpRigidDynamic.cpp b/physx/source/physx/src/NpRigidDynamic.cpp index f5c2ffebe..861df21a1 100644 --- a/physx/source/physx/src/NpRigidDynamic.cpp +++ b/physx/source/physx/src/NpRigidDynamic.cpp @@ -339,7 +339,7 @@ void NpRigidDynamic::setSleepThreshold(PxReal threshold) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidDynamic::setSleepThreshold() not allowed while simulation is running. Call will be ignored.") - OMNI_PVD_SET(actor, sleepThreshold, static_cast(*this), threshold); // @@@ + OMNI_PVD_SET(PxRigidDynamic, sleepThreshold, static_cast(*this), threshold); // @@@ mCore.setSleepThreshold(threshold); UPDATE_PVD_PROPERTY_BODY @@ -361,7 +361,7 @@ void NpRigidDynamic::setStabilizationThreshold(PxReal threshold) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidDynamic::setStabilizationThreshold() not allowed while simulation is running. Call will be ignored.") - OMNI_PVD_SET(actor, stabilizationThreshold, static_cast(*this), threshold); // @@@ + OMNI_PVD_SET(PxRigidDynamic, stabilizationThreshold, static_cast(*this), threshold); // @@@ mCore.setFreezeThreshold(threshold); UPDATE_PVD_PROPERTY_BODY @@ -387,7 +387,7 @@ void NpRigidDynamic::setWakeCounter(PxReal wakeCounterValue) scSetWakeCounter(wakeCounterValue); - OMNI_PVD_SET(actor, wakeCounter, static_cast(*this), wakeCounterValue); // @@@ + OMNI_PVD_SET(PxRigidDynamic, wakeCounter, static_cast(*this), wakeCounterValue); // @@@ } PxReal NpRigidDynamic::getWakeCounter() const @@ -437,8 +437,8 @@ void NpRigidDynamic::setSolverIterationCounts(PxU32 positionIters, PxU32 velocit scSetSolverIterationCounts((velocityIters & 0xff) << 8 | (positionIters & 0xff)); - OMNI_PVD_SET(actor, positionIterations, static_cast(*this), positionIters); // @@@ - OMNI_PVD_SET(actor, velocityIterations, static_cast(*this), velocityIters); // @@@ + OMNI_PVD_SET(PxRigidDynamic, positionIterations, static_cast(*this), positionIters); // @@@ + OMNI_PVD_SET(PxRigidDynamic, velocityIterations, static_cast(*this), velocityIters); // @@@ } void NpRigidDynamic::getSolverIterationCounts(PxU32 & positionIters, PxU32 & velocityIters) const @@ -459,7 +459,7 @@ void NpRigidDynamic::setContactReportThreshold(PxReal threshold) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxRigidDynamic::setContactReportThreshold() not allowed while simulation is running. Call will be ignored.") - OMNI_PVD_SET(actor, contactReportThreshold, static_cast(*this), threshold); // @@@ + OMNI_PVD_SET(PxRigidDynamic, contactReportThreshold, static_cast(*this), threshold); // @@@ mCore.setContactReportThreshold(threshold<0 ? 0 : threshold); UPDATE_PVD_PROPERTY_BODY @@ -521,7 +521,7 @@ void NpRigidDynamic::setRigidDynamicLockFlags(PxRigidDynamicLockFlags flags) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxRigidDynamic::setRigidDynamicLockFlags() not allowed while simulation is running. Call will be ignored.") scSetLockFlags(flags); - OMNI_PVD_SET(actor, rigidDynamicLockFlags, static_cast(*this), flags); // @@@ + OMNI_PVD_SET(PxRigidDynamic, rigidDynamicLockFlags, static_cast(*this), flags); // @@@ } void NpRigidDynamic::setRigidDynamicLockFlag(PxRigidDynamicLockFlag::Enum flag, bool value) @@ -535,6 +535,6 @@ void NpRigidDynamic::setRigidDynamicLockFlag(PxRigidDynamicLockFlag::Enum flag, scSetLockFlags(flags); - OMNI_PVD_SET(actor, rigidDynamicLockFlags, static_cast(*this), flags); // @@@ + OMNI_PVD_SET(PxRigidDynamic, rigidDynamicLockFlags, static_cast(*this), flags); // @@@ } diff --git a/physx/source/physx/src/NpRigidDynamic.h b/physx/source/physx/src/NpRigidDynamic.h index 2d5695c28..982068f5b 100644 --- a/physx/source/physx/src/NpRigidDynamic.h +++ b/physx/source/physx/src/NpRigidDynamic.h @@ -39,12 +39,6 @@ typedef NpRigidBodyTemplate NpRigidDynamicT; class NpRigidDynamic : public NpRigidDynamicT { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpRigidDynamic(PxBaseFlags baseFlags) : NpRigidDynamicT(baseFlags) {} @@ -75,6 +69,7 @@ class NpRigidDynamic : public NpRigidDynamicT PX_FORCE_INLINE PxTransform getGlobalPoseFast() const { const Sc::BodyCore& body = getCore(); + // PT:: tag: scalar transform*transform return body.getBody2World() * body.getBody2Actor().getInverse(); } virtual PxTransform getGlobalPose() const PX_OVERRIDE diff --git a/physx/source/physx/src/NpRigidStatic.h b/physx/source/physx/src/NpRigidStatic.h index 26f12d9ea..ad8c3f92c 100644 --- a/physx/source/physx/src/NpRigidStatic.h +++ b/physx/source/physx/src/NpRigidStatic.h @@ -40,12 +40,6 @@ typedef NpRigidActorTemplate NpRigidStaticT; class NpRigidStatic : public NpRigidStaticT { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpRigidStatic(PxBaseFlags baseFlags) : NpRigidStaticT(baseFlags), mCore(PxEmpty) {} diff --git a/physx/source/physx/src/NpScene.cpp b/physx/source/physx/src/NpScene.cpp index d6bb5cfa0..912c8df0e 100644 --- a/physx/source/physx/src/NpScene.cpp +++ b/physx/source/physx/src/NpScene.cpp @@ -120,9 +120,9 @@ static PX_FORCE_INLINE bool removeFromSceneCheck(NpScene* npScene, PxScene* scen /////////////////////////////////////////////////////////////////////////////// #if PX_SUPPORT_OMNI_PVD -static void SleepingStateChanged(PxActor* actor, bool sleeping) +static void SleepingStateChanged(PxRigidDynamic& actor, bool sleeping) { - OMNI_PVD_SET(actor, isSleeping, *actor, sleeping) + OMNI_PVD_SET(PxRigidDynamic, isSleeping, actor, sleeping) } #endif @@ -159,7 +159,6 @@ NpScene::NpScene(const PxSceneDesc& desc, NpPhysics& physics) : mConcurrentErrorCount (0), mCurrentWriter (0), mSQUpdateRunning (false), - mHasSimulatedOnce (false), mBetweenFetchResults (false), mBuildFrozenActors (false), mScene (desc, getContextId()), @@ -167,7 +166,8 @@ NpScene::NpScene(const PxSceneDesc& desc, NpPhysics& physics) : mScenePvdClient (*this), #endif mWakeCounterResetValue (desc.wakeCounterResetValue), - mPhysics (physics) + mPhysics (physics), + mName (NULL) { mGpuDynamicsConfig = desc.gpuDynamicsConfig; mSceneQueriesStaticPrunerUpdate.setObject(this); @@ -196,7 +196,7 @@ NpScene::NpScene(const PxSceneDesc& desc, NpPhysics& physics) : NpScene::~NpScene() { - OMNI_PVD_DESTROY(scene, static_cast(*this)) + OMNI_PVD_DESTROY(PxScene, static_cast(*this)) // PT: we need to do that one first, now that we don't release the objects anymore. Otherwise we end up with a sequence like: // - actor is part of an aggregate, and part of a scene @@ -231,10 +231,6 @@ NpScene::~NpScene() particleCount = mMPMParticleSystems.size(); while (particleCount--) removeParticleSystem(*mMPMParticleSystems.getEntries()[particleCount], false); - - particleCount = mCustomParticleSystems.size(); - while (particleCount--) - removeParticleSystem(*mCustomParticleSystems.getEntries()[particleCount], false); #endif PxU32 softBodyCount = mSoftBodies.size(); @@ -328,7 +324,7 @@ void NpScene::setGravity(const PxVec3& g) mScene.setGravity(g); - OMNI_PVD_SET(scene, gravity, static_cast(*this), g) + OMNI_PVD_SET(PxScene, gravity, static_cast(*this), g) updatePvdProperties(); } @@ -350,7 +346,7 @@ void NpScene::setBounceThresholdVelocity(const PxReal t) mScene.setBounceThresholdVelocity(t); updatePvdProperties(); - OMNI_PVD_SET(scene, bounceThresholdVelocity, static_cast(*this), t) + OMNI_PVD_SET(PxScene, bounceThresholdVelocity, static_cast(*this), t) } PxReal NpScene::getBounceThresholdVelocity() const @@ -381,14 +377,14 @@ void NpScene::setLimits(const PxSceneLimits& limits) updatePvdProperties(); - OMNI_PVD_SET(scene, limitsMaxNbActors, static_cast(*this), limits.maxNbActors) - OMNI_PVD_SET(scene, limitsMaxNbBodies, static_cast(*this), limits.maxNbBodies) - OMNI_PVD_SET(scene, limitsMaxNbStaticShapes, static_cast(*this), limits.maxNbStaticShapes) - OMNI_PVD_SET(scene, limitsMaxNbDynamicShapes, static_cast(*this), limits.maxNbDynamicShapes) - OMNI_PVD_SET(scene, limitsMaxNbAggregates, static_cast(*this), limits.maxNbAggregates) - OMNI_PVD_SET(scene, limitsMaxNbConstraints, static_cast(*this), limits.maxNbConstraints) - OMNI_PVD_SET(scene, limitsMaxNbRegions, static_cast(*this), limits.maxNbRegions) - OMNI_PVD_SET(scene, limitsMaxNbBroadPhaseOverlaps, static_cast(*this), limits.maxNbBroadPhaseOverlaps) + OMNI_PVD_SET(PxScene, limitsMaxNbActors, static_cast(*this), limits.maxNbActors) + OMNI_PVD_SET(PxScene, limitsMaxNbBodies, static_cast(*this), limits.maxNbBodies) + OMNI_PVD_SET(PxScene, limitsMaxNbStaticShapes, static_cast(*this), limits.maxNbStaticShapes) + OMNI_PVD_SET(PxScene, limitsMaxNbDynamicShapes, static_cast(*this), limits.maxNbDynamicShapes) + OMNI_PVD_SET(PxScene, limitsMaxNbAggregates, static_cast(*this), limits.maxNbAggregates) + OMNI_PVD_SET(PxScene, limitsMaxNbConstraints, static_cast(*this), limits.maxNbConstraints) + OMNI_PVD_SET(PxScene, limitsMaxNbRegions, static_cast(*this), limits.maxNbRegions) + OMNI_PVD_SET(PxScene, limitsMaxNbBroadPhaseOverlaps, static_cast(*this), limits.maxNbBroadPhaseOverlaps) } @@ -419,14 +415,14 @@ void NpScene::setFlag(PxSceneFlag::Enum flag, bool value) else currentFlags &= ~PxSceneFlags(flag); - mScene.setPublicFlags(currentFlags); + mScene.setFlags(currentFlags); const bool pcm = (currentFlags & PxSceneFlag::eENABLE_PCM); mScene.setPCM(pcm); const bool contactCache = !(currentFlags & PxSceneFlag::eDISABLE_CONTACT_CACHE); mScene.setContactCache(contactCache); updatePvdProperties(); - OMNI_PVD_SET(scene, flags, static_cast(*this), getFlags()) + OMNI_PVD_SET(PxScene, flags, static_cast(*this), getFlags()) } PxSceneFlags NpScene::getFlags() const @@ -435,6 +431,20 @@ PxSceneFlags NpScene::getFlags() const return mScene.getFlags(); } +void NpScene::setName(const char* name) +{ + mName = name; +#if PX_SUPPORT_OMNI_PVD + PxScene & s = *this; + streamSceneName(s, mName); +#endif +} + +const char* NpScene::getName() const +{ + return mName; +} + /////////////////////////////////////////////////////////////////////////////// template @@ -532,7 +542,6 @@ bool NpScene::addActorInternal(PxActor& actor, const PxBVH* bvh) case (PxConcreteType::ePBD_PARTICLESYSTEM): case (PxConcreteType::eFLIP_PARTICLESYSTEM): case (PxConcreteType::eMPM_PARTICLESYSTEM): - case (PxConcreteType::eCUSTOM_PARTICLESYSTEM): { return addParticleSystem(static_cast(actor)); } @@ -731,7 +740,7 @@ static void removeActorT(NpScene* npScene, ActorT& actor, PxArray& acto npScene->scRemoveActor(actor, wakeOnLostTouch, noSim); removeFromRigidActorListT(actor, actors, npScene->mRigidActorIndexPool); - OMNI_PVD_REMOVE(scene, actors, static_cast(*npScene), static_cast(actor)) + OMNI_PVD_REMOVE(PxScene, actors, static_cast(*npScene), static_cast(actor)) } void NpScene::removeActors(PxActor*const* PX_RESTRICT actors, PxU32 nbActors, bool wakeOnLostTouch) @@ -853,12 +862,6 @@ void NpScene::removeActorInternal(PxActor& actor, bool wakeOnLostTouch, bool rem } break; - case PxActorType::eCUSTOM_PARTICLESYSTEM: - { - PxCustomParticleSystem& npParticleSystem = static_cast(actor); - removeParticleSystem(npParticleSystem, wakeOnLostTouch); - } - break; case PxActorType::eHAIRSYSTEM: { NpHairSystem& npHairSystem = static_cast(actor); @@ -885,10 +888,11 @@ static PX_FORCE_INLINE bool addRigidActorT(T& rigidActor, PxArray& rigidActo for (PxU32 i = 0; i < rigidActor.getShapeManager().getNbShapes(); ++i) { const NpShape* shape = rigidActor.getShapeManager().getShapes()[i]; - const PxGeometryType::Enum t = shape->getGeometryType(); + const PxGeometry& geom = shape->getGeometry(); + const PxGeometryType::Enum t = geom.getType(); if (t == PxGeometryType::eTRIANGLEMESH) { - const PxTriangleMeshGeometry& triGeom = static_cast(shape->getGeometry()); + const PxTriangleMeshGeometry& triGeom = static_cast(geom); if (triGeom.triangleMesh->getSDF() != NULL) { return outputError(__LINE__, "PxScene::addRigidActor(): Rigid actors with SDFs are currently only supported with GPU-accelerated scenes!"); @@ -914,7 +918,7 @@ static PX_FORCE_INLINE bool addRigidActorT(T& rigidActor, PxArray& rigidActo if(!isNoSimActor) rigidActor.addConstraintsToScene(); - OMNI_PVD_ADD(scene, actors, static_cast(*scene), static_cast(rigidActor)) + OMNI_PVD_ADD(PxScene, actors, static_cast(*scene), static_cast(rigidActor)) return true; } @@ -957,7 +961,7 @@ static PX_FORCE_INLINE void removeRigidActorT(T& rigidActor, NpScene* scene, boo scene->scRemoveActor(rigidActor, wakeOnLostTouch, isNoSimActor); scene->removeFromRigidActorList(rigidActor); - OMNI_PVD_REMOVE(scene, actors, static_cast(*scene), static_cast(rigidActor)) + OMNI_PVD_REMOVE(PxScene, actors, static_cast(*scene), static_cast(rigidActor)) } void NpScene::removeRigidStatic(NpRigidStatic& actor, bool wakeOnLostTouch, bool removeFromAggregate) @@ -1282,10 +1286,9 @@ bool NpScene::addArticulationInternal(PxArticulationReducedCoordinate& npa) //add loop joints - if ((scArtCore.getArticulationFlags() & PxArticulationFlag::eFIX_BASE)) - { - rootLink->setKinematicLink(true); - } + if(scArtCore.getArticulationFlags() & PxArticulationFlag::eFIX_BASE) + rootLink->setFixedBaseLink(true); + //This method will prepare link data for the gpu mScene.addArticulationSimControl(scArtCore); const PxU32 maxLinks = mScene.getMaxArticulationLinks(); @@ -1368,8 +1371,8 @@ bool NpScene::addArticulationInternal(PxArticulationReducedCoordinate& npa) } } - OMNI_PVD_ADD(scene, articulations, static_cast(*this), static_cast(npa)); - OMNI_PVD_SET(articulation, dofs, static_cast(npa), npa.getDofs()); + OMNI_PVD_ADD(PxScene, articulations, static_cast(*this), static_cast(npa)); + OMNI_PVD_SET(PxArticulationReducedCoordinate, dofs, static_cast(npa), npa.getDofs()); return true; } @@ -1386,7 +1389,6 @@ void NpScene::removeArticulation(PxArticulationReducedCoordinate& articulation, void NpScene::removeArticulationInternal(PxArticulationReducedCoordinate& pxa, bool wakeOnLostTouch, bool removeFromAggregate) { - NpArticulationReducedCoordinate& npArticulation = static_cast(pxa); PxU32 nbLinks = npArticulation.getNbLinks(); @@ -1446,8 +1448,8 @@ void NpScene::removeArticulationInternal(PxArticulationReducedCoordinate& pxa, b scRemoveArticulation(npArticulation); removeFromArticulationList(npArticulation); - OMNI_PVD_REMOVE(scene, articulations, static_cast(*this), pxa) - OMNI_PVD_SET(articulation, dofs, pxa, pxa.getDofs()); + OMNI_PVD_REMOVE(PxScene, articulations, static_cast(*this), pxa) + OMNI_PVD_SET(PxArticulationReducedCoordinate, dofs, pxa, pxa.getDofs()); } /////////////////////////////////////////////////////////////////////////////// @@ -1640,20 +1642,6 @@ bool NpScene::addParticleSystem(PxParticleSystem& particleSystem) return true; } - - case PxConcreteType::eCUSTOM_PARTICLESYSTEM: - { - NpCustomParticleSystem& npPS = static_cast(particleSystem); - scAddParticleSystem(npPS); - - PxCustomParticleSystem& pxPS = static_cast(particleSystem); - mCustomParticleSystems.insert(&pxPS); - - //for gpu particle system - mScene.addParticleSystemSimControl(npPS.getCore()); - - return true; - } #endif default: { @@ -1705,17 +1693,6 @@ void NpScene::removeParticleSystem(PxParticleSystem& particleSystem, bool /*wake removeFromParticleSystemList(pxPS); return; } - - case PxConcreteType::eCUSTOM_PARTICLESYSTEM: - { - // Remove particle system - NpCustomParticleSystem& npPS = reinterpret_cast(particleSystem); - scRemoveParticleSystem(npPS); - - PxCustomParticleSystem& pxPS = static_cast(particleSystem); - removeFromParticleSystemList(pxPS); - return; - } #endif default: PX_ASSERT(false); @@ -1755,14 +1732,6 @@ PxU32 NpScene::getNbParticleSystems(PxParticleSolverType::Enum type) const #endif } - case PxParticleSolverType::eCUSTOM: - { -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - return mCustomParticleSystems.size(); -#else - return 0; -#endif - } default: { PX_ASSERT(false); @@ -1799,11 +1768,6 @@ PxU32 NpScene::getParticleSystems(PxParticleSolverType::Enum type, PxParticleSys { return Cm::getArrayOfPointers(userBuffer, bufferSize, startIndex, mMPMParticleSystems.getEntries(), mMPMParticleSystems.size()); } - - case PxParticleSolverType::eCUSTOM: - { - return Cm::getArrayOfPointers(userBuffer, bufferSize, startIndex, mCustomParticleSystems.getEntries(), mCustomParticleSystems.size()); - } #endif default: { @@ -2085,53 +2049,34 @@ bool NpScene::addAggregate(PxAggregate& aggregate) NpAggregate& np = static_cast(aggregate); - const PxU32 nb = np.getCurrentSizeFast(); #if PX_CHECKED - for(PxU32 i=0;iis(); - if(a && !static_cast(a)->checkConstraintValidity()) - return outputError(__LINE__, "PxScene::addAggregate(): Aggregate contains an actor with an invalid constraint!"); + const PxU32 nb = np.getCurrentSizeFast(); + for(PxU32 i=0;iis(); + if(a && !static_cast(a)->checkConstraintValidity()) + return outputError(__LINE__, "PxScene::addAggregate(): Aggregate contains an actor with an invalid constraint!"); + } } #endif - if(mScene.isUsingGpuDynamicsOrBp()) - { - if(np.getMaxNbShapesFast() == PX_MAX_U32) - return outputError(__LINE__, "PxScene::addAggregate(): Aggregates cannot be added to GPU scene unless you provide a maxNbShapes!"); - } - - if(!np.getNpScene()) - { - scAddAggregate(np); - - for(PxU32 i=0;i(__LINE__, "PxScene::addAggregate(): Aggregates cannot be added to GPU scene unless you provide a maxNbShapes!"); - //A.B. check if a bvh was connected to that actor, we will use it for the insert and remove it - NpActor& npActor = NpActor::getFromPxActor(actor); - BVH* bvh = NULL; - if(npActor.getConnectors(NpConnectorType::eBvh, &bvh, 1)) - npActor.removeConnector(actor, NpConnectorType::eBvh, bvh, "PxBVH connector could not have been removed!"); + if(np.getNpScene()) + return outputError(__LINE__, "PxScene::addAggregate(): Aggregate already assigned to a scene. Call will be ignored!"); - np.addActorInternal(actor, *this, bvh); + scAddAggregate(np); - // if a bvh was used dec ref count, we increased the ref count when adding the actor connection - if(bvh) - bvh->decRefCount(); - } + np.addToScene(*this); - mAggregates.insert(&aggregate); + mAggregates.insert(&aggregate); - OMNI_PVD_ADD(scene, aggregates, static_cast(*this), aggregate); - OMNI_PVD_SET(aggregate, scene, aggregate, static_cast(this)); + OMNI_PVD_ADD(PxScene, aggregates, static_cast(*this), aggregate); + OMNI_PVD_SET(PxAggregate, scene, aggregate, static_cast(this)); - return true; - } - else - return outputError(__LINE__, "PxScene::addAggregate(): Aggregate already assigned to a scene. Call will be ignored!"); + return true; } void NpScene::removeAggregate(PxAggregate& aggregate, bool wakeOnLostTouch) @@ -2181,8 +2126,8 @@ void NpScene::removeAggregate(PxAggregate& aggregate, bool wakeOnLostTouch) removeFromAggregateList(aggregate); - OMNI_PVD_REMOVE(scene, aggregates, static_cast(*this), aggregate); - OMNI_PVD_SET(aggregate, scene, aggregate, static_cast(NULL)); + OMNI_PVD_REMOVE(PxScene, aggregates, static_cast(*this), aggregate); + OMNI_PVD_SET(PxAggregate, scene, aggregate, static_cast(NULL)); } PxU32 NpScene::getNbAggregates() const @@ -2558,7 +2503,7 @@ void NpScene::setSimulationEventCallback(PxSimulationEventCallback* callback) mScene.setSimulationEventCallback(callback); updatePvdProperties(); - OMNI_PVD_SET(scene, hasSimulationEventCallback, static_cast(*this), callback ? true : false) + OMNI_PVD_SET(PxScene, hasSimulationEventCallback, static_cast(*this), callback ? true : false) } PxSimulationEventCallback* NpScene::getSimulationEventCallback() const @@ -2575,7 +2520,7 @@ void NpScene::setContactModifyCallback(PxContactModifyCallback* callback) mScene.setContactModifyCallback(callback); updatePvdProperties(); - OMNI_PVD_SET(scene, hasContactModifyCallback, static_cast(*this), callback ? true : false) + OMNI_PVD_SET(PxScene, hasContactModifyCallback, static_cast(*this), callback ? true : false) } PxContactModifyCallback* NpScene::getContactModifyCallback() const @@ -2592,7 +2537,7 @@ void NpScene::setCCDContactModifyCallback(PxCCDContactModifyCallback* callback) mScene.setCCDContactModifyCallback(callback); updatePvdProperties(); - OMNI_PVD_SET(scene, hasCCDContactModifyCallback, static_cast(*this), callback ? true : false) + OMNI_PVD_SET(PxScene, hasCCDContactModifyCallback, static_cast(*this), callback ? true : false) } PxCCDContactModifyCallback* NpScene::getCCDContactModifyCallback() const @@ -2607,15 +2552,15 @@ void NpScene::setBroadPhaseCallback(PxBroadPhaseCallback* callback) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(this, "PxScene::setBroadPhaseCallback() not allowed while simulation is running. Call will be ignored.") - mScene.setBroadPhaseCallback(callback); + mScene.getBroadphaseManager().setBroadPhaseCallback(callback); updatePvdProperties(); - OMNI_PVD_SET(scene, hasBroadPhaseCallback, static_cast(*this), callback ? true : false) + OMNI_PVD_SET(PxScene, hasBroadPhaseCallback, static_cast(*this), callback ? true : false) } PxBroadPhaseCallback* NpScene::getBroadPhaseCallback() const { NP_READ_CHECK(this); - return mScene.getBroadPhaseCallback(); + return mScene.getBroadphaseManager().getBroadPhaseCallback(); } void NpScene::setCCDMaxPasses(PxU32 ccdMaxPasses) @@ -2627,7 +2572,7 @@ void NpScene::setCCDMaxPasses(PxU32 ccdMaxPasses) mScene.setCCDMaxPasses(ccdMaxPasses); updatePvdProperties(); - OMNI_PVD_SET(scene, ccdMaxPasses, static_cast(*this), ccdMaxPasses) + OMNI_PVD_SET(PxScene, ccdMaxPasses, static_cast(*this), ccdMaxPasses) } PxU32 NpScene::getCCDMaxPasses() const @@ -2645,7 +2590,7 @@ void NpScene::setCCDMaxSeparation(const PxReal separation) mScene.setCCDMaxSeparation(separation); updatePvdProperties(); - OMNI_PVD_SET(scene, ccdMaxSeparation, static_cast(*this), separation) + OMNI_PVD_SET(PxScene, ccdMaxSeparation, static_cast(*this), separation) } PxReal NpScene::getCCDMaxSeparation() const @@ -2663,7 +2608,7 @@ void NpScene::setCCDThreshold(const PxReal t) mScene.setCCDThreshold(t); updatePvdProperties(); - OMNI_PVD_SET(scene, ccdThreshold, static_cast(*this), t) + OMNI_PVD_SET(PxScene, ccdThreshold, static_cast(*this), t) } PxReal NpScene::getCCDThreshold() const @@ -2974,7 +2919,25 @@ static void updateLowLevelMaterials(NpPhysics& physics, PxMutex& sceneMaterialBu materialBuffer.resize(0); } +void NpScene::syncMaterialEvents() +{ + //sync all the material events + PxvNphaseImplementationContext* context = mScene.getLowLevelContext()->getNphaseImplementationContext(); + updateLowLevelMaterials(mPhysics, mSceneMaterialBufferLock, mScene.getMaterialManager(), mSceneMaterialBuffer, context); + +#if PX_SUPPORT_GPU_PHYSX + updateLowLevelMaterials (mPhysics, mSceneFEMSoftBodyMaterialBufferLock, mScene.getFEMMaterialManager(), mSceneFEMSoftBodyMaterialBuffer, context); + updateLowLevelMaterials (mPhysics, mScenePBDMaterialBufferLock, mScene.getPBDMaterialManager(), mScenePBDMaterialBuffer, context); + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + updateLowLevelMaterials (mPhysics, mSceneFEMClothMaterialBufferLock, mScene.getFEMClothMaterialManager(), mSceneFEMClothMaterialBuffer, context); + updateLowLevelMaterials (mPhysics, mSceneFLIPMaterialBufferLock, mScene.getFLIPMaterialManager(), mSceneFLIPMaterialBuffer, context); + updateLowLevelMaterials (mPhysics, mSceneMPMMaterialBufferLock, mScene.getMPMMaterialManager(), mSceneMPMMaterialBuffer, context); + #endif +#endif +} + /////////////////////////////////////////////////////////////////////////////// + bool NpScene::simulateOrCollide(PxReal elapsedTime, PxBaseTask* completionTask, void* scratchBlock, PxU32 scratchBlockSize, bool controlSimulation, const char* invalidCallMsg, Sc::SimulationStage::Enum simStage) { PX_SIMD_GUARD; @@ -2998,8 +2961,12 @@ bool NpScene::simulateOrCollide(PxReal elapsedTime, PxBaseTask* completionTask, { if (mScene.isUsingGpuDynamicsOrBp()) { - if (mCudaContextManager->getCudaContext()->getLastError()) - return outputError(__LINE__, "PhysX Internal CUDA error. Simulation can not continue!"); + PxCUresult lastError = mCudaContextManager->getCudaContext()->getLastError(); + if (lastError) + { + PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "PhysX Internal CUDA error. Simulation can not continue! Error code %i!\n", PxI32(lastError)); + //return outputError(__LINE__, "PhysX Internal CUDA error. Simulation can not continue!"); + } } } #endif @@ -3035,28 +3002,12 @@ bool NpScene::simulateOrCollide(PxReal elapsedTime, PxBaseTask* completionTask, mControllingSimulation = controlSimulation; - //sync all the material events - PxvNphaseImplementationContext* context = mScene.getLowLevelContext()->getNphaseImplementationContext(); - updateLowLevelMaterials(mPhysics, mSceneMaterialBufferLock, mScene.getMaterialManager(), mSceneMaterialBuffer, context); - -#if PX_SUPPORT_GPU_PHYSX - updateLowLevelMaterials (mPhysics, mSceneFEMSoftBodyMaterialBufferLock, mScene.getFEMMaterialManager(), mSceneFEMSoftBodyMaterialBuffer, context); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - updateLowLevelMaterials (mPhysics, mSceneFEMClothMaterialBufferLock, mScene.getFEMClothMaterialManager(), mSceneFEMClothMaterialBuffer, context); -#endif - updateLowLevelMaterials (mPhysics, mScenePBDMaterialBufferLock, mScene.getPBDMaterialManager(), mScenePBDMaterialBuffer, context); -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - updateLowLevelMaterials (mPhysics, mSceneFLIPMaterialBufferLock, mScene.getFLIPMaterialManager(), mSceneFLIPMaterialBuffer, context); - updateLowLevelMaterials (mPhysics, mSceneMPMMaterialBufferLock, mScene.getMPMMaterialManager(), mSceneMPMMaterialBuffer, context); - updateLowLevelMaterials (mPhysics, mSceneCustomMaterialBufferLock, mScene.getCustomMaterialManager(), mSceneCustomMaterialBuffer, context); -#endif -#endif + syncMaterialEvents(); setSimulationStage(simStage); setAPIWriteToForbidden(); setAPIReadToForbidden(); mScene.setCollisionPhaseToActive(); - mHasSimulatedOnce = true; } { @@ -3246,7 +3197,6 @@ IMPLEMENT_MATERIAL(NpMaterial, PxsMaterialCore, mSceneMaterialBufferLock, mScene #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION IMPLEMENT_MATERIAL(NpFLIPMaterial, PxsFLIPMaterialCore, mSceneFLIPMaterialBufferLock, mSceneFLIPMaterialBuffer) IMPLEMENT_MATERIAL(NpMPMMaterial, PxsMPMMaterialCore, mSceneMPMMaterialBufferLock, mSceneMPMMaterialBuffer) - IMPLEMENT_MATERIAL(NpCustomMaterial, PxsCustomMaterialCore, mSceneCustomMaterialBufferLock, mSceneCustomMaterialBuffer) #endif #endif @@ -3300,7 +3250,7 @@ void NpScene::setSolverBatchSize(PxU32 solverBatchSize) mScene.setSolverBatchSize(solverBatchSize); updatePvdProperties(); - OMNI_PVD_SET(scene, solverBatchSize, static_cast(*this), solverBatchSize) + OMNI_PVD_SET(PxScene, solverBatchSize, static_cast(*this), solverBatchSize) } PxU32 NpScene::getSolverBatchSize(void) const @@ -3318,7 +3268,7 @@ void NpScene::setSolverArticulationBatchSize(PxU32 solverBatchSize) mScene.setSolverArticBatchSize(solverBatchSize); updatePvdProperties(); - OMNI_PVD_SET(scene, solverArticulationBatchSize, static_cast(*this), solverBatchSize) + OMNI_PVD_SET(PxScene, solverArticulationBatchSize, static_cast(*this), solverBatchSize) } PxU32 NpScene::getSolverArticulationBatchSize(void) const @@ -3382,7 +3332,7 @@ void NpScene::setNbContactDataBlocks(PxU32 numBlocks) "PxScene::setNbContactDataBlock: This call is not allowed while the simulation is running. Call will be ignored!"); mScene.setNbContactDataBlocks(numBlocks); - OMNI_PVD_SET(scene, nbContactDataBlocks, static_cast(*this), numBlocks) + OMNI_PVD_SET(PxScene, nbContactDataBlocks, static_cast(*this), numBlocks) } PxU32 NpScene::getNbContactDataBlocksUsed() const @@ -3425,7 +3375,7 @@ void NpScene::setMaxBiasCoefficient(const PxReal coeff) mScene.setMaxBiasCoefficient(coeff); updatePvdProperties(); - OMNI_PVD_SET(scene, maxBiasCoefficient, static_cast(*this), coeff) + OMNI_PVD_SET(PxScene, maxBiasCoefficient, static_cast(*this), coeff) } PxReal NpScene::getMaxBiasCoefficient() const @@ -3443,7 +3393,7 @@ void NpScene::setFrictionOffsetThreshold(const PxReal t) mScene.setFrictionOffsetThreshold(t); updatePvdProperties(); - OMNI_PVD_SET(scene, frictionOffsetThreshold, static_cast(*this), t) + OMNI_PVD_SET(PxScene, frictionOffsetThreshold, static_cast(*this), t) } PxReal NpScene::getFrictionOffsetThreshold() const @@ -3461,7 +3411,7 @@ void NpScene::setFrictionCorrelationDistance(const PxReal t) mScene.setFrictionCorrelationDistance(t); updatePvdProperties(); - OMNI_PVD_SET(scene, frictionCorrelationDistance, static_cast(*this), t) + OMNI_PVD_SET(PxScene, frictionCorrelationDistance, static_cast(*this), t) } PxReal NpScene::getFrictionCorrelationDistance() const @@ -3831,7 +3781,7 @@ void NpScene::copyArticulationData(void* jointData, void* index, PxArticulationG return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->copyArticulationData(jointData, index, dataType, nbCopyArticulations, copyEvent); } @@ -3845,22 +3795,22 @@ void NpScene::applyArticulationData(void* data, void* index, PxArticulationGpuDa return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->applyArticulationData(data,index, dataType, nbUpdatedArticulations, waitEvent, signalEvent); } -void NpScene::copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent) +void NpScene::copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyGpuDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent) { PX_CHECK_SCENE_API_READ_FORBIDDEN(this, "PxScene::copySoftBodyData() not allowed while simulation is running. Call will be ignored."); - //if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuRigidBodies()) + //if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuRigidBodies()) mScene.getSimulationController()->copySoftBodyData(data, dataSizes, softBodyIndices, flag, nbCopySoftBodies, maxSize, copyEvent); } -void NpScene::applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbUpdatedSoftBodies, const PxU32 maxSize, void* applyEvent) +void NpScene::applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyGpuDataFlag::Enum flag, const PxU32 nbUpdatedSoftBodies, const PxU32 maxSize, void* applyEvent) { PX_CHECK_SCENE_API_WRITE_FORBIDDEN(this, "PxScene::applySoftBodyData() not allowed while simulation is running. Call will be ignored."); - //if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuRigidBodies()) + //if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuRigidBodies()) mScene.getSimulationController()->applySoftBodyData(data, dataSizes, softBodyIndices, flag, nbUpdatedSoftBodies, maxSize, applyEvent); } @@ -3874,7 +3824,7 @@ void NpScene::copyContactData(void* data, const PxU32 maxContactPairs, void* num return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->copyContactData(mScene.getDynamicsContext(), data, maxContactPairs, numContactPairs, copyEvent); } @@ -3888,7 +3838,7 @@ void NpScene::copyBodyData(PxGpuBodyData* data, PxGpuActorPair* index, const PxU return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->copyBodyData(data, index, nbCopyActors, copyEvent); } @@ -3902,10 +3852,18 @@ void NpScene::applyActorData(void* data, PxGpuActorPair* index, PxActorCacheFlag return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->applyActorData(data, index, flag, nbUpdatedActors, waitEvent, signalEvent); } +void NpScene::evaluateSDFDistances(const PxU32* sdfShapeIds, const PxU32 nbShapes, const PxVec4* samplePointsConcatenated, + const PxU32* samplePointCountPerShape, const PxU32 maxPointCount, PxVec4* localGradientAndSDFConcatenated, void* event) +{ + PX_CHECK_SCENE_API_WRITE_FORBIDDEN(this, "PxScene::evaluateSDFDistances() not allowed while simulation is running. Call will be ignored."); + mScene.getSimulationController()->evaluateSDFDistances(sdfShapeIds, nbShapes, samplePointsConcatenated, + samplePointCountPerShape, maxPointCount, localGradientAndSDFConcatenated, event); +} + void NpScene::computeDenseJacobians(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) { PX_CHECK_SCENE_API_READ_FORBIDDEN(this, "PxScene::computeDenseJacobians() not allowed while simulation is running. Call will be ignored."); @@ -3916,7 +3874,7 @@ void NpScene::computeDenseJacobians(const PxIndexDataPair* indices, PxU32 nbIndi return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->computeDenseJacobians(indices, nbIndices, computeEvent); } @@ -3930,7 +3888,7 @@ void NpScene::computeGeneralizedMassMatrices(const PxIndexDataPair* indices, PxU return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->computeGeneralizedMassMatrices(indices, nbIndices, computeEvent); } @@ -3944,7 +3902,7 @@ void NpScene::computeGeneralizedGravityForces(const PxIndexDataPair* indices, Px return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->computeGeneralizedGravityForces(indices, nbIndices, getGravity(), computeEvent); } @@ -3958,7 +3916,7 @@ void NpScene::computeCoriolisAndCentrifugalForces(const PxIndexDataPair* indices return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->computeCoriolisAndCentrifugalForces(indices, nbIndices, computeEvent); } @@ -3972,7 +3930,7 @@ void NpScene::applyParticleBufferData(const PxU32* indices, const PxGpuParticleB return; } - if ((mScene.getFlags() & PxSceneFlag::eSUPPRESS_READBACK) && mScene.isUsingGpuDynamicsOrBp()) + if ((mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && mScene.isUsingGpuDynamicsOrBp()) mScene.getSimulationController()->applyParticleBufferData(indices, indexPairs, flags, nbUpdatedBuffers, waitEvent, signalEvent); } @@ -4229,19 +4187,6 @@ template<> struct ScSceneFns } }; -template<> struct ScSceneFns -{ - static PX_FORCE_INLINE void insert(Sc::Scene& s, NpCustomParticleSystem& v, PxBounds3*, const BVH*, bool) - { - s.addParticleSystem(v.getCore()); - } - - static PX_FORCE_INLINE void remove(Sc::Scene& s, NpCustomParticleSystem& v, bool /*wakeOnLostTouch*/) - { - s.removeParticleSystem(v.getCore()); - } -}; - template<> struct ScSceneFns { static PX_FORCE_INLINE void insert(Sc::Scene& s, NpHairSystem& v, PxBounds3*, const BVH*, bool) @@ -4523,7 +4468,7 @@ static PX_FORCE_INLINE void addActorT(NpScene* npScene, T& actor, bool noSim, Px PvdFns::createInstance(*npScene, pvdClient, &actor); #endif - OMNI_PVD_ADD(scene, actors, static_cast(*npScene), static_cast(actor)) + OMNI_PVD_ADD(PxScene, actors, static_cast(*npScene), static_cast(actor)) addNonSimActor(actor); } @@ -4712,18 +4657,6 @@ void NpScene::scRemoveParticleSystem(NpMPMParticleSystem& particleSystem) //////////////////////////////////////////////////////////////////////////////// -void NpScene::scAddParticleSystem(NpCustomParticleSystem& particleSystem) -{ - add(this, particleSystem); -} - -void NpScene::scRemoveParticleSystem(NpCustomParticleSystem& particleSystem) -{ - mScene.removeParticleSystemSimControl(particleSystem.getCore()); - remove(this, particleSystem); -} -//////////////////////////////////////////////////////////////////////////////// - void NpScene::scAddHairSystem(NpHairSystem& hairSystem) { add(this, hairSystem); @@ -4802,54 +4735,53 @@ void NpScene::createInOmniPVD(const PxSceneDesc& desc) { PX_UNUSED(desc); - OMNI_PVD_CREATE(scene, static_cast(*this)) - - OMNI_PVD_SET(scene, gravity, static_cast(*this), getGravity()) - OMNI_PVD_SET(scene, flags, static_cast(*this), getFlags()) - OMNI_PVD_SET(scene, frictionType, static_cast(*this), getFrictionType()) - OMNI_PVD_SET(scene, broadPhaseType, static_cast(*this), getBroadPhaseType()) - OMNI_PVD_SET(scene, kineKineFilteringMode, static_cast(*this), getKinematicKinematicFilteringMode()) - OMNI_PVD_SET(scene, staticKineFilteringMode, static_cast(*this), getStaticKinematicFilteringMode()) - - OMNI_PVD_SET(scene, solverType, static_cast(*this), getSolverType()) - OMNI_PVD_SET(scene, bounceThresholdVelocity, static_cast(*this), getBounceThresholdVelocity()) - OMNI_PVD_SET(scene, frictionOffsetThreshold, static_cast(*this), getFrictionOffsetThreshold()) - OMNI_PVD_SET(scene, frictionCorrelationDistance, static_cast(*this), getFrictionCorrelationDistance()) - OMNI_PVD_SET(scene, solverBatchSize, static_cast(*this), getSolverBatchSize()) - OMNI_PVD_SET(scene, solverArticulationBatchSize, static_cast(*this), getSolverArticulationBatchSize()) - OMNI_PVD_SET(scene, nbContactDataBlocks, static_cast(*this), getNbContactDataBlocksUsed()) - OMNI_PVD_SET(scene, maxNbContactDataBlocks, static_cast(*this), getMaxNbContactDataBlocksUsed())//naming problem of functions - OMNI_PVD_SET(scene, maxBiasCoefficient, static_cast(*this), getMaxBiasCoefficient()) - OMNI_PVD_SET(scene, contactReportStreamBufferSize, static_cast(*this), getContactReportStreamBufferSize()) - OMNI_PVD_SET(scene, ccdMaxPasses, static_cast(*this), getCCDMaxPasses()) - OMNI_PVD_SET(scene, ccdThreshold, static_cast(*this), getCCDThreshold()) - OMNI_PVD_SET(scene, ccdMaxSeparation, static_cast(*this), getCCDMaxSeparation()) - OMNI_PVD_SET(scene, wakeCounterResetValue, static_cast(*this), getWakeCounterResetValue()) - //OMNI_PVD_SET(scene, sceneQuerySystem, static_cast(*this), getSQAPI())//needs class + OMNI_PVD_CREATE(PxScene, static_cast(*this)) + + OMNI_PVD_SET(PxScene, gravity, static_cast(*this), getGravity()) + OMNI_PVD_SET(PxScene, flags, static_cast(*this), getFlags()) + OMNI_PVD_SET(PxScene, frictionType, static_cast(*this), getFrictionType()) + OMNI_PVD_SET(PxScene, broadPhaseType, static_cast(*this), getBroadPhaseType()) + OMNI_PVD_SET(PxScene, kineKineFilteringMode, static_cast(*this), getKinematicKinematicFilteringMode()) + OMNI_PVD_SET(PxScene, staticKineFilteringMode, static_cast(*this), getStaticKinematicFilteringMode()) + + OMNI_PVD_SET(PxScene, solverType, static_cast(*this), getSolverType()) + OMNI_PVD_SET(PxScene, bounceThresholdVelocity, static_cast(*this), getBounceThresholdVelocity()) + OMNI_PVD_SET(PxScene, frictionOffsetThreshold, static_cast(*this), getFrictionOffsetThreshold()) + OMNI_PVD_SET(PxScene, frictionCorrelationDistance, static_cast(*this), getFrictionCorrelationDistance()) + OMNI_PVD_SET(PxScene, solverBatchSize, static_cast(*this), getSolverBatchSize()) + OMNI_PVD_SET(PxScene, solverArticulationBatchSize, static_cast(*this), getSolverArticulationBatchSize()) + OMNI_PVD_SET(PxScene, nbContactDataBlocks, static_cast(*this), getNbContactDataBlocksUsed()) + OMNI_PVD_SET(PxScene, maxNbContactDataBlocks, static_cast(*this), getMaxNbContactDataBlocksUsed())//naming problem of functions + OMNI_PVD_SET(PxScene, maxBiasCoefficient, static_cast(*this), getMaxBiasCoefficient()) + OMNI_PVD_SET(PxScene, contactReportStreamBufferSize, static_cast(*this), getContactReportStreamBufferSize()) + OMNI_PVD_SET(PxScene, ccdMaxPasses, static_cast(*this), getCCDMaxPasses()) + OMNI_PVD_SET(PxScene, ccdThreshold, static_cast(*this), getCCDThreshold()) + OMNI_PVD_SET(PxScene, ccdMaxSeparation, static_cast(*this), getCCDMaxSeparation()) + OMNI_PVD_SET(PxScene, wakeCounterResetValue, static_cast(*this), getWakeCounterResetValue()) + //OMNI_PVD_SET(PxScene, sceneQuerySystem, static_cast(*this), getSQAPI())//needs class //OMNI_PVD_CREATE(scenelimits, limits)//owned temp object .. would be cool if this could be automated - OMNI_PVD_SET(scene, limitsMaxNbActors, static_cast(*this), desc.limits.maxNbActors) - OMNI_PVD_SET(scene, limitsMaxNbBodies, static_cast(*this), desc.limits.maxNbBodies) - OMNI_PVD_SET(scene, limitsMaxNbStaticShapes, static_cast(*this), desc.limits.maxNbStaticShapes) - OMNI_PVD_SET(scene, limitsMaxNbDynamicShapes, static_cast(*this), desc.limits.maxNbDynamicShapes) - OMNI_PVD_SET(scene, limitsMaxNbAggregates, static_cast(*this), desc.limits.maxNbAggregates) - OMNI_PVD_SET(scene, limitsMaxNbConstraints, static_cast(*this), desc.limits.maxNbConstraints) - OMNI_PVD_SET(scene, limitsMaxNbRegions, static_cast(*this), desc.limits.maxNbRegions) - OMNI_PVD_SET(scene, limitsMaxNbBroadPhaseOverlaps, static_cast(*this), desc.limits.maxNbBroadPhaseOverlaps) - - OMNI_PVD_SET(scene, hasCPUDispatcher, static_cast(*this), getCpuDispatcher() ? true : false) - OMNI_PVD_SET(scene, hasCUDAContextManager, static_cast(*this), getCudaContextManager() ? true : false) - OMNI_PVD_SET(scene, hasSimulationEventCallback, static_cast(*this), getSimulationEventCallback() ? true : false) - OMNI_PVD_SET(scene, hasContactModifyCallback, static_cast(*this), getContactModifyCallback() ? true : false) - OMNI_PVD_SET(scene, hasCCDContactModifyCallback, static_cast(*this), getCCDContactModifyCallback() ? true : false) - OMNI_PVD_SET(scene, hasBroadPhaseCallback, static_cast(*this), getBroadPhaseCallback() ? true : false) - OMNI_PVD_SET(scene, hasFilterCallback, static_cast(*this), getFilterCallback() ? true : false) + OMNI_PVD_SET(PxScene, limitsMaxNbActors, static_cast(*this), desc.limits.maxNbActors) + OMNI_PVD_SET(PxScene, limitsMaxNbBodies, static_cast(*this), desc.limits.maxNbBodies) + OMNI_PVD_SET(PxScene, limitsMaxNbStaticShapes, static_cast(*this), desc.limits.maxNbStaticShapes) + OMNI_PVD_SET(PxScene, limitsMaxNbDynamicShapes, static_cast(*this), desc.limits.maxNbDynamicShapes) + OMNI_PVD_SET(PxScene, limitsMaxNbAggregates, static_cast(*this), desc.limits.maxNbAggregates) + OMNI_PVD_SET(PxScene, limitsMaxNbConstraints, static_cast(*this), desc.limits.maxNbConstraints) + OMNI_PVD_SET(PxScene, limitsMaxNbRegions, static_cast(*this), desc.limits.maxNbRegions) + OMNI_PVD_SET(PxScene, limitsMaxNbBroadPhaseOverlaps, static_cast(*this), desc.limits.maxNbBroadPhaseOverlaps) + + OMNI_PVD_SET(PxScene, hasCPUDispatcher, static_cast(*this), getCpuDispatcher() ? true : false) + OMNI_PVD_SET(PxScene, hasCUDAContextManager, static_cast(*this), getCudaContextManager() ? true : false) + OMNI_PVD_SET(PxScene, hasSimulationEventCallback, static_cast(*this), getSimulationEventCallback() ? true : false) + OMNI_PVD_SET(PxScene, hasContactModifyCallback, static_cast(*this), getContactModifyCallback() ? true : false) + OMNI_PVD_SET(PxScene, hasCCDContactModifyCallback, static_cast(*this), getCCDContactModifyCallback() ? true : false) + OMNI_PVD_SET(PxScene, hasBroadPhaseCallback, static_cast(*this), getBroadPhaseCallback() ? true : false) + OMNI_PVD_SET(PxScene, hasFilterCallback, static_cast(*this), getFilterCallback() ? true : false) - //TODO: add these too, currently we don't have getter functions to retrieve them: - OMNI_PVD_SET(scene, sanityBounds, static_cast(*this), desc.sanityBounds) - OMNI_PVD_SET(scene, gpuDynamicsConfig, static_cast(*this), desc.gpuDynamicsConfig) - OMNI_PVD_SET(scene, gpuMaxNumPartitions, static_cast(*this), desc.gpuMaxNumPartitions) - OMNI_PVD_SET(scene, gpuMaxNumStaticPartitions, static_cast(*this), desc.gpuMaxNumStaticPartitions) - OMNI_PVD_SET(scene, gpuComputeVersion, static_cast(*this), desc.gpuComputeVersion) - OMNI_PVD_SET(scene, contactPairSlabSize, static_cast(*this), desc.contactPairSlabSize) - OMNI_PVD_SET(scene, tolerancesScale, static_cast(*this), desc.getTolerancesScale()) + OMNI_PVD_SET(PxScene, sanityBounds, static_cast(*this), desc.sanityBounds) + OMNI_PVD_SET(PxScene, gpuDynamicsConfig, static_cast(*this), desc.gpuDynamicsConfig) + OMNI_PVD_SET(PxScene, gpuMaxNumPartitions, static_cast(*this), desc.gpuMaxNumPartitions) + OMNI_PVD_SET(PxScene, gpuMaxNumStaticPartitions, static_cast(*this), desc.gpuMaxNumStaticPartitions) + OMNI_PVD_SET(PxScene, gpuComputeVersion, static_cast(*this), desc.gpuComputeVersion) + OMNI_PVD_SET(PxScene, contactPairSlabSize, static_cast(*this), desc.contactPairSlabSize) + OMNI_PVD_SET(PxScene, tolerancesScale, static_cast(*this), desc.getTolerancesScale()) } diff --git a/physx/source/physx/src/NpScene.h b/physx/source/physx/src/NpScene.h index e5871dc01..d6c699d3a 100644 --- a/physx/source/physx/src/NpScene.h +++ b/physx/source/physx/src/NpScene.h @@ -99,13 +99,11 @@ class NpHairSystem; class NpPBDParticleSystem; class NpFLIPParticleSystem; class NpMPMParticleSystem; -class NpCustomParticleSystem; class NpFEMSoftBodyMaterial; class NpFEMClothMaterial; class NpPBDMaterial; class NpFLIPMaterial; class NpMPMMaterial; -class NpCustomMaterial; #endif class NpContactCallbackTask : public physx::PxLightCpuTask @@ -138,6 +136,9 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated virtual void setFlag(PxSceneFlag::Enum flag, bool value); virtual PxSceneFlags getFlags() const; + virtual void setName(const char* name); + virtual const char* getName() const; + // implement PxScene: virtual void setGravity(const PxVec3&); @@ -309,12 +310,14 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated virtual void applyArticulationData(void* data, void* index, PxArticulationGpuDataType::Enum dataType, const PxU32 nbUpdatedArticulations, void* waitEvent, void* signalEvent); virtual void copyContactData(void* data, const PxU32 numContactPatches, void* numContactPairs, void* copyEvent); - virtual void copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent); - virtual void applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbUpdatedSoftBodies, const PxU32 maxSize, void* applyEvent); + virtual void copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyGpuDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent); + virtual void applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyGpuDataFlag::Enum flag, const PxU32 nbUpdatedSoftBodies, const PxU32 maxSize, void* applyEvent); virtual void copyBodyData(PxGpuBodyData* data, PxGpuActorPair* index, const PxU32 nbCopyActors, void* copyEvent); virtual void applyActorData(void* data, PxGpuActorPair* index, PxActorCacheFlag::Enum flag, const PxU32 nbUpdatedActors, void* waitEvent, void* signalEvent); + virtual void evaluateSDFDistances(const PxU32* sdfShapeIds, const PxU32 nbShapes, const PxVec4* samplePointsConcatenated, const PxU32* samplePointCountPerShape, const PxU32 maxPointCount, PxVec4* localGradientAndSDFConcatenated, void* event); + virtual void computeDenseJacobians(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent); virtual void computeGeneralizedMassMatrices(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent); virtual void computeGeneralizedGravityForces(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent); @@ -368,7 +371,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated virtual bool fetchQueries(bool block); //~PxSceneSQSystem - //internal public methods: public: NpScene(const PxSceneDesc& desc, NpPhysics&); ~NpScene(); @@ -416,10 +418,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated void addMaterial(const NpMPMMaterial& mat); void updateMaterial(const NpMPMMaterial& mat); void removeMaterial(const NpMPMMaterial& mat); - - void addMaterial(const NpCustomMaterial& mat); - void updateMaterial(const NpCustomMaterial& mat); - void removeMaterial(const NpCustomMaterial& mat); #endif void executeScene(PxBaseTask* continuation); @@ -439,7 +437,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated PX_FORCE_INLINE void removeFromParticleSystemList(PxPBDParticleSystem&); PX_FORCE_INLINE void removeFromParticleSystemList(PxFLIPParticleSystem&); PX_FORCE_INLINE void removeFromParticleSystemList(PxMPMParticleSystem&); - PX_FORCE_INLINE void removeFromParticleSystemList(PxCustomParticleSystem&); PX_FORCE_INLINE void removeFromHairSystemList(PxHairSystem&); PX_FORCE_INLINE void removeFromAggregateList(PxAggregate&); @@ -536,9 +533,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated void scAddParticleSystem(NpMPMParticleSystem&); void scRemoveParticleSystem(NpMPMParticleSystem&); - - void scAddParticleSystem(NpCustomParticleSystem&); - void scRemoveParticleSystem(NpCustomParticleSystem&); #endif void scAddHairSystem(NpHairSystem&); void scRemoveHairSystem(NpHairSystem&); @@ -598,7 +592,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated void updateDirtyShaders(); - void fireOutOfBoundsCallbacks(); void fetchResultsPreContactCallbacks(); void fetchResultsPostContactCallbacks(); void fetchResultsParticleSystem(); @@ -612,6 +605,8 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated void sceneQueriesStaticPrunerUpdate(PxBaseTask* continuation); void sceneQueriesDynamicPrunerUpdate(PxBaseTask* continuation); + void syncMaterialEvents(); + NpSceneQueries mNpSQ; PxPruningStructureType::Enum mPrunerType[2]; typedef Cm::DelegateTask SceneQueriesStaticPrunerUpdate; @@ -631,7 +626,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated PxCoalescedHashSet mPBDParticleSystems; PxCoalescedHashSet mFLIPParticleSystems; PxCoalescedHashSet mMPMParticleSystems; - PxCoalescedHashSet mCustomParticleSystems; PxCoalescedHashSet mHairSystems; PxCoalescedHashSet mAggregates; @@ -718,7 +712,6 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated bool mSQUpdateRunning; - bool mHasSimulatedOnce; bool mBetweenFetchResults; bool mBuildFrozenActors; @@ -747,23 +740,22 @@ class NpScene : public NpSceneAccessor, public PxUserAllocated PxArray mScenePBDMaterialBuffer; PxArray mSceneFLIPMaterialBuffer; PxArray mSceneMPMMaterialBuffer; - PxArray mSceneCustomMaterialBuffer; PxMutex mSceneMaterialBufferLock; PxMutex mSceneFEMSoftBodyMaterialBufferLock; PxMutex mSceneFEMClothMaterialBufferLock; PxMutex mScenePBDMaterialBufferLock; PxMutex mSceneFLIPMaterialBufferLock; PxMutex mSceneMPMMaterialBufferLock; - PxMutex mSceneCustomMaterialBufferLock; Sc::Scene mScene; #if PX_SUPPORT_PVD Vd::PvdSceneClient mScenePvdClient; #endif - PxReal mWakeCounterResetValue; + const PxReal mWakeCounterResetValue; PxgDynamicsMemoryConfig mGpuDynamicsConfig; NpPhysics& mPhysics; + const char* mName; }; template<> @@ -820,13 +812,6 @@ PX_FORCE_INLINE void NpScene::removeFromParticleSystemList(PxMPMParticleSystem& PX_ASSERT(exists); PX_UNUSED(exists); } - -PX_FORCE_INLINE void NpScene::removeFromParticleSystemList(PxCustomParticleSystem& particleSystem) -{ - const bool exists = mCustomParticleSystems.erase(&particleSystem); - PX_ASSERT(exists); - PX_UNUSED(exists); -} #endif PX_FORCE_INLINE void NpScene::removeFromHairSystemList(PxHairSystem& hairSystem) diff --git a/physx/source/physx/src/NpSceneFetchResults.cpp b/physx/source/physx/src/NpSceneFetchResults.cpp index 0ba46c58c..5ace0c4b5 100644 --- a/physx/source/physx/src/NpSceneFetchResults.cpp +++ b/physx/source/physx/src/NpSceneFetchResults.cpp @@ -91,44 +91,6 @@ void NpScene::fetchResultsParticleSystem() mScene.getSimulationController()->syncParticleData(); } -void NpScene::fireOutOfBoundsCallbacks() -{ - PX_PROFILE_ZONE("Sim.fireOutOfBoundsCallbacks", getContextId()); - - // Fire broad-phase callbacks - { - Sc::Scene& scene = mScene; - using namespace physx::Sc; - - bool outputWarning = scene.fireOutOfBoundsCallbacks(); - - // Aggregates - { - Bp::AABBManagerBase* aabbManager = scene.getAABBManager(); - - PxU32 nbOut1; - void** outAgg = aabbManager->getOutOfBoundsAggregates(nbOut1); - if(nbOut1) - { - PxBroadPhaseCallback* cb = scene.getBroadPhaseCallback(); - - for(PxU32 i=0;i(outAgg[i]); - if(cb) - cb->onObjectOutOfBounds(*px); - else - outputWarning = true; - } - aabbManager->clearOutOfBoundsAggregates(); - } - } - - if(outputWarning) - outputError(__LINE__, "At least one object is out of the broadphase bounds. To manage those objects, define a PxBroadPhaseCallback for each used client."); - } -} - // The order of the following operations is important! // 1. Mark the simulation as not running internally to allow reading data which should not be read otherwise // 2. Fire callbacks with latest state. @@ -139,14 +101,17 @@ void NpScene::fetchResultsPreContactCallbacks() mScenePvdClient.updateContacts(); #endif - mScene.prepareOutOfBoundsCallbacks(); mScene.endSimulation(); setAPIReadToAllowed(); { PX_PROFILE_ZONE("Sim.fireCallbacksPreSync", getContextId()); - fireOutOfBoundsCallbacks(); // fire out-of-bounds callbacks + { + PX_PROFILE_ZONE("Sim.fireOutOfBoundsCallbacks", getContextId()); + if(mScene.fireOutOfBoundsCallbacks()) + outputError(__LINE__, "At least one object is out of the broadphase bounds. To manage those objects, define a PxBroadPhaseCallback for each used client."); + } mScene.fireBrokenConstraintCallbacks(); mScene.fireTriggerCallbacks(); } @@ -221,9 +186,9 @@ bool NpScene::fetchResults(bool block, PxU32* errorState) } #endif - { - PX_SIMD_GUARD; + PX_SIMD_GUARD; + { // take write check *after* simulation has finished, otherwise // we will block simulation callbacks from using the API // disallow re-entry to detect callbacks making write calls @@ -265,21 +230,22 @@ bool NpScene::fetchResults(bool block, PxU32* errorState) { PxRigidActor* ra = static_cast(a); PxTransform t = ra->getGlobalPose(); - OMNI_PVD_SET(actor, translation, *a, t.p) - OMNI_PVD_SET(actor, rotation, *a, t.q) + OMNI_PVD_SET(PxRigidActor, translation, *ra, t.p) + OMNI_PVD_SET(PxRigidActor, rotation, *ra, t.q) if (a->getType() == PxActorType::eRIGID_DYNAMIC) { PxRigidDynamic* rdyn = static_cast(a); + PxRigidBody& rb = *static_cast(a); const PxVec3 linVel = rdyn->getLinearVelocity(); - OMNI_PVD_SET(actor, linearVelocity, *a, linVel) + OMNI_PVD_SET(PxRigidBody, linearVelocity, rb, linVel) const PxVec3 angVel = rdyn->getAngularVelocity(); - OMNI_PVD_SET(actor, angularVelocity, *a, angVel) + OMNI_PVD_SET(PxRigidBody, angularVelocity, rb, angVel) const PxRigidBodyFlags rFlags = rdyn->getRigidBodyFlags(); - OMNI_PVD_SET(actor, rigidBodyFlags, *a, rFlags) + OMNI_PVD_SET(PxRigidBody, rigidBodyFlags, rb, rFlags) } } @@ -292,14 +258,14 @@ bool NpScene::fetchResults(bool block, PxU32* errorState) { pxArticulationParentLink = &(pxArticulationJoint->getParentArticulationLink()); - PxArticulationJointReducedCoordinate & jcord = *pxArticulationJoint; + PxArticulationJointReducedCoordinate& jcord = *pxArticulationJoint; PxReal vals[6]; for (PxU32 ax = 0; ax < 6; ++ax) vals[ax] = jcord.getJointPosition(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, jointPosition, jcord, vals, sizeof(vals)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, jointPosition, jcord, vals, sizeof(vals)); for (PxU32 ax = 0; ax < 6; ++ax) vals[ax] = jcord.getJointVelocity(static_cast(ax)); - OMNI_PVD_SETB(articulationjoint, jointVelocity, jcord, vals, sizeof(vals)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, jointVelocity, jcord, vals, sizeof(vals)); } physx::PxTransform TArtLinkLocal; @@ -312,27 +278,28 @@ bool NpScene::fetchResults(bool block, PxU32* errorState) //physx::PxTransform TParentGlobal = pxArticulationParentLink->getGlobalPose(); physx::PxTransform TParentGlobalInv = pxArticulationParentLink->getGlobalPose().getInverse(); physx::PxTransform TArtLinkGlobal = pxArticulationLink->getGlobalPose(); + // PT:: tag: scalar transform*transform TArtLinkLocal = TParentGlobalInv * TArtLinkGlobal; } else { TArtLinkLocal = pxArticulationLink->getGlobalPose(); - OMNI_PVD_SET(articulation, worldBounds, pxArticulationLink->getArticulation(), pxArticulationLink->getArticulation().getWorldBounds()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, worldBounds, pxArticulationLink->getArticulation(), pxArticulationLink->getArticulation().getWorldBounds()); } - OMNI_PVD_SET(actor, translation, *a, TArtLinkLocal.p) - OMNI_PVD_SET(actor, rotation, *a, TArtLinkLocal.q) + OMNI_PVD_SET(PxRigidActor, translation, static_cast(*a), TArtLinkLocal.p) + OMNI_PVD_SET(PxRigidActor, rotation, static_cast(*a), TArtLinkLocal.q) const PxVec3 linVel = pxArticulationLink->getLinearVelocity(); - OMNI_PVD_SET(actor, linearVelocity, *a, linVel) + OMNI_PVD_SET(PxRigidBody, linearVelocity, static_cast(*a), linVel) const PxVec3 angVel = pxArticulationLink->getAngularVelocity(); - OMNI_PVD_SET(actor, angularVelocity, *a, angVel) + OMNI_PVD_SET(PxRigidBody, angularVelocity, static_cast(*a), angVel) const PxRigidBodyFlags rFlags = pxArticulationLink->getRigidBodyFlags(); - OMNI_PVD_SET(actor, rigidBodyFlags, *a, rFlags) + OMNI_PVD_SET(PxRigidBody, rigidBodyFlags, static_cast(*a), rFlags) } const PxBounds3 worldBounds = a->getWorldBounds(); - OMNI_PVD_SET(actor, worldBounds, *a, worldBounds) + OMNI_PVD_SET(PxActor, worldBounds, *a, worldBounds) // update active actors' joints const PxRigidActor* ra = a->is(); @@ -373,10 +340,7 @@ bool NpScene::fetchResults(bool block, PxU32* errorState) } #if PX_SUPPORT_PVD - { - PX_SIMD_GUARD; - mScenePvdClient.frameEnd(); - } + mScenePvdClient.frameEnd(); #endif return true; } diff --git a/physx/source/physx/src/NpShape.cpp b/physx/source/physx/src/NpShape.cpp index a6c6a24a0..40b4a1141 100644 --- a/physx/source/physx/src/NpShape.cpp +++ b/physx/source/physx/src/NpShape.cpp @@ -65,11 +65,12 @@ static PX_FORCE_INLINE void decreaseActorCount(PxU32* count) NpShape::NpShape(const PxGeometry& geometry, PxShapeFlags shapeFlags, const PxU16* materialIndices, PxU16 materialCount, bool isExclusive, PxShapeCoreFlag::Enum flag) : PxShape (PxConcreteType::eSHAPE, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), - NpBase (NpType::eSHAPE), - mActor (NULL), - mCore (geometry, shapeFlags, materialIndices, materialCount, isExclusive, flag) + NpBase (NpType::eSHAPE), + mExclusiveShapeActor (NULL), + mCore (geometry, shapeFlags, materialIndices, materialCount, isExclusive, flag) { - mFreeSlot = isExclusive ? EXCLUSIVE_MASK : 0; + //actor count + mFreeSlot = 0; PX_ASSERT(mCore.getPxShape() == static_cast(this)); PX_ASSERT(!PxShape::userData); @@ -88,15 +89,17 @@ NpShape::~NpShape() if (flags & PxShapeCoreFlag::eCLOTH_SHAPE) { -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX for (PxU32 i = 0; i < nbMaterials; i++) RefCountable_decRefCount(*scGetMaterial(i)); #endif } else if(flags & PxShapeCoreFlag::eSOFT_BODY_SHAPE) { +#if PX_SUPPORT_GPU_PHYSX for (PxU32 i = 0; i < nbMaterials; i++) RefCountable_decRefCount(*scGetMaterial(i)); +#endif } else { @@ -121,7 +124,8 @@ NpShape::NpShape(PxBaseFlags baseFlags) : PxShape(baseFlags), NpBase(PxEmpty), m void NpShape::preExportDataReset() { RefCountable_preExportDataReset(*this); - mFreeSlot &= EXCLUSIVE_MASK; + mExclusiveShapeActor = NULL; + mFreeSlot = 0; } void NpShape::exportExtraData(PxSerializationContext& context) @@ -180,7 +184,8 @@ void NpShape::resolveReferences(PxDeserializationContext& context) } } - context.translatePxBase(mActor); + //we don't resolve mExclusiveShapeActor because it's set to NULL on export. + //it's recovered when the actors resolveReferences attaches to the shape mCore.resolveReferences(context); @@ -227,14 +232,14 @@ void NpShape::releaseInternal() Sc::RigidCore& NpShape::getScRigidObjectExclusive() const { - const PxType actorType = mActor->getConcreteType(); + const PxType actorType = mExclusiveShapeActor->getConcreteType(); if (actorType == PxConcreteType::eRIGID_DYNAMIC) - return static_cast(*mActor).getCore(); + return static_cast(*mExclusiveShapeActor).getCore(); else if (actorType == PxConcreteType::eARTICULATION_LINK) - return static_cast(*mActor).getCore(); + return static_cast(*mExclusiveShapeActor).getCore(); else - return static_cast(*mActor).getCore(); + return static_cast(*mExclusiveShapeActor).getCore(); } void NpShape::updateSQ(const char* errorMessage) @@ -251,7 +256,7 @@ void NpShape::updateSQ(const char* errorMessage) if(shapeManager->getPruningStructure()) { outputError(__LINE__, errorMessage); - shapeManager->getPruningStructure()->invalidate(mActor); + shapeManager->getPruningStructure()->invalidate(mExclusiveShapeActor); } } } @@ -325,7 +330,7 @@ const PxGeometry& NpShape::getGeometry() const PxRigidActor* NpShape::getActor() const { NP_READ_CHECK(getNpScene()); - return mActor ? mActor->is() : NULL; + return mExclusiveShapeActor ? mExclusiveShapeActor->is() : NULL; } void NpShape::setLocalPose(const PxTransform& newShape2Actor) @@ -342,8 +347,8 @@ void NpShape::setLocalPose(const PxTransform& newShape2Actor) notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlag::eSHAPE2BODY); - OMNI_PVD_SET(shape, translation, static_cast(*this), normalizedTransform.p) - OMNI_PVD_SET(shape, rotation, static_cast(*this), normalizedTransform.q) + OMNI_PVD_SET(PxShape, translation, static_cast(*this), normalizedTransform.p) + OMNI_PVD_SET(PxShape, rotation, static_cast(*this), normalizedTransform.q) updateSQ("PxShape::setLocalPose: Shape is a part of pruning structure, pruning structure is now invalid!"); } @@ -367,7 +372,7 @@ void NpShape::setSimulationFilterData(const PxFilterData& data) notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlag::eFILTERDATA); - OMNI_PVD_SET(shape, simulationFilterData, static_cast(*this), data); + OMNI_PVD_SET(PxShape, simulationFilterData, static_cast(*this), data); } PxFilterData NpShape::getSimulationFilterData() const @@ -384,7 +389,7 @@ void NpShape::setQueryFilterData(const PxFilterData& data) PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxShape::setQueryFilterData() not allowed while simulation is running. Call will be ignored.") - OMNI_PVD_SET(shape, queryFilterData, static_cast(*this), data); + OMNI_PVD_SET(PxShape, queryFilterData, static_cast(*this), data); mQueryFilterData = data; UPDATE_PVD_PROPERTY @@ -425,7 +430,7 @@ void NpShape::setMaterialsInternal(PxMaterialType* const * materials, PxU16 mate #endif #if PX_SUPPORT_OMNI_PVD - streamShapeMaterials((physx::PxShape*)this, (physx::PxMaterial**)materials, materialCount); + streamShapeMaterials(static_cast(this), materials, materialCount); #endif if (ret) @@ -444,15 +449,16 @@ void NpShape::setMaterials(PxMaterial*const* materials, PxU16 materialCount) PX_CHECK_AND_RETURN(!(mCore.getCore().mShapeCoreFlags & PxShapeCoreFlag::eCLOTH_SHAPE), "NpShape::setMaterials: cannot set rigid body materials to a cloth shape!"); setMaterialsInternal(materials, materialCount); } + void NpShape::setSoftBodyMaterials(PxFEMSoftBodyMaterial*const* materials, PxU16 materialCount) { #if PX_SUPPORT_GPU_PHYSX PX_CHECK_AND_RETURN((mCore.getCore().mShapeCoreFlags & PxShapeCoreFlag::eSOFT_BODY_SHAPE), "NpShape::setMaterials: can only apply soft body materials to a soft body shape!"); setMaterialsInternal(materials, materialCount); - if (this->mActor) + if (this->mExclusiveShapeActor) { - static_cast(mActor)->updateMaterials(); + static_cast(mExclusiveShapeActor)->updateMaterials(); } #else PX_UNUSED(materials); @@ -463,7 +469,6 @@ void NpShape::setSoftBodyMaterials(PxFEMSoftBodyMaterial*const* materials, PxU16 void NpShape::setClothMaterials(PxFEMClothMaterial*const* materials, PxU16 materialCount) { #if PX_SUPPORT_GPU_PHYSX && PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PX_CHECK_AND_RETURN((mCore.getCore().mShapeCoreFlags & PxShapeCoreFlag::eCLOTH_SHAPE), "NpShape::setMaterials: can only apply cloth materials to a cloth shape!"); setMaterialsInternal(materials, materialCount); @@ -485,13 +490,20 @@ PxU32 NpShape::getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 sta return scGetMaterials(userBuffer, bufferSize, startIndex); } +#if PX_SUPPORT_GPU_PHYSX PxU32 NpShape::getSoftBodyMaterials(PxFEMSoftBodyMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { NP_READ_CHECK(getNpScene()); return scGetMaterials(userBuffer, bufferSize, startIndex); } +#else +PxU32 NpShape::getSoftBodyMaterials(PxFEMSoftBodyMaterial**, PxU32, PxU32) const +{ + return 0; +} +#endif -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION && PX_SUPPORT_GPU_PHYSX PxU32 NpShape::getClothMaterials(PxFEMClothMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex) const { NP_READ_CHECK(getNpScene()); @@ -508,14 +520,15 @@ PxBaseMaterial* NpShape::getMaterialFromInternalFaceIndex(PxU32 faceIndex) const { NP_READ_CHECK(getNpScene()); - bool isHf = (getGeometryType() == PxGeometryType::eHEIGHTFIELD); - bool isMesh = (getGeometryType() == PxGeometryType::eTRIANGLEMESH); + const PxGeometry& geom = mCore.getGeometry(); + const PxGeometryType::Enum geomType = geom.getType(); + bool isHf = (geomType == PxGeometryType::eHEIGHTFIELD); + bool isMesh = (geomType == PxGeometryType::eTRIANGLEMESH); // if SDF tri-mesh, where no multi-material setup is allowed, return zero-index material if (isMesh) { - PxTriangleMeshGeometry triGeo; - getTriangleMeshGeometry(triGeo); + const PxTriangleMeshGeometry& triGeo = static_cast(geom); if (triGeo.triangleMesh->getSDF()) { return getMaterial(0); @@ -532,15 +545,13 @@ PxBaseMaterial* NpShape::getMaterialFromInternalFaceIndex(PxU32 faceIndex) const if(isHf) { - PxHeightFieldGeometry hfGeom; - getHeightFieldGeometry(hfGeom); + const PxHeightFieldGeometry& hfGeom = static_cast(geom); hitMatTableId = hfGeom.heightField->getTriangleMaterialIndex(faceIndex); } else if(isMesh) { - PxTriangleMeshGeometry triGeo; - getTriangleMeshGeometry(triGeo); + const PxTriangleMeshGeometry& triGeo = static_cast(geom); Gu::TriangleMesh* tm = static_cast(triGeo.triangleMesh); if(tm->hasPerTriangleMaterials()) @@ -565,7 +576,7 @@ void NpShape::setContactOffset(PxReal contactOffset) notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlag::eCONTACTOFFSET); - OMNI_PVD_SET(shape, contactOffset, static_cast(*this), contactOffset) + OMNI_PVD_SET(PxShape, contactOffset, static_cast(*this), contactOffset) } PxReal NpShape::getContactOffset() const @@ -588,7 +599,7 @@ void NpShape::setRestOffset(PxReal restOffset) notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlag::eRESTOFFSET); - OMNI_PVD_SET(shape, restOffset, static_cast(*this), restOffset) + OMNI_PVD_SET(PxShape, restOffset, static_cast(*this), restOffset) } PxReal NpShape::getRestOffset() const @@ -610,7 +621,7 @@ void NpShape::setDensityForFluid(PxReal densityForFluid) ///notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlag::eRESTOFFSET); - OMNI_PVD_SET(shape, densityForFluid, static_cast(*this), densityForFluid); + OMNI_PVD_SET(PxShape, densityForFluid, static_cast(*this), densityForFluid); } PxReal NpShape::getDensityForFluid() const @@ -631,7 +642,7 @@ void NpShape::setTorsionalPatchRadius(PxReal radius) // const PxShapeFlags oldShapeFlags = mShape.getFlags(); mCore.setTorsionalPatchRadius(radius); - OMNI_PVD_SET(shape, torsionalPatchRadius, static_cast(*this), radius); + OMNI_PVD_SET(PxShape, torsionalPatchRadius, static_cast(*this), radius); // shared shapes return NULL. But shared shapes aren't mutable when attached to an actor, so no notification needed. // Sc::RigidCore* rigidCore = NpShapeGetScRigidObjectFromScSLOW(); @@ -659,7 +670,7 @@ void NpShape::setMinTorsionalPatchRadius(PxReal radius) // const PxShapeFlags oldShapeFlags = mShape.getFlags(); mCore.setMinTorsionalPatchRadius(radius); - OMNI_PVD_SET(shape, minTorsionalPatchRadius, static_cast(*this), radius); + OMNI_PVD_SET(PxShape, minTorsionalPatchRadius, static_cast(*this), radius); // Sc::RigidCore* rigidCore = NpShapeGetScRigidObjectFromSbSLOW(); // if(rigidCore) @@ -670,10 +681,22 @@ void NpShape::setMinTorsionalPatchRadius(PxReal radius) PxReal NpShape::getMinTorsionalPatchRadius() const { - NP_READ_CHECK(getNpScene()); + NP_READ_CHECK(getNpScene()); return mCore.getMinTorsionalPatchRadius(); } +PxU32 NpShape::getInternalShapeIndex() const +{ + NP_READ_CHECK(getNpScene()); + if (getNpScene()) + { + PxsSimulationController* simulationController = getNpScene()->getSimulationController(); + if (simulationController) + return mCore.getInternalShapeIndex(*simulationController); + } + return PX_INVALID_NODE; +} + void NpShape::setFlagsInternal(PxShapeFlags inFlags) { const bool hasMeshTypeGeom = mCore.getGeometryType() == PxGeometryType::eTRIANGLEMESH || mCore.getGeometryType() == PxGeometryType::eHEIGHTFIELD; @@ -695,15 +718,15 @@ void NpShape::setFlagsInternal(PxShapeFlags inFlags) const bool oldIsSimShape = oldFlags & PxShapeFlag::eSIMULATION_SHAPE; const bool isSimShape = inFlags & PxShapeFlag::eSIMULATION_SHAPE; - if(mActor) + if(mExclusiveShapeActor) { - const PxType type = mActor->getConcreteType(); + const PxType type = mExclusiveShapeActor->getConcreteType(); // PT: US5732 - support kinematic meshes bool isKinematic = false; if(type==PxConcreteType::eRIGID_DYNAMIC) { - PxRigidDynamic* rigidDynamic = static_cast(mActor); + PxRigidDynamic* rigidDynamic = static_cast(mExclusiveShapeActor); isKinematic = rigidDynamic->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC; } @@ -747,7 +770,7 @@ void NpShape::setFlagsInternal(PxShapeFlags inFlags) if(shapeManager->getPruningStructure()) { outputError(__LINE__, "PxShape::setFlag: Shape is a part of pruning structure, pruning structure is now invalid!"); - shapeManager->getPruningStructure()->invalidate(mActor); + shapeManager->getPruningStructure()->invalidate(mExclusiveShapeActor); } } } @@ -767,7 +790,7 @@ void NpShape::setFlag(PxShapeFlag::Enum flag, bool value) setFlagsInternal(shapeFlags); - OMNI_PVD_SET(shape, shapeFlags, static_cast(*this), shapeFlags); + OMNI_PVD_SET(PxShape, shapeFlags, static_cast(*this), shapeFlags); } void NpShape::setFlags(PxShapeFlags inFlags) @@ -782,7 +805,7 @@ void NpShape::setFlags(PxShapeFlags inFlags) setFlagsInternal(inFlags); - OMNI_PVD_SET(shape, shapeFlags, static_cast(*this), inFlags); + OMNI_PVD_SET(PxShape, shapeFlags, static_cast(*this), inFlags); } PxShapeFlags NpShape::getFlags() const @@ -801,7 +824,7 @@ void NpShape::onActorAttach(PxActor& actor) { RefCountable_incRefCount(*this); if(isExclusiveFast()) - mActor = &actor; + mExclusiveShapeActor = &actor; increaseActorCount(&mFreeSlot); } @@ -810,7 +833,7 @@ void NpShape::onActorDetach() PX_ASSERT(getActorCount() > 0); decreaseActorCount(&mFreeSlot); if(isExclusiveFast()) - mActor = NULL; + mExclusiveShapeActor = NULL; RefCountable_decRefCount(*this); } @@ -919,20 +942,20 @@ bool NpShape::setMaterialsHelper(PxMaterialType* const* materials, PxU16 materia void NpShape::notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlags notifyFlags) { // shared shapes return NULL. But shared shapes aren't mutable when attached to an actor, so no notification needed. - if(mActor) + if(mExclusiveShapeActor) { Sc::RigidCore* rigidCore = getScRigidObjectSLOW(); if(rigidCore) rigidCore->onShapeChange(mCore, notifyFlags); #if PX_SUPPORT_GPU_PHYSX - const PxType type = mActor->getConcreteType(); + const PxType type = mExclusiveShapeActor->getConcreteType(); #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION if(type==PxConcreteType::eFEM_CLOTH) - static_cast(mActor)->getCore().onShapeChange(mCore, notifyFlags); + static_cast(mExclusiveShapeActor)->getCore().onShapeChange(mCore, notifyFlags); #endif if(type==PxConcreteType::eSOFT_BODY) - static_cast(mActor)->getCore().onShapeChange(mCore, notifyFlags); + static_cast(mExclusiveShapeActor)->getCore().onShapeChange(mCore, notifyFlags); #endif } diff --git a/physx/source/physx/src/NpShape.h b/physx/source/physx/src/NpShape.h index 28bf9ef1b..93a9d79f5 100644 --- a/physx/source/physx/src/NpShape.h +++ b/physx/source/physx/src/NpShape.h @@ -42,12 +42,6 @@ class NpScene; class NpShape : public PxShape, public NpBase { -//= 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. -//================================================================================================== public: // PX_SERIALIZATION NpShape(PxBaseFlags baseFlags); @@ -102,6 +96,7 @@ class NpShape : public PxShape, public NpBase virtual PxReal getTorsionalPatchRadius() const PX_OVERRIDE; virtual void setMinTorsionalPatchRadius(PxReal) PX_OVERRIDE; virtual PxReal getMinTorsionalPatchRadius() const PX_OVERRIDE; + virtual PxU32 getInternalShapeIndex() const PX_OVERRIDE; virtual void setFlag(PxShapeFlag::Enum flag, bool value) PX_OVERRIDE; virtual void setFlags(PxShapeFlags inFlags) PX_OVERRIDE; virtual PxShapeFlags getFlags() const PX_OVERRIDE; @@ -125,7 +120,7 @@ class NpShape : public PxShape, public NpBase PX_FORCE_INLINE PxGeometryType::Enum getGeometryTypeFast() const { return mCore.getGeometryType(); } PX_FORCE_INLINE const PxFilterData& getQueryFilterDataFast() const { return mQueryFilterData; } - PX_FORCE_INLINE PxU32 getActorCount() const { return mFreeSlot & ACTOR_COUNT_MASK; } + PX_FORCE_INLINE PxU32 getActorCount() const { return mFreeSlot; } PX_FORCE_INLINE bool isExclusiveFast() const { return mCore.getCore().mShapeCoreFlags.isSet(PxShapeCoreFlag::eIS_EXCLUSIVE); } PX_FORCE_INLINE const Sc::ShapeCore& getCore() const { return mCore; } @@ -144,9 +139,11 @@ class NpShape : public PxShape, public NpBase } void releaseInternal(); // PT: it's "internal" but called by the NpFactory - template - static PX_INLINE bool checkMaterialSetup(const PxGeometry& geom, const char* errorMsgPrefix, PxMaterialType*const* materials, PxU16 materialCount); +#if PX_CHECKED + template + static bool checkMaterialSetup(const PxGeometry& geom, const char* errorMsgPrefix, PxMaterialType*const* materials, PxU16 materialCount); +#endif void onActorAttach(PxActor& actor); void onActorDetach(); @@ -181,14 +178,11 @@ class NpShape : public PxShape, public NpBase setBaseIndex(NP_UNUSED_BASE_INDEX); } - PX_FORCE_INLINE PxRigidActor* getRigidActor() const { return mActor->is(); } private: - PxActor* mActor; + PxActor* mExclusiveShapeActor; Sc::ShapeCore mCore; PxFilterData mQueryFilterData; // Query filter data PT: TODO: consider moving this to SQ structures - static const PxI32 EXCLUSIVE_MASK = 0x80000000; - static const PxI32 ACTOR_COUNT_MASK = 0x7fffffff; private: void notifyActorAndUpdatePVD(Sc::ShapeChangeNotifyFlags notifyFlags); void notifyActorAndUpdatePVD(const PxShapeFlags oldShapeFlags); // PT: for shape flags change @@ -247,99 +241,114 @@ class NpShape : public PxShape, public NpBase template void setMaterialsInternal(PxMaterialType* const * materials, PxU16 materialCount); }; +#if PX_CHECKED template -PX_INLINE bool NpShape::checkMaterialSetup(const PxGeometry& geom, const char* errorMsgPrefix, PxMaterialType*const* materials, PxU16 materialCount) +bool NpShape::checkMaterialSetup(const PxGeometry& geom, const char* errorMsgPrefix, PxMaterialType*const* materials, PxU16 materialCount) { - for (PxU32 i = 0; i < materialCount; ++i) + for(PxU32 i=0; i 1 && (geom.getType() != PxGeometryType::eHEIGHTFIELD) && (geom.getType() != PxGeometryType::eTRIANGLEMESH) && (geom.getType() != PxGeometryType::eTETRAHEDRONMESH)) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, - "%s: multiple materials defined for single material geometry!", errorMsgPrefix); - return false; - } - - // verify we provide all materials required - if (materialCount > 1 && (geom.getType() == PxGeometryType::eTRIANGLEMESH)) + if(materialCount > 1) { - const PxTriangleMeshGeometry& meshGeom = static_cast(geom); - const PxTriangleMesh& mesh = *meshGeom.triangleMesh; + const PxGeometryType::Enum type = geom.getType(); - // do not allow SDF multi-material tri-meshes: - if (mesh.getSDF()) + // verify we provide all materials required + if(type == PxGeometryType::eTRIANGLEMESH) { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, - "%s: multiple materials defined for an SDF triangle-mesh geometry!", errorMsgPrefix); - return false; - } + const PxTriangleMeshGeometry& meshGeom = static_cast(geom); + const PxTriangleMesh& mesh = *meshGeom.triangleMesh; - if (mesh.getTriangleMaterialIndex(0) != 0xffff) - { - for (PxU32 i = 0; i < mesh.getNbTriangles(); i++) + // do not allow SDF multi-material tri-meshes: + if(mesh.getSDF()) { - const PxMaterialTableIndex meshMaterialIndex = mesh.getTriangleMaterialIndex(i); - if (meshMaterialIndex >= materialCount) + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: multiple materials defined for an SDF triangle-mesh geometry!", errorMsgPrefix); + return false; + } + + const Gu::TriangleMesh& tmesh = static_cast(mesh); + if(tmesh.hasPerTriangleMaterials()) + { + const PxU32 nbTris = tmesh.getNbTrianglesFast(); + for(PxU32 i=0; i= materialCount) + { + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: PxTriangleMesh material indices reference more materials than provided!", errorMsgPrefix); + break; + } } } + else + { + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: multiple materials defined for a triangle-mesh that does not have per-triangle materials!", errorMsgPrefix); + } } - } - - if (materialCount > 1 && (geom.getType() == PxGeometryType::eTETRAHEDRONMESH)) - { - const PxTetrahedronMeshGeometry& meshGeom = static_cast(geom); - const PxTetrahedronMesh& mesh = *meshGeom.tetrahedronMesh; - PX_UNUSED(mesh); - //Need to fill in material - /*if (mesh.getTriangleMaterialIndex(0) != 0xffff) + else if(type == PxGeometryType::eTETRAHEDRONMESH) { - for (PxU32 i = 0; i < mesh.getNbTriangles(); i++) + const PxTetrahedronMeshGeometry& meshGeom = static_cast(geom); + const PxTetrahedronMesh& mesh = *meshGeom.tetrahedronMesh; + PX_UNUSED(mesh); + //Need to fill in material + /*if (mesh.getTriangleMaterialIndex(0) != 0xffff) { - const PxMaterialTableIndex meshMaterialIndex = mesh.getTriangleMaterialIndex(i); - if (meshMaterialIndex >= materialCount) + for (PxU32 i = 0; i < mesh.getNbTriangles(); i++) { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, - "%s: PxTriangleMesh material indices reference more materials than provided!", errorMsgPrefix); - break; + const PxMaterialTableIndex meshMaterialIndex = mesh.getTriangleMaterialIndex(i); + if (meshMaterialIndex >= materialCount) + { + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: PxTriangleMesh material indices reference more materials than provided!", errorMsgPrefix); + break; + } } - } - }*/ - } - - if (materialCount > 1 && (geom.getType() == PxGeometryType::eHEIGHTFIELD)) - { - const PxHeightFieldGeometry& meshGeom = static_cast(geom); - const PxHeightField& mesh = *meshGeom.heightField; - if (mesh.getTriangleMaterialIndex(0) != 0xffff) + }*/ + } + else if(type == PxGeometryType::eHEIGHTFIELD) { - const PxU32 nbTris = mesh.getNbColumns()*mesh.getNbRows() * 2; - for (PxU32 i = 0; i < nbTris; i++) + const PxHeightFieldGeometry& meshGeom = static_cast(geom); + const PxHeightField& mesh = *meshGeom.heightField; + if (mesh.getTriangleMaterialIndex(0) != 0xffff) { - const PxMaterialTableIndex meshMaterialIndex = mesh.getTriangleMaterialIndex(i); - if (meshMaterialIndex != PxHeightFieldMaterial::eHOLE && meshMaterialIndex >= materialCount) + const PxU32 nbTris = mesh.getNbColumns()*mesh.getNbRows() * 2; + for (PxU32 i = 0; i < nbTris; i++) { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, - "%s: PxHeightField material indices reference more materials than provided!", errorMsgPrefix); - break; + const PxMaterialTableIndex meshMaterialIndex = mesh.getTriangleMaterialIndex(i); + if (meshMaterialIndex != PxHeightFieldMaterial::eHOLE && meshMaterialIndex >= materialCount) + { + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: PxHeightField material indices reference more materials than provided!", errorMsgPrefix); + break; + } } } + else + { + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: multiple materials defined for a heightfield that does not have per-triangle materials!", errorMsgPrefix); + } + } + else + { + // check that simple shapes don't get assigned multiple materials + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, PX_FL, + "%s: multiple materials defined for single material geometry!", errorMsgPrefix); + return false; } } - return true; } +#endif } diff --git a/physx/source/physx/src/NpShapeManager.cpp b/physx/source/physx/src/NpShapeManager.cpp index 7445ae9bb..1da4a6b0a 100644 --- a/physx/source/physx/src/NpShapeManager.cpp +++ b/physx/source/physx/src/NpShapeManager.cpp @@ -35,6 +35,7 @@ #include "NpAggregate.h" #include "CmTransformUtils.h" #include "NpRigidStatic.h" +#include "foundation/PxSIMDHelpers.h" using namespace physx; using namespace Sq; @@ -285,12 +286,18 @@ PxBounds3 NpShapeManager::getWorldBounds_(const PxRigidActor& actor) const PxBounds3 bounds(PxBounds3::empty()); const PxU32 nbShapes = getNbShapes(); - const PxTransform actorPose = actor.getGlobalPose(); NpShape*const* PX_RESTRICT shapes = getShapes(); + const PxTransform32 actorPose(actor.getGlobalPose()); + for(PxU32 i=0;igetCore().getGeometry(), actorPose * shapes[i]->getLocalPoseFast())); - + { + PxTransform32 shapeAbsPose; + aos::transformMultiply(shapeAbsPose, actorPose, shapes[i]->getLocalPoseFast()); + + bounds.include(computeBounds(shapes[i]->getCore().getGeometry(), shapeAbsPose)); + } + return bounds; } diff --git a/physx/source/physx/src/NpShapeManager.h b/physx/source/physx/src/NpShapeManager.h index 08cd39c3d..bc85896e9 100644 --- a/physx/source/physx/src/NpShapeManager.h +++ b/physx/source/physx/src/NpShapeManager.h @@ -59,12 +59,6 @@ class NpScene; class NpShapeManager : 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. -//================================================================================================== public: // PX_SERIALIZATION static void getBinaryMetaData(PxOutputStream& stream); diff --git a/physx/source/physx/src/NpSoftBody.cpp b/physx/source/physx/src/NpSoftBody.cpp index 06364ea83..78c07b6d1 100644 --- a/physx/source/physx/src/NpSoftBody.cpp +++ b/physx/source/physx/src/NpSoftBody.cpp @@ -44,6 +44,7 @@ #include "NpArticulationLink.h" #include "ScSoftBodySim.h" #include "NpFEMSoftBodyMaterial.h" +#include "cudamanager/PxCudaContext.h" using namespace physx; @@ -116,7 +117,7 @@ namespace physx return mCore.getFlags(); } - void NpSoftBody::setParameter(const PxFEMParameters paramters) + void NpSoftBody::setParameter(PxFEMParameters paramters) { NpScene* npScene = getNpScene(); NP_WRITE_CHECK(npScene); @@ -133,108 +134,53 @@ namespace physx return mCore.getParameter(); } - PxBuffer* NpSoftBody::getBufferFromFlag(PxSoftBodyData::Enum flags) + PxVec4* NpSoftBody::getPositionInvMassBufferD() { - PxBuffer* buf = NULL; + PX_CHECK_AND_RETURN_NULL(mShape != NULL, "NpSoftBody::getPositionInvMassBufferD: Softbody does not have a shape, attach shape first."); + Dy::SoftBodyCore& core = mCore.getCore(); - PX_UNUSED(core); - switch (flags) - { - case PxSoftBodyData::ePOSITION_INVMASS: - buf = core.mPositionInvMass; - break; - case PxSoftBodyData::eSIM_POSITION_INVMASS: - buf = core.mSimPositionInvMass; - break; - case PxSoftBodyData::eSIM_VELOCITY: - buf = core.mSimVelocityInvMass; - break; - case PxSoftBodyData::eSIM_KINEMATIC_TARGET: - buf = core.mKinematicTarget; - break; - case PxSoftBodyData::eNONE: - case PxSoftBodyData::eALL: - default: - PX_ASSERT(0); - } - return buf; + return core.mPositionInvMass; } - PxBuffer* NpSoftBody::getBufferHostFromFlag(PxSoftBodyData::Enum flags) + PxVec4* NpSoftBody::getRestPositionBufferD() { - PxBuffer* buf = NULL; + PX_CHECK_AND_RETURN_NULL(mShape != NULL, "NpSoftBody::getRestPositionBufferD: Softbody does not have a shape, attach shape first."); + Dy::SoftBodyCore& core = mCore.getCore(); - PX_UNUSED(core); - switch (flags) - { - case PxSoftBodyData::ePOSITION_INVMASS: - buf = core.mPositionInvMassCPU; - break; - case PxSoftBodyData::eSIM_POSITION_INVMASS: - buf = core.mSimPositionInvMassCPU; - break; - case PxSoftBodyData::eSIM_VELOCITY: - buf = core.mSimVelocityInvMassCPU; - break; - case PxSoftBodyData::eSIM_KINEMATIC_TARGET: - buf = core.mKinematicTargetCPU; - break; - case PxSoftBodyData::eNONE: - case PxSoftBodyData::eALL: - default: - PX_ASSERT(0); - } - return buf; + return core.mRestPosition; } - void NpSoftBody::readData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush) + PxVec4* NpSoftBody::getSimPositionInvMassBufferD() { - PxBuffer* sourceBuffer = getBufferFromFlag(flags); - if (!sourceBuffer) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "PxSoftBody::readData, source buffer hasn't been allocated."); - return; - } + PX_CHECK_AND_RETURN_NULL(mSimulationMesh != NULL, "NpSoftBody::getSimPositionInvMassBufferD: Softbody does not have a simulation mesh, attach simulation mesh first."); - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - PX_ASSERT(physxGpu); - - physxGpu->addCopyCommand(buffer, *sourceBuffer, flush); + Dy::SoftBodyCore& core = mCore.getCore(); + return core.mSimPositionInvMass; } - void NpSoftBody::readData(PxSoftBodyData::Enum flags, bool flush) + PxVec4* NpSoftBody::getSimVelocityBufferD() { - readData(flags, *getBufferHostFromFlag(flags), flush); + PX_CHECK_AND_RETURN_NULL(mSimulationMesh != NULL, "NpSoftBody::getSimVelocityBufferD: Softbody does not have a simulation mesh, attach simulation mesh first."); + + Dy::SoftBodyCore& core = mCore.getCore(); + return core.mSimVelocity; } - void NpSoftBody::writeData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush) + void NpSoftBody::markDirty(PxSoftBodyDataFlags flags) { - NpScene* npScene = getNpScene(); - NP_WRITE_CHECK(npScene); - - PX_CHECK_SCENE_API_WRITE_FORBIDDEN(npScene, "PxSoftBody::writeData() not allowed while simulation is running. Call will be ignored.") - - if (flags == PxSoftBodyData::ePOSITION_INVMASS) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "NpSoftBody::writeData, ePOSITION_INVMASS is immutable."); - return; - } - PxBuffer* targetBuffer = getBufferFromFlag(flags); - if (!targetBuffer) - { - PxGetFoundation().error(PxErrorCode::eINVALID_OPERATION, __FILE__, __LINE__, "NpSoftBody::writeData, target buffer hasn't been allocated."); - return; - } - - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - PX_ASSERT(physxGpu); + NP_WRITE_CHECK(getNpScene()); - physxGpu->addCopyCommand(*targetBuffer, buffer, flush); + Dy::SoftBodyCore& core = mCore.getCore(); + core.mDirtyFlags |= flags; } - void NpSoftBody::writeData(PxSoftBodyData::Enum flags, bool flush) + void NpSoftBody::setKinematicTargetBufferD(const PxVec4* positions, PxSoftBodyFlags flags) { - writeData(flags, *getBufferHostFromFlag(flags), flush); + NP_WRITE_CHECK(getNpScene()); + PX_CHECK_AND_RETURN(!(positions == NULL && flags != PxSoftBodyFlags(0)), "NpSoftBody::setKinematicTargetBufferD: targets cannot be null if flags are set to be kinematic."); + PX_CHECK_SCENE_API_WRITE_FORBIDDEN(getNpScene(), "PxSoftBody::setKinematicTargetBufferD() not allowed while simulation is running. Call will be ignored.") + + mCore.setKinematicTargets(positions, flags); } PxCudaContextManager* NpSoftBody::getCudaContextManager() const @@ -288,73 +234,38 @@ namespace physx } PxShape* NpSoftBody::getShape() - { - return mShape; + { + return mShape; } PxTetrahedronMesh* NpSoftBody::getCollisionMesh() { - PxTetrahedronMeshGeometry tetMeshGeom; - mShape->getTetrahedronMeshGeometry(tetMeshGeom); + const PxTetrahedronMeshGeometry& tetMeshGeom = static_cast(mShape->getGeometry()); return tetMeshGeom.tetrahedronMesh; } - PxTetrahedronMesh* NpSoftBody::getSimulationMesh() + const PxTetrahedronMesh* NpSoftBody::getCollisionMesh() const { - return mSimulationMesh; + const PxTetrahedronMeshGeometry& tetMeshGeom = static_cast(mShape->getGeometry()); + return tetMeshGeom.tetrahedronMesh; } - PxSoftBodyAuxData* NpSoftBody::getSoftBodyAuxData() - { - return mSoftBodyAuxData; - } bool NpSoftBody::attachSimulationMesh(PxTetrahedronMesh& simulationMesh, PxSoftBodyAuxData& softBodyAuxData) { Dy::SoftBodyCore& core = mCore.getCore(); - PX_CHECK_AND_RETURN_NULL(core.mSimPositionInvMassCPU == NULL, "NpSoftBody::attachSimulationMesh: mSimPositionInvMassCPU already exists, overwrite not allowed, call detachSimulationMesh first"); - PX_CHECK_AND_RETURN_NULL(core.mSimVelocityInvMassCPU == NULL, "NpSoftBody::attachSimulationMesh: mSimVelocityInvMassCPU already exists, overwrite not allowed, call detachSimulationMesh first"); - PX_CHECK_AND_RETURN_NULL(core.mSimPositionInvMass == NULL, "NpSoftBody::attachSimulationMesh: mSimPositionInvMass already exists, overwrite not allowed, call detachSimulationMesh first"); - PX_CHECK_AND_RETURN_NULL(core.mSimVelocityInvMass == NULL, "NpSoftBody::attachSimulationMesh: mSimVelocityInvMass already exists, overwrite not allowed, call detachSimulationMesh first"); + PX_CHECK_AND_RETURN_NULL(core.mSimVelocity == NULL, "NpSoftBody::attachSimulationMesh: mSimVelocity already exists, overwrite not allowed, call detachSimulationMesh first"); mSimulationMesh = static_cast(&simulationMesh); mSoftBodyAuxData = static_cast(&softBodyAuxData); - //const PxTetrahedronMeshGeometry& tetGeometry = mSimShape->getGeometry().tetMesh(); Gu::TetrahedronMesh* tetMesh = static_cast(&simulationMesh); - - const PxU32 numVertsGM = tetMesh->getNbVerticesFast(); - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - - core.mSimPositionInvMassCPU = physxGpu->createBuffer(numVertsGM * sizeof(PxVec4), PxBufferType::eHOST, mCudaContextManager, &mCore.getGpuMemStat()); - core.mSimVelocityInvMassCPU = physxGpu->createBuffer(numVertsGM * sizeof(PxVec4), PxBufferType::eHOST, mCudaContextManager, &mCore.getGpuMemStat()); - core.mKinematicTargetCPU = physxGpu->createBuffer(numVertsGM * sizeof(PxVec4), PxBufferType::eHOST, mCudaContextManager, &mCore.getGpuMemStat()); - - core.mSimPositionInvMass = physxGpu->createBuffer(numVertsGM * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); - core.mSimVelocityInvMass = physxGpu->createBuffer(numVertsGM * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); - core.mKinematicTarget = physxGpu->createBuffer(numVertsGM * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); - - const Gu::TetrahedronMesh* meshData = static_cast(tetMesh); - PxVec3* positions = meshData->getVerticesFast(); - PxVec4* positionInv = reinterpret_cast(core.mSimPositionInvMassCPU->map()); - PxVec4* velocityInv = reinterpret_cast(core.mSimVelocityInvMassCPU->map()); - PxVec4* kinematicTarget = reinterpret_cast(core.mKinematicTargetCPU->map()); - const Gu::SoftBodyAuxData* s = static_cast(&softBodyAuxData); - const float* invMassGM = s->mGridModelInvMass; - for (PxU32 i = 0; i < numVertsGM; ++i) - { - const PxVec3 vert = positions[i]; - PxReal invMass = invMassGM ? invMassGM[i] : 1.0f; - positionInv[i] = PxVec4(vert.x, vert.y, vert.z, invMass); - velocityInv[i] = PxVec4(0.f, 0.f, 0.f, invMass); - kinematicTarget[i] = PxVec4(vert.x, vert.y, vert.z, 0.f); - } - core.mSimPositionInvMassCPU->unmap(); - core.mSimVelocityInvMassCPU->unmap(); - core.mKinematicTargetCPU->unmap(); + const PxU32 numVertsGM = tetMesh->getNbVerticesFast(); + core.mSimPositionInvMass = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVertsGM); + core.mSimVelocity = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVertsGM); return true; } @@ -379,42 +290,23 @@ namespace physx PX_CHECK_AND_RETURN_NULL(mShape == NULL, "NpSoftBody::attachShape: soft body can just have one shape"); PX_CHECK_AND_RETURN_NULL(shape.isExclusive(), "NpSoftBody::attachShape: shape must be exclusive"); PX_CHECK_AND_RETURN_NULL(npShape->getCore().getCore().mShapeCoreFlags & PxShapeCoreFlag::eSOFT_BODY_SHAPE, "NpSoftBody::attachShape: shape must be a soft body shape!"); - + Dy::SoftBodyCore& core = mCore.getCore(); - PX_CHECK_AND_RETURN_NULL(core.mPositionInvMassCPU == NULL, "NpSoftBody::attachShape: mPositionInvMassCPU already exists, overwrite not allowed, call detachShape first"); - PX_CHECK_AND_RETURN_NULL(core.mPositionInvMass == NULL, "NpSoftBody::attachShape: mPositionInvMass already exists, overwrite not allowed, call detachShape first"); - + mShape = npShape; PX_ASSERT(shape.getActor() == NULL); npShape->onActorAttach(*this); - + const PxGeometryHolder gh(mShape->getGeometry()); // PT: TODO: avoid that copy const PxTetrahedronMeshGeometry& tetGeometry = gh.tetMesh(); Gu::BVTetrahedronMesh* tetMesh = static_cast(tetGeometry.tetrahedronMesh); const PxU32 numVerts = tetMesh->getNbVerticesFast(); - PxPhysXGpu* physxGpu = PxvGetPhysXGpu(true); - - core.mPositionInvMassCPU = physxGpu->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eHOST, mCudaContextManager, &mCore.getGpuMemStat()); - core.mRestPositionInvMassCPU = physxGpu->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eHOST, mCudaContextManager, &mCore.getGpuMemStat()); - - core.mPositionInvMass = physxGpu->createBuffer(numVerts * sizeof(PxVec4), PxBufferType::eDEVICE, mCudaContextManager, &mCore.getGpuMemStat()); - - const Gu::TetrahedronMesh* meshData = static_cast(tetMesh); - PxVec3* positions = meshData->getVerticesFast(); - PxVec4* positionInv = reinterpret_cast(core.mPositionInvMassCPU->map()); - PxVec4* restPositionInv = reinterpret_cast(core.mRestPositionInvMassCPU->map()); - for (PxU32 i = 0; i < numVerts; ++i) - { - const PxVec3 vert = positions[i]; - positionInv[i] = PxVec4(vert.x, vert.y, vert.z, 1.0f); - restPositionInv[i] = PxVec4(vert.x, vert.y, vert.z, 1.f); - } - core.mPositionInvMassCPU->unmap(); - core.mRestPositionInvMassCPU->unmap(); + core.mPositionInvMass = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVerts); + core.mRestPosition = PX_DEVICE_ALLOC_T(PxVec4, mCudaContextManager, numVerts); updateMaterials(); @@ -426,34 +318,17 @@ namespace physx PX_CHECK_MSG(getNpSceneFromActor(*this) == NULL, "Detaching a shape from a softbody is currenly only allowed as long as it is not part of a scene. Please remove the softbody from its scene first."); Dy::SoftBodyCore& core = mCore.getCore(); - if (core.mPositionInvMassCPU) - { - core.mPositionInvMassCPU->release(); - core.mPositionInvMassCPU = NULL; - } - if (core.mRestPositionInvMassCPU) + if (core.mRestPosition) { - core.mRestPositionInvMassCPU->release(); - core.mRestPositionInvMassCPU = NULL; + PX_DEVICE_FREE(mCudaContextManager, core.mRestPosition); + core.mRestPosition = NULL; } if (core.mPositionInvMass) { - core.mPositionInvMass->release(); + PX_DEVICE_FREE(mCudaContextManager, core.mPositionInvMass); core.mPositionInvMass = NULL; } - if (core.mKinematicTargetCPU) - { - core.mKinematicTargetCPU->release(); - core.mKinematicTargetCPU = NULL; - } - - if (core.mKinematicTarget) - { - core.mKinematicTarget->release(); - core.mKinematicTarget = NULL; - } - if (mShape) mShape->onActorDetach(); mShape = NULL; @@ -462,37 +337,16 @@ namespace physx void NpSoftBody::detachSimulationMesh() { Dy::SoftBodyCore& core = mCore.getCore(); - if (core.mSimPositionInvMassCPU) - { - core.mSimPositionInvMassCPU->release(); - core.mSimPositionInvMassCPU = NULL; - } if (core.mSimPositionInvMass) { - core.mSimPositionInvMass->release(); + PX_DEVICE_FREE(mCudaContextManager, core.mSimPositionInvMass); core.mSimPositionInvMass = NULL; } - if (core.mSimVelocityInvMassCPU) - { - core.mSimVelocityInvMassCPU->release(); - core.mSimVelocityInvMassCPU = NULL; - } - if (core.mSimVelocityInvMass) - { - core.mSimVelocityInvMass->release(); - core.mSimVelocityInvMass = NULL; - } - - if (core.mKinematicTargetCPU) - { - core.mKinematicTargetCPU->release(); - core.mKinematicTargetCPU = NULL; - } - if (core.mKinematicTarget) + if (core.mSimVelocity) { - core.mKinematicTarget->release(); - core.mKinematicTarget = NULL; + PX_DEVICE_FREE(mCudaContextManager, core.mSimVelocity); + core.mSimVelocity = NULL; } mSimulationMesh = NULL; @@ -504,6 +358,7 @@ namespace physx NpScene* npScene = getNpScene(); NP_WRITE_CHECK(npScene); + // AD why is this commented out? // NpPhysics::getInstance().notifyDeletionListenersUserRelease(this, PxArticulationBase::userData); if (npScene) @@ -512,6 +367,7 @@ namespace physx npScene->removeFromSoftBodyList(*this); } + detachSimulationMesh(); detachShape(); PX_ASSERT(!isAPIWriteForbidden()); @@ -612,13 +468,14 @@ namespace physx NP_WRITE_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "NpSoftBody::addRigidAttachment: Soft body must be inserted into the scene.", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL((actor == NULL || actor->getScene() != NULL), "NpSoftBody::addRigidAttachment: actor must be inserted into the scene.", 0xFFFFFFFF); + PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "NpSoftBody::addRigidAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF); PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "NpSoftBody::addRigidAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF); Sc::BodyCore* core = getBodyCore(actor); PxVec3 aPose = actorSpacePose; - if(actor && actor->getConcreteType()==PxConcreteType::eRIGID_STATIC) + if (actor && actor->getConcreteType()==PxConcreteType::eRIGID_STATIC) { NpRigidStatic* stat = static_cast(actor); aPose = stat->getGlobalPose().transform(aPose); @@ -668,13 +525,14 @@ namespace physx NP_WRITE_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "NpSoftBody::addTetRigidAttachment: Soft body must be inserted into the scene.", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL((actor == NULL || actor->getScene() != NULL), "NpSoftBody::addTetRigidAttachment: actor must be inserted into the scene.", 0xFFFFFFFF); + PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "NpSoftBody::addTetRigidAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF); PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "NpSoftBody::addTetRigidAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF); Sc::BodyCore* core = getBodyCore(actor); PxVec3 aPose = actorSpacePose; - if(actor && actor->getConcreteType()==PxConcreteType::eRIGID_STATIC) + if (actor && actor->getConcreteType()==PxConcreteType::eRIGID_STATIC) { NpRigidStatic* stat = static_cast(actor); aPose = stat->getGlobalPose().transform(aPose); @@ -743,19 +601,21 @@ namespace physx mCore.removeSoftBodyFilters(*core, tetIndices0, tetIndices1, tetIndicesSize); } - PxU32 NpSoftBody::addSoftBodyAttachment(PxSoftBody* softbody0, PxU32 tetIdx0, const PxVec4& tetBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1, PxConeLimitedConstraint* constraint) + PxU32 NpSoftBody::addSoftBodyAttachment(PxSoftBody* softbody0, PxU32 tetIdx0, const PxVec4& tetBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1, + PxConeLimitedConstraint* constraint, PxReal constraintOffset) { NP_WRITE_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(softbody0 != NULL, "NpSoftBody::addSoftBodyAttachment: soft body must not be null", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "NpSoftBody::addSoftBodyAttachment: soft body must be inserted into the scene.", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL(softbody0->getScene() != NULL, "NpSoftBody::addSoftBodyAttachment: soft body must be inserted into the scene.", 0xFFFFFFFF); + PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "NpSoftBody::addSoftBodyAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF); PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "NpSoftBody::addSoftBodyAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF); NpSoftBody* dyn = static_cast(softbody0); Sc::SoftBodyCore* core = &dyn->getCore(); - return mCore.addSoftBodyAttachment(*core, tetIdx0, tetBarycentric0, tetIdx1, tetBarycentric1, constraint); + return mCore.addSoftBodyAttachment(*core, tetIdx0, tetBarycentric0, tetIdx1, tetBarycentric1, constraint, constraintOffset); } void NpSoftBody::removeSoftBodyAttachment(PxSoftBody* softbody0, PxU32 handle) @@ -813,25 +673,24 @@ namespace physx #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION - PxU32 NpSoftBody::addClothAttachment(PxFEMCloth* cloth, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, PxConeLimitedConstraint* constraint) + PxU32 NpSoftBody::addClothAttachment(PxFEMCloth* cloth, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, + PxConeLimitedConstraint* constraint, PxReal constraintOffset) { NP_WRITE_CHECK(getNpScene()); PX_CHECK_AND_RETURN_VAL(cloth != NULL, "NpSoftBody::addClothAttachment: actor must not be null", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL(getNpScene() != NULL, "NpSoftBody::addClothAttachment: Soft body must be inserted into the scene.", 0xFFFFFFFF); PX_CHECK_AND_RETURN_VAL(cloth->getScene() != NULL, "NpSoftBody::addClothAttachment: actor must be inserted into the scene.", 0xFFFFFFFF); + PX_CHECK_AND_RETURN_VAL(constraint == NULL || constraint->isValid(), "NpSoftBody::addClothAttachment: PxConeLimitedConstraint needs to be valid if specified.", 0xFFFFFFFF); PX_CHECK_SCENE_API_WRITE_FORBIDDEN_AND_RETURN_VAL(getNpScene(), "NpSoftBody::addClothAttachment: Illegal to call while simulation is running.", 0xFFFFFFFF); NpFEMCloth* dyn = static_cast(cloth); Sc::FEMClothCore* core = &dyn->getCore(); - - return mCore.addClothAttachment(*core, triIdx, triBarycentric, tetIdx, tetBarycentric, constraint); + + return mCore.addClothAttachment(*core, triIdx, triBarycentric, tetIdx, tetBarycentric, constraint, constraintOffset); } #else - PxU32 NpSoftBody::addClothAttachment(PxFEMCloth*, PxU32, const PxVec4&, PxU32, const PxVec4&, PxConeLimitedConstraint*) - { - return 0; - } + PxU32 NpSoftBody::addClothAttachment(PxFEMCloth*, PxU32, const PxVec4&, PxU32, const PxVec4&, PxConeLimitedConstraint*, PxReal) { return 0; } #endif #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION diff --git a/physx/source/physx/src/NpSoftBody.h b/physx/source/physx/src/NpSoftBody.h index f97f7a776..b8a14c702 100644 --- a/physx/source/physx/src/NpSoftBody.h +++ b/physx/source/physx/src/NpSoftBody.h @@ -29,6 +29,8 @@ #ifndef NP_SOFTBODY_H #define NP_SOFTBODY_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxSoftBody.h" #include "ScSoftBodyCore.h" #include "NpActorTemplate.h" @@ -42,33 +44,36 @@ namespace physx class NpSoftBody : public NpActorTemplate { public: - NpSoftBody(PxCudaContextManager& cudaContextManager); - NpSoftBody(PxBaseFlags baseFlags, PxCudaContextManager& cudaContextManager); + NpSoftBody(PxCudaContextManager& cudaContextManager); + NpSoftBody(PxBaseFlags baseFlags, PxCudaContextManager& cudaContextManager); - virtual ~NpSoftBody() {} + virtual ~NpSoftBody() {} - void exportData(PxSerializationContext& /*context*/) const{} + void exportData(PxSerializationContext& /*context*/) const{} //external API - virtual PxActorType::Enum getType() const { return PxActorType::eSOFTBODY; } + virtual PxActorType::Enum getType() const { return PxActorType::eSOFTBODY; } - virtual PxBounds3 getWorldBounds(float inflation = 1.01f) const; - virtual PxU32 getGpuSoftBodyIndex(); + virtual PxBounds3 getWorldBounds(float inflation = 1.01f) const; + virtual PxU32 getGpuSoftBodyIndex(); - virtual void setSoftBodyFlag(PxSoftBodyFlag::Enum flag, bool val); - virtual void setSoftBodyFlags(PxSoftBodyFlags flags); - virtual PxSoftBodyFlags getSoftBodyFlag() const; + virtual void setSoftBodyFlag(PxSoftBodyFlag::Enum flag, bool val); + virtual void setSoftBodyFlags(PxSoftBodyFlags flags); + virtual PxSoftBodyFlags getSoftBodyFlag() const; - virtual void setParameter(const PxFEMParameters paramters); - virtual PxFEMParameters getParameter() const; + virtual void setParameter(PxFEMParameters paramters); + virtual PxFEMParameters getParameter() const; - virtual void readData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush); - virtual void readData(PxSoftBodyData::Enum flags, bool flush); + virtual PxVec4* getPositionInvMassBufferD(); + virtual PxVec4* getRestPositionBufferD(); + virtual PxVec4* getSimPositionInvMassBufferD(); + virtual PxVec4* getSimVelocityBufferD(); - virtual void writeData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush); - virtual void writeData(PxSoftBodyData::Enum flags, bool flush); + virtual void markDirty(PxSoftBodyDataFlags flags); - virtual PxCudaContextManager* getCudaContextManager() const; + virtual void setKinematicTargetBufferD(const PxVec4* positions, PxSoftBodyFlags flags); + + virtual PxCudaContextManager* getCudaContextManager() const; virtual void setWakeCounter(PxReal wakeCounterValue); virtual PxReal getWakeCounter() const; @@ -81,8 +86,11 @@ namespace physx virtual PxShape* getShape(); virtual PxTetrahedronMesh* getCollisionMesh(); - virtual PxTetrahedronMesh* getSimulationMesh(); - virtual PxSoftBodyAuxData* getSoftBodyAuxData(); + virtual const PxTetrahedronMesh* getCollisionMesh() const; + virtual PxTetrahedronMesh* getSimulationMesh() { return mSimulationMesh; } + virtual const PxTetrahedronMesh* getSimulationMesh() const { return mSimulationMesh; } + virtual PxSoftBodyAuxData* getSoftBodyAuxData() { return mSoftBodyAuxData; } + virtual const PxSoftBodyAuxData* getSoftBodyAuxData() const { return mSoftBodyAuxData; } virtual bool attachShape(PxShape& shape); virtual bool attachSimulationMesh(PxTetrahedronMesh& simulationMesh, PxSoftBodyAuxData& softBodyAuxData); @@ -120,34 +128,25 @@ namespace physx virtual void removeSoftBodyFilters(PxSoftBody* softbody0, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize); virtual PxU32 addSoftBodyAttachment(PxSoftBody* softbody0, PxU32 tetIdx0, const PxVec4& tetBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1, - PxConeLimitedConstraint* constraint); + PxConeLimitedConstraint* constraint, PxReal constraintOffset); virtual void removeSoftBodyAttachment(PxSoftBody* softbody0, PxU32 handle); virtual void addClothFilter(PxFEMCloth* cloth, PxU32 triIdx, PxU32 tetIdx); virtual void removeClothFilter(PxFEMCloth* cloth, PxU32 triIdx, PxU32 tetIdx); virtual PxU32 addClothAttachment(PxFEMCloth* cloth, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, - PxConeLimitedConstraint* constraint); + PxConeLimitedConstraint* constraint, PxReal constraintOffset); + virtual void removeClothAttachment(PxFEMCloth* cloth, PxU32 handle); // Debug name void setName(const char*); const char* getName() const; - virtual PxBuffer* getSimPositionInvMassCPU() { return mCore.getCore().mSimPositionInvMassCPU; } - virtual PxBuffer* getSimVelocityInvMassCPU() { return mCore.getCore().mSimVelocityInvMassCPU; } - virtual PxBuffer* getKinematicTargetCPU() { return mCore.getCore().mKinematicTargetCPU; } - - virtual PxBuffer* getPositionInvMassCPU() { return mCore.getCore().mPositionInvMassCPU; } - virtual PxBuffer* getRestPositionInvMassCPU() { return mCore.getCore().mRestPositionInvMassCPU; } - void updateMaterials(); private: - PxBuffer* getBufferFromFlag(PxSoftBodyData::Enum flags); - PxBuffer* getBufferHostFromFlag(PxSoftBodyData::Enum flags); - NpShape* mShape; //soft body should just have one shape. The geometry type should be tetrahedron mesh Gu::TetrahedronMesh* mSimulationMesh; Gu::SoftBodyAuxData* mSoftBodyAuxData; @@ -156,3 +155,4 @@ namespace physx }; } #endif +#endif diff --git a/physx/source/physx/src/PvdMetaDataPvdBinding.cpp b/physx/source/physx/src/PvdMetaDataPvdBinding.cpp index bb21c4277..bae896b68 100644 --- a/physx/source/physx/src/PvdMetaDataPvdBinding.cpp +++ b/physx/source/physx/src/PvdMetaDataPvdBinding.cpp @@ -1102,23 +1102,21 @@ static void sendGeometry(PvdMetaDataBinding& metaBind, PvdDataStream& inStream, static void setGeometry(PvdMetaDataBinding& metaBind, PvdDataStream& inStream, const PxShape& inObj, PsPvd* pvd) { - switch(inObj.getGeometryType()) - { -#define SEND_PVD_GEOM_TYPE(enumType, geomType, valueType) \ - case PxGeometryType::enumType: \ - { \ - Px##geomType geom; \ - inObj.get##geomType(geom); \ - sendGeometry(metaBind, inStream, inObj, geom, pvd); \ - } \ + const PxGeometry& geom = inObj.getGeometry(); + switch(geom.getType()) + { +#define SEND_PVD_GEOM_TYPE(enumType, geomType, valueType) \ + case PxGeometryType::enumType: \ + { \ + Px##geomType geomT = static_cast(geom); \ + sendGeometry(metaBind, inStream, inObj, geomT, pvd); \ + } \ break; SEND_PVD_GEOM_TYPE(eSPHERE, SphereGeometry, PxSphereGeometryGeneratedValues); // Plane geometries don't have any properties, so this avoids using a property // struct for them. case PxGeometryType::ePLANE: { - PxPlaneGeometry geom; - inObj.getPlaneGeometry(geom); const void* geomInst = (reinterpret_cast(&inObj)) + 4; inStream.createInstance(getPvdNamespacedNameForType(), geomInst); inStream.setPropertyValue(&inObj, "Geometry", geomInst); @@ -1205,11 +1203,11 @@ void PvdMetaDataBinding::releaseAndRecreateGeometry(PvdDataStream& inStream, con { const void* geomInst = (reinterpret_cast(&inObj)) + 4; inStream.destroyInstance(geomInst); + const PxGeometry& geom = inObj.getGeometry(); // Quick fix for HF modify, PxConvexMesh and PxTriangleMesh need recook, they should always be new if modified - if(inObj.getGeometryType() == PxGeometryType::eHEIGHTFIELD) + if(geom.getType() == PxGeometryType::eHEIGHTFIELD) { - PxHeightFieldGeometry hfGeom; - inObj.getHeightFieldGeometry(hfGeom); + const PxHeightFieldGeometry& hfGeom = static_cast(geom); if(inStream.isInstanceValid(hfGeom.heightField)) sendAllProperties(inStream, *hfGeom.heightField); } @@ -1546,28 +1544,6 @@ void PvdMetaDataBinding::destroyInstance(PvdDataStream& inStream, const PxMPMPar PX_UNUSED(ownerScene); } -void PvdMetaDataBinding::createInstance(PvdDataStream& inStream, const PxCustomParticleSystem& inObj, const PxScene& ownerScene, const PxPhysics& ownerPhysics, PsPvd* pvd) -{ - PX_UNUSED(inStream); - PX_UNUSED(inObj); - PX_UNUSED(ownerScene); - PX_UNUSED(ownerPhysics); - PX_UNUSED(pvd); -} - -void PvdMetaDataBinding::sendAllProperties(PvdDataStream& inStream, const PxCustomParticleSystem& inObj) -{ - PX_UNUSED(inStream); - PX_UNUSED(inObj); -} - -void PvdMetaDataBinding::destroyInstance(PvdDataStream& inStream, const PxCustomParticleSystem& inObj, const PxScene& ownerScene) -{ - PX_UNUSED(inStream); - PX_UNUSED(inObj); - PX_UNUSED(ownerScene); -} - void PvdMetaDataBinding::createInstance(PvdDataStream& inStream, const PxHairSystem& inObj, const PxScene& ownerScene, const PxPhysics& ownerPhysics, PsPvd* pvd) { PX_UNUSED(inStream); diff --git a/physx/source/physx/src/PvdMetaDataPvdBinding.h b/physx/source/physx/src/PvdMetaDataPvdBinding.h index dcb4342c3..e798173e8 100644 --- a/physx/source/physx/src/PvdMetaDataPvdBinding.h +++ b/physx/source/physx/src/PvdMetaDataPvdBinding.h @@ -155,10 +155,6 @@ class PvdMetaDataBinding void sendAllProperties(PvdDataStream& inStream, const PxMPMParticleSystem& inObj); void destroyInstance(PvdDataStream& inStream, const PxMPMParticleSystem& inObj, const PxScene& ownerScene); - void createInstance(PvdDataStream& inStream, const PxCustomParticleSystem& inObj, const PxScene& ownerScene, const PxPhysics& ownerPhysics, PsPvd* pvd); - void sendAllProperties(PvdDataStream& inStream, const PxCustomParticleSystem& inObj); - void destroyInstance(PvdDataStream& inStream, const PxCustomParticleSystem& inObj, const PxScene& ownerScene); - void createInstance(PvdDataStream& inStream, const PxHairSystem& inObj, const PxScene& ownerScene, const PxPhysics& ownerPhysics, PsPvd* pvd); void sendAllProperties(PvdDataStream& inStream, const PxHairSystem& inObj); void destroyInstance(PvdDataStream& inStream, const PxHairSystem& inObj, const PxScene& ownerScene); diff --git a/physx/source/physx/src/PvdPhysicsClient.cpp b/physx/source/physx/src/PvdPhysicsClient.cpp index fd032fc6a..d90c9a16a 100644 --- a/physx/source/physx/src/PvdPhysicsClient.cpp +++ b/physx/source/physx/src/PvdPhysicsClient.cpp @@ -28,6 +28,7 @@ // PX_DUMMY_SYMBOL +#include "foundation/PxPreprocessor.h" #if PX_SUPPORT_PVD #include "pvd/PxPvdTransport.h" diff --git a/physx/source/physx/src/device/windows/PhysXIndicatorWindows.cpp b/physx/source/physx/src/device/windows/PhysXIndicatorWindows.cpp index ffa4a31ba..33f0bc328 100644 --- a/physx/source/physx/src/device/windows/PhysXIndicatorWindows.cpp +++ b/physx/source/physx/src/device/windows/PhysXIndicatorWindows.cpp @@ -29,10 +29,7 @@ #include "PhysXIndicator.h" #include "nvPhysXtoDrv.h" -#pragma warning (push) -#pragma warning (disable : 4668) //'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives' -#include -#pragma warning (pop) +#include "foundation/windows/PxWindowsInclude.h" #include diff --git a/physx/source/physx/src/gpu/PxGpu.cpp b/physx/source/physx/src/gpu/PxGpu.cpp index 309275eee..c793feb26 100644 --- a/physx/source/physx/src/gpu/PxGpu.cpp +++ b/physx/source/physx/src/gpu/PxGpu.cpp @@ -45,6 +45,7 @@ namespace physx typedef physx::PxKernelIndex* (PxGetCudaFunctionTable_FUNC)(); typedef PxU32 (PxGetCudaFunctionTableSize_FUNC)(); typedef void** PxGetCudaModuleTable_FUNC(); + typedef PxPhysicsGpu* PxCreatePhysicsGpu_FUNC(); extern PxCreateCudaContextManager_FUNC* g_PxCreateCudaContextManager_Func; extern PxGetSuggestedCudaDeviceOrdinal_FUNC* g_PxGetSuggestedCudaDeviceOrdinal_Func; @@ -55,6 +56,7 @@ namespace physx extern PxGetCudaFunctionTableSize_FUNC* g_PxGetCudaFunctionTableSize_Func; extern PxGetCudaFunctionTableSize_FUNC* g_PxGetCudaModuleTableSize_Func; extern PxGetCudaModuleTable_FUNC* g_PxGetCudaModuleTable_Func; + extern PxCreatePhysicsGpu_FUNC* g_PxCreatePhysicsGpu_Func; } // end of physx namespace @@ -62,8 +64,7 @@ namespace physx physx::PxCudaContextManager* PxCreateCudaContextManager(physx::PxFoundation& foundation, const physx::PxCudaContextManagerDesc& desc, physx::PxProfilerCallback* profilerCallback) { - if (!physx::g_PxCreateCudaContextManager_Func) - physx::PxLoadPhysxGPUModule(desc.appGUID); + physx::PxLoadPhysxGPUModule(desc.appGUID); if (physx::g_PxCreateCudaContextManager_Func) return physx::g_PxCreateCudaContextManager_Func(foundation, desc, profilerCallback); @@ -73,8 +74,7 @@ physx::PxCudaContextManager* PxCreateCudaContextManager(physx::PxFoundation& fou int PxGetSuggestedCudaDeviceOrdinal(physx::PxErrorCallback& errc) { - if (!physx::g_PxGetSuggestedCudaDeviceOrdinal_Func) - physx::PxLoadPhysxGPUModule(NULL); + physx::PxLoadPhysxGPUModule(NULL); if (physx::g_PxGetSuggestedCudaDeviceOrdinal_Func) return physx::g_PxGetSuggestedCudaDeviceOrdinal_Func(errc); @@ -84,8 +84,7 @@ int PxGetSuggestedCudaDeviceOrdinal(physx::PxErrorCallback& errc) void PxSetPhysXGpuProfilerCallback(physx::PxProfilerCallback* profilerCallback) { - if (!physx::g_PxSetPhysXGpuProfilerCallback_Func) - physx::PxLoadPhysxGPUModule(NULL); + physx::PxLoadPhysxGPUModule(NULL); if (physx::g_PxSetPhysXGpuProfilerCallback_Func) physx::g_PxSetPhysXGpuProfilerCallback_Func(profilerCallback); @@ -93,8 +92,7 @@ void PxSetPhysXGpuProfilerCallback(physx::PxProfilerCallback* profilerCallback) void PxCudaRegisterFunction(int moduleIndex, const char* functionName) { - if (!physx::g_PxCudaRegisterFunction_Func) - physx::PxLoadPhysxGPUModule(NULL); + physx::PxLoadPhysxGPUModule(NULL); if (physx::g_PxCudaRegisterFunction_Func) physx::g_PxCudaRegisterFunction_Func(moduleIndex, functionName); @@ -102,8 +100,7 @@ void PxCudaRegisterFunction(int moduleIndex, const char* functionName) void** PxCudaRegisterFatBinary(void* fatBin) { - if (!physx::g_PxCudaRegisterFatBinary_Func) - physx::PxLoadPhysxGPUModule(NULL); + physx::PxLoadPhysxGPUModule(NULL); if (physx::g_PxCudaRegisterFatBinary_Func) return physx::g_PxCudaRegisterFatBinary_Func(fatBin); @@ -114,8 +111,7 @@ void** PxCudaRegisterFatBinary(void* fatBin) physx::PxKernelIndex* PxGetCudaFunctionTable() { - if(!physx::g_PxGetCudaFunctionTable_Func) - physx::PxLoadPhysxGPUModule(NULL); + physx::PxLoadPhysxGPUModule(NULL); if(physx::g_PxGetCudaFunctionTable_Func) return physx::g_PxGetCudaFunctionTable_Func(); @@ -123,10 +119,9 @@ physx::PxKernelIndex* PxGetCudaFunctionTable() return NULL; } -physx::PxU32 PxGetCudaFunctionTableSize() { - - if(!physx::g_PxGetCudaFunctionTableSize_Func) - physx::PxLoadPhysxGPUModule(NULL); +physx::PxU32 PxGetCudaFunctionTableSize() +{ + physx::PxLoadPhysxGPUModule(NULL); if(physx::g_PxGetCudaFunctionTableSize_Func) return physx::g_PxGetCudaFunctionTableSize_Func(); @@ -134,9 +129,9 @@ physx::PxU32 PxGetCudaFunctionTableSize() { return 0; } -void** PxGetCudaModuleTable() { - if(!physx::g_PxGetCudaModuleTable_Func) - physx::PxLoadPhysxGPUModule(NULL); +void** PxGetCudaModuleTable() +{ + physx::PxLoadPhysxGPUModule(NULL); if(physx::g_PxGetCudaModuleTable_Func) return physx::g_PxGetCudaModuleTable_Func(); @@ -147,8 +142,7 @@ void** PxGetCudaModuleTable() { physx::PxU32 PxGetCudaModuleTableSize() { - if(!physx::g_PxGetCudaModuleTableSize_Func) - physx::PxLoadPhysxGPUModule(NULL); + physx::PxLoadPhysxGPUModule(NULL); if(physx::g_PxGetCudaModuleTableSize_Func) return physx::g_PxGetCudaModuleTableSize_Func(); @@ -157,6 +151,16 @@ physx::PxU32 PxGetCudaModuleTableSize() } +physx::PxPhysicsGpu* PxGetPhysicsGpu() +{ + physx::PxLoadPhysxGPUModule(NULL); + + if (physx::g_PxCreatePhysicsGpu_Func) + return physx::g_PxCreatePhysicsGpu_Func(); + + return NULL; +} + #endif // PX_PHYSX_GPU_STATIC #endif // PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/physx/src/gpu/PxPhysXGpuModuleLoader.cpp b/physx/source/physx/src/gpu/PxPhysXGpuModuleLoader.cpp index 5731efa1f..d7d9fbfd3 100644 --- a/physx/source/physx/src/gpu/PxPhysXGpuModuleLoader.cpp +++ b/physx/source/physx/src/gpu/PxPhysXGpuModuleLoader.cpp @@ -43,6 +43,12 @@ #include "stdio.h" + +#if PX_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundefined-reinterpret-cast" +#endif + #define STRINGIFY(x) #x #define GETSTRING(x) STRINGIFY(x) @@ -58,15 +64,15 @@ static void reportError(const char* file, int line, const char* format, ...) va_list args; va_start(args, format); - physx::PxFoundation* foundation = &PxGetFoundation(); + physx::PxFoundation* foundation = PxIsFoundationValid(); if(foundation) { foundation->error(physx::PxErrorCode::eINTERNAL_ERROR, file, line, format, args); } else { - printf("Error in %s:%i: ", file, line); - vprintf(format, args); + fprintf(stderr, "Error in %s:%i: ", file, line); + vfprintf(stderr, format, args); } va_end(args); @@ -86,6 +92,7 @@ namespace physx class PxFoundation; class PxPhysXGpu; + class PxPhysicsGpu; typedef physx::PxPhysXGpu* (PxCreatePhysXGpu_FUNC)(); typedef physx::PxCudaContextManager* (PxCreateCudaContextManager_FUNC)(physx::PxFoundation& foundation, const physx::PxCudaContextManagerDesc& desc, physx::PxProfilerCallback* profilerCallback); @@ -96,7 +103,7 @@ namespace physx typedef physx::PxKernelIndex* (PxGetCudaFunctionTable_FUNC)(); typedef PxU32 (PxGetCudaFunctionTableSize_FUNC)(); typedef void** PxGetCudaModuleTable_FUNC(); - + typedef PxPhysicsGpu* PxCreatePhysicsGpu_FUNC(); PxCreatePhysXGpu_FUNC* g_PxCreatePhysXGpu_Func = NULL; PxCreateCudaContextManager_FUNC* g_PxCreateCudaContextManager_Func = NULL; @@ -108,27 +115,42 @@ namespace physx PxGetCudaFunctionTableSize_FUNC* g_PxGetCudaFunctionTableSize_Func = NULL; PxGetCudaFunctionTableSize_FUNC* g_PxGetCudaModuleTableSize_Func = NULL; PxGetCudaModuleTable_FUNC* g_PxGetCudaModuleTable_Func = NULL; + PxCreatePhysicsGpu_FUNC* g_PxCreatePhysicsGpu_Func = NULL; + + void PxUnloadPhysxGPUModule() + { + g_PxCreatePhysXGpu_Func = NULL; + g_PxCreateCudaContextManager_Func = NULL; + g_PxGetSuggestedCudaDeviceOrdinal_Func = NULL; + g_PxSetPhysXGpuProfilerCallback_Func = NULL; + g_PxCudaRegisterFunction_Func = NULL; + g_PxCudaRegisterFatBinary_Func = NULL; + g_PxGetCudaFunctionTable_Func = NULL; + g_PxGetCudaFunctionTableSize_Func = NULL; + g_PxGetCudaModuleTableSize_Func = NULL; + g_PxGetCudaModuleTable_Func = NULL; + g_PxCreatePhysicsGpu_Func = NULL; + } #if PX_WINDOWS typedef void (PxSetPhysXGpuDelayLoadHook_FUNC)(const PxDelayLoadHook* delayLoadHook); #define DEFAULT_PHYSX_GPU_GUID "D79FA4BF-177C-4841-8091-4375D311D6A3" - + void PxLoadPhysxGPUModule(const char* appGUID) { - static HMODULE s_library; - - if (s_library == NULL) - s_library = GetModuleHandle(gPhysXGpuLibraryName); + HMODULE s_library = GetModuleHandle(gPhysXGpuLibraryName); + bool freshlyLoaded = false; if (s_library == NULL) { Cm::CmModuleUpdateLoader moduleLoader(UPDATE_LOADER_DLL_NAME); s_library = moduleLoader.LoadModule(gPhysXGpuLibraryName, appGUID == NULL ? DEFAULT_PHYSX_GPU_GUID : appGUID); + freshlyLoaded = true; } - if (s_library) + if (s_library && (freshlyLoaded || g_PxCreatePhysXGpu_Func == NULL)) { g_PxCreatePhysXGpu_Func = (PxCreatePhysXGpu_FUNC*)GetProcAddress(s_library, "PxCreatePhysXGpu"); g_PxCreateCudaContextManager_Func = (PxCreateCudaContextManager_FUNC*)GetProcAddress(s_library, "PxCreateCudaContextManager"); @@ -140,6 +162,7 @@ namespace physx g_PxGetCudaFunctionTableSize_Func = (PxGetCudaFunctionTableSize_FUNC*)GetProcAddress(s_library, "PxGpuGetCudaFunctionTableSize"); g_PxGetCudaModuleTableSize_Func = (PxGetCudaFunctionTableSize_FUNC*)GetProcAddress(s_library, "PxGpuGetCudaModuleTableSize"); g_PxGetCudaModuleTable_Func = (PxGetCudaModuleTable_FUNC*)GetProcAddress(s_library, "PxGpuGetCudaModuleTable"); + g_PxCreatePhysicsGpu_Func = (PxCreatePhysicsGpu_FUNC*)GetProcAddress(s_library, "PxGpuCreatePhysicsGpu"); } // Check for errors @@ -160,7 +183,7 @@ namespace physx void PxLoadPhysxGPUModule(const char*) { - static void* s_library; + static void* s_library = NULL; if (s_library == NULL) { @@ -173,7 +196,8 @@ namespace physx } else { - reportError(PX_FL, "Could not find libcuda.so!"); + char* error = dlerror(); + reportError(PX_FL, "Could not load libcuda.so: %s\n", error); return; } } @@ -191,17 +215,19 @@ namespace physx *reinterpret_cast(&g_PxGetCudaFunctionTableSize_Func) = dlsym(s_library, "PxGpuGetCudaFunctionTableSize"); *reinterpret_cast(&g_PxGetCudaModuleTableSize_Func) = dlsym(s_library, "PxGpuGetCudaModuleTableSize"); *reinterpret_cast(&g_PxGetCudaModuleTable_Func) = dlsym(s_library, "PxGpuGetCudaModuleTable"); + *reinterpret_cast(&g_PxCreatePhysicsGpu_Func) = dlsym(s_library, "PxGpuCreatePhysicsGpu"); } // Check for errors if (s_library == NULL) { - reportError(PX_FL, "Failed to load %s!", gPhysXGpuLibraryName); + char* error = dlerror(); + reportError(PX_FL, "Failed to load %s!: %s\n", gPhysXGpuLibraryName, error); return; } if (g_PxCreatePhysXGpu_Func == NULL || g_PxCreateCudaContextManager_Func == NULL || g_PxGetSuggestedCudaDeviceOrdinal_Func == NULL) { - reportError(PX_FL, "%s is incompatible with this version of PhysX!", gPhysXGpuLibraryName); + reportError(PX_FL, "%s is incompatible with this version of PhysX!\n", gPhysXGpuLibraryName); return; } } @@ -210,4 +236,8 @@ namespace physx } // end physx namespace +#if PX_CLANG +#pragma clang diagnostic pop +#endif + #endif // PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/physx/src/omnipvd/NpOmniPvd.cpp b/physx/source/physx/src/omnipvd/NpOmniPvd.cpp index 6df425ac4..9a16ed360 100644 --- a/physx/source/physx/src/omnipvd/NpOmniPvd.cpp +++ b/physx/source/physx/src/omnipvd/NpOmniPvd.cpp @@ -54,12 +54,12 @@ namespace physx if (mFileWriteStream) { mFileWriteStream->closeStream(); - mLoader->mDestroyOmniPvdFileWriteStream(mFileWriteStream); + mLoader->mDestroyOmniPvdFileWriteStream(*mFileWriteStream); mFileWriteStream = NULL; } if (mWriter) { - mLoader->mDestroyOmniPvdWriter(mWriter); + mLoader->mDestroyOmniPvdWriter(*mWriter); mWriter = NULL; } if (mLoader) diff --git a/physx/source/physx/src/omnipvd/OmniPvdPxSampler.cpp b/physx/source/physx/src/omnipvd/OmniPvdPxSampler.cpp index 49d2c011b..b455e3174 100644 --- a/physx/source/physx/src/omnipvd/OmniPvdPxSampler.cpp +++ b/physx/source/physx/src/omnipvd/OmniPvdPxSampler.cpp @@ -26,7 +26,7 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - +#include "foundation/PxPreprocessor.h" #if PX_SUPPORT_OMNI_PVD #include "OmniPvdPxSampler.h" #include "common/PxProfileZone.h" @@ -124,12 +124,12 @@ bool OmniPvdStreamContainer::initOmniPvd() PxPhysics& physicsRef = static_cast(NpPhysics::getInstance()); - OMNI_PVD_CREATE(physics, physicsRef); + OMNI_PVD_CREATE(PxPhysics, physicsRef); const physx::PxTolerancesScale tolScale = physicsRef.getTolerancesScale(); PxF32 scale[2]; scale[0] = tolScale.length; scale[1] = tolScale.speed; - OMNI_PVD_SETB(physics, tolerancesScale, physicsRef, scale, sizeof(PxF32) * 2); + OMNI_PVD_SETB(PxPhysics, tolerancesScale, physicsRef, scale, sizeof(PxF32) * 2); return true; } @@ -138,26 +138,24 @@ bool OmniPvdStreamContainer::initOmniPvd() static unsigned sizeOfOmniPvdTypes[32]; //create a class for each SDK type and attribute -- the primary thing is to allocate handle storage, the rest is just fluff. -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) OmniPvdClassHandle OmniPvdPxSampler::classHandle_##c; -#define OMNI_PVD_CLASS(c, classT) OmniPvdClassHandle OmniPvdPxSampler::classHandle_##c; -#define OMNI_PVD_ENUM(c, classT) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) OmniPvdAttributeHandle OmniPvdPxSampler::attributeHandle_##c##_##a; +#define OMNI_PVD_CLASS(classT) OmniPvdClassHandle OmniPvdPxSampler::classHandle_##classT; +#define OMNI_PVD_ENUM(classT) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) OmniPvdAttributeHandle OmniPvdPxSampler::attributeHandle_##classT##_##a; //enum values don't need to save their handle, since they are const/immutable: -#define OMNI_PVD_ENUM_VALUE(c, a, v) -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) OmniPvdAttributeHandle OmniPvdPxSampler::attributeHandle_##c##_##a; -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) OmniPvdAttributeHandle OmniPvdPxSampler::attributeHandle_##c##_##a; +#define OMNI_PVD_ENUM_VALUE(classT, a) +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) OmniPvdAttributeHandle OmniPvdPxSampler::attributeHandle_##classT##_##a; +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) OmniPvdAttributeHandle OmniPvdPxSampler::attributeHandle_##classT##_##a; #include "OmniPvdTypes.h" #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST #undef OMNI_PVD_ATTRIBUTE_FLAG void OmniPvdStreamContainer::registerClasses() @@ -166,118 +164,134 @@ void OmniPvdStreamContainer::registerClasses() if (mWriter) { //register all SDK classes and attributes: -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) OmniPvdPxSampler::classHandle_##c = mWriter->registerClass(#classStr); -#define OMNI_PVD_CLASS(c, classT) OmniPvdPxSampler::classHandle_##c = mWriter->registerClass(#classT); -#define OMNI_PVD_ENUM(c, classT) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OmniPvdPxSampler::classHandle_##c = mWriter->registerClass(#classT, OmniPvdPxSampler::classHandle_##baseClass); -#define OMNI_PVD_ENUM_VALUE(c, a, v) mWriter->registerEnumValue(OmniPvdPxSampler::classHandle_##c, #a, v); -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) OmniPvdPxSampler::attributeHandle_##c##_##a = mWriter->registerSetAttribute(OmniPvdPxSampler::classHandle_##c, #a, OmniPvdDataTypeEnum::eOBJECT_HANDLE); -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) PX_ASSERT((n == 0) || (sizeof(attrT) == sizeOfOmniPvdTypes[t] * n)); OmniPvdPxSampler::attributeHandle_##c##_##a = mWriter->registerAttribute(OmniPvdPxSampler::classHandle_##c, #a, t, n); -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) OmniPvdPxSampler::attributeHandle_##c##_##a = mWriter->registerFlagsAttribute(OmniPvdPxSampler::classHandle_##c, OmniPvdPxSampler::classHandle_##enumClass, #a); +#define OMNI_PVD_CLASS(classT) OmniPvdPxSampler::classHandle_##classT = mWriter->registerClass(#classT); +#define OMNI_PVD_ENUM(classT) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OmniPvdPxSampler::classHandle_##classT = mWriter->registerClass(#classT, OmniPvdPxSampler::classHandle_##baseClass); +#define OMNI_PVD_ENUM_VALUE(classT, a) mWriter->registerEnumValue(OmniPvdPxSampler::classHandle_##classT, #a, classT::a); +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) OmniPvdPxSampler::attributeHandle_##classT##_##a = mWriter->registerUniqueListAttribute(OmniPvdPxSampler::classHandle_##classT, #a, OmniPvdDataType::eOBJECT_HANDLE); +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) PX_ASSERT((n == 0) || (sizeof(attrT) == sizeOfOmniPvdTypes[t] * n)); OmniPvdPxSampler::attributeHandle_##classT##_##a = mWriter->registerAttribute(OmniPvdPxSampler::classHandle_##classT, #a, t, n); +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) OmniPvdPxSampler::attributeHandle_##classT##_##a = mWriter->registerFlagsAttribute(OmniPvdPxSampler::classHandle_##classT, #a, OmniPvdPxSampler::classHandle_##enumClassT); #include "OmniPvdTypes.h" #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST #undef OMNI_PVD_ATTRIBUTE_FLAG mClassesRegistered = true; } } - - //instance any templates that are not used in this compilation unit so that code gets generated anyways -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) \ -template void OmniPvdPxSampler::createObject (OmniPvdClassHandle, classT const &);\ -template void OmniPvdPxSampler::destroyObject(classT const &); - -#define OMNI_PVD_CLASS(c, classT) \ +#define OMNI_PVD_CLASS(classT) \ template void OmniPvdPxSampler::createObject (OmniPvdClassHandle, classT const &);\ template void OmniPvdPxSampler::destroyObject(classT const &); -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OMNI_PVD_CLASS(c, classT) +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OMNI_PVD_CLASS(classT) -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) \ -template void OmniPvdPxSampler::addToSet(OmniPvdAttributeHandle, classT const & , attrT const & );\ -template void OmniPvdPxSampler::removeFromSet(OmniPvdAttributeHandle, classT const & , attrT const & ); +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) \ +template void OmniPvdPxSampler::addToUniqueList(OmniPvdAttributeHandle, classT const & , attrT const & );\ +template void OmniPvdPxSampler::removeFromUniqueList(OmniPvdAttributeHandle, classT const & , attrT const & ); -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) \ +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) \ template void OmniPvdPxSampler::setAttribute(OmniPvdAttributeHandle, const classT&, attrT const &); \ template void OmniPvdPxSampler::setAttributeBytes(OmniPvdAttributeHandle, const classT&, attrT const *, unsigned); -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) \ +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) \ template void OmniPvdPxSampler::setAttribute(OmniPvdAttributeHandle, classT const &, attrT const &); -#define OMNI_PVD_ENUM(c, enumT) -#define OMNI_PVD_ENUM_VALUE(c, a, v) +#define OMNI_PVD_ENUM(classT) +#define OMNI_PVD_ENUM_VALUE(classT, a) #include "OmniPvdTypes.h" #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST //end instance templates -void streamActorName(physx::PxActor & a, const char* name) + +int streamStringLength(const char* name) { #if PX_SUPPORT_OMNI_PVD if (NpPhysics::getInstance().mOmniPvdSampler == NULL) { - return; + return 0; } if (name == NULL) { - return; + return 0; } int len = static_cast(strlen(name)); if (len > 0) { - len += 1; - OMNI_PVD_SETB(actor, name, a, name, len); // copies over the trailing zero too + return len; } + else + { + return 0; + } +#else + return 0; #endif } -void streamSphere(const physx::PxGeometry& g) +void streamActorName(physx::PxActor & a, const char* name) { - PxGeometryHolder gh(g); - OMNI_PVD_CREATE(geomsphere, g); - OMNI_PVD_SET(geomsphere, radius, g, gh.sphere().radius); +#if PX_SUPPORT_OMNI_PVD + int strLen = streamStringLength(name); + if (strLen) + { + OMNI_PVD_SETB(PxActor, name, a, name, strLen + 1); // copies over the trailing zero too + } +#endif +} + +void streamSceneName(physx::PxScene & s, const char* name) +{ +#if PX_SUPPORT_OMNI_PVD + int strLen = streamStringLength(name); + if (strLen) + { + OMNI_PVD_SETB(PxScene, name, s, name, strLen + 1); // copies over the trailing zero too + } +#endif } -void streamCapsule(const physx::PxGeometry& g) +void streamSphere(const physx::PxSphereGeometry& g) { - PxGeometryHolder gh(g); - OMNI_PVD_CREATE(geomcapsule, g); - OMNI_PVD_SET(geomcapsule, halfHeight, g, gh.capsule().halfHeight); - OMNI_PVD_SET(geomcapsule, radius, g, gh.capsule().radius); + OMNI_PVD_CREATE(PxSphereGeometry, g); + OMNI_PVD_SET(PxSphereGeometry, radius, g, g.radius); } -void streamBox(const physx::PxGeometry& g) +void streamCapsule(const physx::PxCapsuleGeometry& g) { - PxGeometryHolder gh(g); - OMNI_PVD_CREATE(geombox, g); - OMNI_PVD_SET(geombox, halfExtents, g, gh.box().halfExtents); + OMNI_PVD_CREATE(PxCapsuleGeometry, g); + OMNI_PVD_SET(PxCapsuleGeometry, halfHeight, g, g.halfHeight); + OMNI_PVD_SET(PxCapsuleGeometry, radius, g, g.radius); } -void streamPlane(const physx::PxGeometry& g) +void streamBox(const physx::PxBoxGeometry& g) { - OMNI_PVD_CREATE(geomplane, g); + OMNI_PVD_CREATE(PxBoxGeometry, g); + OMNI_PVD_SET(PxBoxGeometry, halfExtents, g, g.halfExtents); +} + +void streamPlane(const physx::PxPlaneGeometry& g) +{ + OMNI_PVD_CREATE(PxPlaneGeometry, g); } void streamConvexMesh(const physx::PxConvexMesh* mesh) { if (samplerInternals->addSharedMeshIfNotSeen(mesh, OmniPvdSharedMeshEnum::eOmniPvdConvexMesh)) { - OMNI_PVD_CREATE(convexmesh, *mesh); + OMNI_PVD_CREATE(PxConvexMesh, *mesh); const physx::PxU32 nbPolys = mesh->getNbPolygons(); const physx::PxU8* polygons = mesh->getIndexBuffer(); @@ -323,29 +337,27 @@ void streamConvexMesh(const physx::PxConvexMesh* mesh) } } - OMNI_PVD_SETB(convexmesh, verts, *mesh, tmpVerts, sizeof(float) * 3 * nbrVerts); - OMNI_PVD_SETB(convexmesh, tris, *mesh, tmpIndices, sizeof(int) * 3 * totalTris); + OMNI_PVD_SETB(PxConvexMesh, verts, *mesh, tmpVerts, sizeof(float) * 3 * nbrVerts); + OMNI_PVD_SETB(PxConvexMesh, tris, *mesh, tmpIndices, sizeof(int) * 3 * totalTris); PX_FREE(tmpVerts); PX_FREE(tmpIndices); } } -void streamConvexMeshGeometry(const physx::PxGeometry& g) +void streamConvexMeshGeometry(const physx::PxConvexMeshGeometry& g) { - PxGeometryHolder gh(g); - OMNI_PVD_CREATE(geomconvexmesh, g); - OMNI_PVD_SET(geomconvexmesh, scale, g, gh.convexMesh().scale.scale); - const physx::PxConvexMeshGeometry& geometry = gh.convexMesh(); - physx::PxConvexMesh const* mesh = geometry.convexMesh; + OMNI_PVD_CREATE(PxConvexMeshGeometry, g); + OMNI_PVD_SET(PxConvexMeshGeometry, scale, g, g.scale.scale); + physx::PxConvexMesh const* mesh = g.convexMesh; streamConvexMesh(mesh); - OMNI_PVD_SET(geomconvexmesh, convexMesh, g, mesh); + OMNI_PVD_SET(PxConvexMeshGeometry, convexMesh, g, mesh); } void streamHeightField(const physx::PxHeightField* hf) { if (samplerInternals->addSharedMeshIfNotSeen(hf, OmniPvdSharedMeshEnum::eOmniPvdHeightField)) { - OMNI_PVD_CREATE(heightfield, *hf); + OMNI_PVD_CREATE(PxHeightField, *hf); const physx::PxU32 nbCols = hf->getNbColumns(); const physx::PxU32 nbRows = hf->getNbRows(); const physx::PxU32 nbVerts = nbRows * nbCols; @@ -398,57 +410,58 @@ void streamHeightField(const physx::PxHeightField* hf) } } PX_FREE(sampleBuffer); - OMNI_PVD_SETB(heightfield, verts, *hf, tmpVerts, sizeof(float) * 3 * nbVerts); - OMNI_PVD_SETB(heightfield, tris, *hf, tmpIndices, sizeof(int) * 3 * nbFaces); + OMNI_PVD_SETB(PxHeightField, verts, *hf, tmpVerts, sizeof(float) * 3 * nbVerts); + OMNI_PVD_SETB(PxHeightField, tris, *hf, tmpIndices, sizeof(int) * 3 * nbFaces); PX_FREE(tmpVerts); PX_FREE(tmpIndices); } } -void streamHeightFieldGeometry(const physx::PxGeometry& g) +void streamHeightFieldGeometry(const physx::PxHeightFieldGeometry& g) { - PxGeometryHolder gh(g); - OMNI_PVD_CREATE(geomheightfield, g); - const physx::PxHeightFieldGeometry& geometry = gh.heightField(); + OMNI_PVD_CREATE(PxHeightFieldGeometry, g); float vertScale[3]; - vertScale[0] = geometry.rowScale; - vertScale[1] = geometry.heightScale; - vertScale[2] = geometry.columnScale; - OMNI_PVD_SET(geomheightfield, scale, g, vertScale); + vertScale[0] = g.rowScale; + vertScale[1] = g.heightScale; + vertScale[2] = g.columnScale; + OMNI_PVD_SET(PxHeightFieldGeometry, scale, g, vertScale); - physx::PxHeightField const * hf = geometry.heightField; + physx::PxHeightField const * hf = g.heightField; streamHeightField(hf); - OMNI_PVD_SET(geomheightfield, heightField, g, hf); + OMNI_PVD_SET(PxHeightFieldGeometry, heightField, g, hf); +} + +void streamRigidActorTForm(const PxRigidActor &ra) +{ + PxTransform t = ra.getGlobalPose(); + OMNI_PVD_SET(PxRigidActor, translation, ra, t.p); + OMNI_PVD_SET(PxRigidActor, rotation, ra, t.q); } void streamRigidStatic(const physx::PxRigidStatic* rs) { const PxActor& a = *rs; - OMNI_PVD_CREATE(actor, a); - OMNI_PVD_SET(actor, type, a, PxActorType::eRIGID_STATIC); - PxTransform t = rs->getGlobalPose(); - OMNI_PVD_SET(actor, translation, a, t.p); - OMNI_PVD_SET(actor, rotation, a, t.q); + OMNI_PVD_CREATE(PxRigidStatic, a); + OMNI_PVD_SET(PxActor, type, a, PxActorType::eRIGID_STATIC); + streamRigidActorTForm(*rs); } void streamRigidDynamic(const physx::PxRigidDynamic* rd) { const PxActor& a = *rd; - OMNI_PVD_CREATE(actor, a); - OMNI_PVD_SET(actor, type, a, PxActorType::eRIGID_DYNAMIC); - PxTransform t = rd->getGlobalPose(); - OMNI_PVD_SET(actor, translation, a, t.p); - OMNI_PVD_SET(actor, rotation, a, t.q); + OMNI_PVD_CREATE(PxRigidDynamic, a); + OMNI_PVD_SET(PxActor, type, a, PxActorType::eRIGID_DYNAMIC); + streamRigidActorTForm(*rd); //OMNI_PVD_SET(actor, isSleeping, a, rd->isSleeping()); // Seems to throw errors since you cannot call isSleeping before a body is part of a scene - OMNI_PVD_SET(actor, sleepThreshold, a, rd->getSleepThreshold()); - OMNI_PVD_SET(actor, wakeCounter, a, rd->getWakeCounter()); - OMNI_PVD_SET(actor, stabilizationThreshold, a, rd->getStabilizationThreshold()); + OMNI_PVD_SET(PxRigidDynamic, sleepThreshold, a, rd->getSleepThreshold()); + OMNI_PVD_SET(PxRigidDynamic, wakeCounter, a, rd->getWakeCounter()); + OMNI_PVD_SET(PxRigidDynamic, stabilizationThreshold, a, rd->getStabilizationThreshold()); PxU32 positionIters, velocityIters; rd->getSolverIterationCounts(positionIters, velocityIters); - OMNI_PVD_SET(actor, positionIterations, a, positionIters); - OMNI_PVD_SET(actor, velocityIterations, a, velocityIters); - OMNI_PVD_SET(actor, rigidDynamicLockFlags, a, rd->getRigidDynamicLockFlags()); - OMNI_PVD_SET(actor, contactReportThreshold, a, rd->getContactReportThreshold()); + OMNI_PVD_SET(PxRigidDynamic, positionIterations, a, positionIters); + OMNI_PVD_SET(PxRigidDynamic, velocityIterations, a, velocityIters); + OMNI_PVD_SET(PxRigidDynamic, rigidDynamicLockFlags, a, rd->getRigidDynamicLockFlags()); + OMNI_PVD_SET(PxRigidDynamic, contactReportThreshold, a, rd->getContactReportThreshold()); } void streamArticulationJoint(const physx::PxArticulationJointReducedCoordinate* joint) @@ -498,151 +511,196 @@ void streamArticulationJoint(const physx::PxArticulationJointReducedCoordinate* for (PxU32 ax = 0; ax < 6; ++ax) drivevelocitys[ax] = jointRef.getDriveVelocity(static_cast(ax)); - OMNI_PVD_CREATE(articulationjoint, jointRef); - OMNI_PVD_SET(articulationjoint, type, jointRef, jointType); - OMNI_PVD_SET(articulationjoint, parentLink, jointRef, parentPxLinkPtr); - OMNI_PVD_SET(articulationjoint, childLink, jointRef, childPxLinkPtr); - OMNI_PVD_SETB(articulationjoint, motion, jointRef, motions, sizeof(motions)); - OMNI_PVD_SETB(articulationjoint, armature, jointRef, armatures, sizeof(armatures)); - OMNI_PVD_SET(articulationjoint, frictionCoefficient, jointRef, coefficient); - OMNI_PVD_SET(articulationjoint, maxJointVelocity, jointRef, maxJointV); - OMNI_PVD_SETB(articulationjoint, jointPosition, jointRef, positions, sizeof(positions)); - OMNI_PVD_SETB(articulationjoint, jointVelocity, jointRef, velocitys, sizeof(velocitys)); - OMNI_PVD_SETB(articulationjoint, concreteTypeName, jointRef, concreteTypeName, concreteTypeNameLen); - OMNI_PVD_SETB(articulationjoint, limitLow, jointRef, lowlimits, sizeof(lowlimits)); - OMNI_PVD_SETB(articulationjoint, limitHigh, jointRef, highlimits, sizeof(highlimits)); - OMNI_PVD_SETB(articulationjoint, driveStiffness, jointRef, stiffnesss, sizeof(stiffnesss)); - OMNI_PVD_SETB(articulationjoint, driveDamping, jointRef, dampings, sizeof(dampings)); - OMNI_PVD_SETB(articulationjoint, driveMaxForce, jointRef, maxforces, sizeof(maxforces)); - OMNI_PVD_SETB(articulationjoint, driveType, jointRef, drivetypes, sizeof(drivetypes)); - OMNI_PVD_SETB(articulationjoint, driveTarget, jointRef, drivetargets, sizeof(drivetargets)); - OMNI_PVD_SETB(articulationjoint, driveVelocity, jointRef, drivevelocitys, sizeof(drivevelocitys)); + OMNI_PVD_CREATE(PxArticulationJointReducedCoordinate, jointRef); + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, type, jointRef, jointType); + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, parentLink, jointRef, parentPxLinkPtr); + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, childLink, jointRef, childPxLinkPtr); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, motion, jointRef, motions, sizeof(motions)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, armature, jointRef, armatures, sizeof(armatures)); + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, frictionCoefficient, jointRef, coefficient); + OMNI_PVD_SET(PxArticulationJointReducedCoordinate, maxJointVelocity, jointRef, maxJointV); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, jointPosition, jointRef, positions, sizeof(positions)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, jointVelocity, jointRef, velocitys, sizeof(velocitys)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, concreteTypeName, jointRef, concreteTypeName, concreteTypeNameLen); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, limitLow, jointRef, lowlimits, sizeof(lowlimits)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, limitHigh, jointRef, highlimits, sizeof(highlimits)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveStiffness, jointRef, stiffnesss, sizeof(stiffnesss)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveDamping, jointRef, dampings, sizeof(dampings)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveMaxForce, jointRef, maxforces, sizeof(maxforces)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveType, jointRef, drivetypes, sizeof(drivetypes)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveTarget, jointRef, drivetargets, sizeof(drivetargets)); + OMNI_PVD_SETB(PxArticulationJointReducedCoordinate, driveVelocity, jointRef, drivevelocitys, sizeof(drivevelocitys)); } void streamArticulationLink(const physx::PxArticulationLink* al) { const PxActor& a = *al; - OMNI_PVD_CREATE(actor, a); - OMNI_PVD_SET(actor, type, a, PxActorType::eARTICULATION_LINK); - OMNI_PVD_SET(actor, articulation, a, &al->getArticulation()); - OMNI_PVD_SET(actor, CFMScale, a, al->getCfmScale()); - OMNI_PVD_SET(actor, inboundJointDOF, a, al->getInboundJointDof()); + OMNI_PVD_CREATE(PxArticulationLink, a); + OMNI_PVD_SET(PxActor, type, a, PxActorType::eARTICULATION_LINK); + OMNI_PVD_SET(PxArticulationLink, articulation, a, &al->getArticulation()); + OMNI_PVD_SET(PxArticulationLink, CFMScale, a, al->getCfmScale()); + OMNI_PVD_SET(PxArticulationLink, inboundJointDOF, a, al->getInboundJointDof()); } void streamArticulation(const physx::PxArticulationReducedCoordinate* art) { - OMNI_PVD_CREATE(articulation, *art); + OMNI_PVD_CREATE(PxArticulationReducedCoordinate, *art); PxU32 solverIterations[2]; art->getSolverIterationCounts(solverIterations[0], solverIterations[1]); - OMNI_PVD_SET(articulation, positionIterations, *art, solverIterations[0]); - OMNI_PVD_SET(articulation, velocityIterations, *art, solverIterations[1]); - OMNI_PVD_SET(articulation, isSleeping, *art, false); - OMNI_PVD_SET(articulation, sleepThreshold, *art, art->getSleepThreshold()); - OMNI_PVD_SET(articulation, stabilizationThreshold, *art, art->getStabilizationThreshold()); - OMNI_PVD_SET(articulation, wakeCounter, *art, art->getWakeCounter()); - OMNI_PVD_SET(articulation, maxLinVelocity, *art, art->getMaxCOMLinearVelocity()); - OMNI_PVD_SET(articulation, maxAngVelocity, *art, art->getMaxCOMAngularVelocity()); - OMNI_PVD_SET(articulation, worldBounds, *art, art->getWorldBounds()); - OMNI_PVD_SET(articulation, articulationFlags, *art, art->getArticulationFlags()); - OMNI_PVD_SET(articulation, dofs, *art, art->getDofs()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, positionIterations, *art, solverIterations[0]); + OMNI_PVD_SET(PxArticulationReducedCoordinate, velocityIterations, *art, solverIterations[1]); + OMNI_PVD_SET(PxArticulationReducedCoordinate, isSleeping, *art, false); + OMNI_PVD_SET(PxArticulationReducedCoordinate, sleepThreshold, *art, art->getSleepThreshold()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, stabilizationThreshold, *art, art->getStabilizationThreshold()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, wakeCounter, *art, art->getWakeCounter()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, maxLinearVelocity, *art, art->getMaxCOMLinearVelocity()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, maxAngularVelocity, *art, art->getMaxCOMAngularVelocity()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, worldBounds, *art, art->getWorldBounds()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, articulationFlags, *art, art->getArticulationFlags()); + OMNI_PVD_SET(PxArticulationReducedCoordinate, dofs, *art, art->getDofs()); } void streamAggregate(const physx::PxAggregate* agg) { - OMNI_PVD_CREATE(aggregate, *agg); + OMNI_PVD_CREATE(PxAggregate, *agg); PxU32 actorCount = agg->getNbActors(); for (PxU32 i = 0; i < actorCount; ++i) { PxActor* a; agg->getActors(&a, 1, i); - OMNI_PVD_ADD(aggregate, actors, *agg, *a); + OMNI_PVD_ADD(PxAggregate, actors, *agg, *a); } - OMNI_PVD_SET(aggregate, selfCollision, *agg, agg->getSelfCollision()); - OMNI_PVD_SET(aggregate, maxNbShapes, *agg, agg->getMaxNbShapes()); - OMNI_PVD_SET(aggregate, scene, *agg, const_cast(agg)->getScene()); -} - -void streamSoBo(const physx::PxSoftBody* b) -{ - OMNI_PVD_CREATE(actor, *b); // @@@ + OMNI_PVD_SET(PxAggregate, selfCollision, *agg, agg->getSelfCollision()); + OMNI_PVD_SET(PxAggregate, maxNbShapes, *agg, agg->getMaxNbShapes()); + OMNI_PVD_SET(PxAggregate, scene, *agg, const_cast(agg)->getScene()); } void streamMPMMaterial(const physx::PxMPMMaterial* m) { - OMNI_PVD_CREATE(mpmmaterial, *m); + OMNI_PVD_CREATE(PxMPMMaterial, *m); } void streamFLIPMaterial(const physx::PxFLIPMaterial* m) { - OMNI_PVD_CREATE(flipmaterial, *m); + OMNI_PVD_CREATE(PxFLIPMaterial, *m); } void streamPBDMaterial(const physx::PxPBDMaterial* m) { - OMNI_PVD_CREATE(pbdmaterial, *m); + OMNI_PVD_CREATE(PxPBDMaterial, *m); } void streamFEMClothMaterial(const physx::PxFEMClothMaterial* m) { - OMNI_PVD_CREATE(femclothmaterial, *m); + OMNI_PVD_CREATE(PxFEMClothMaterial, *m); } void streamFEMSoBoMaterial(const physx::PxFEMSoftBodyMaterial* m) { - OMNI_PVD_CREATE(femsoftbodymaterial, *m); + OMNI_PVD_CREATE(PxFEMSoftBodyMaterial, *m); } void streamMaterial(const physx::PxMaterial* m) { - OMNI_PVD_CREATE(material, *m); - OMNI_PVD_SET(material, flags, *m, m->getFlags()); - OMNI_PVD_SET(material, frictionCombineMode, *m, m->getFrictionCombineMode()); - OMNI_PVD_SET(material, restitutionCombineMode, *m, m->getRestitutionCombineMode()); - OMNI_PVD_SET(material, staticFriction, *m, m->getStaticFriction()); - OMNI_PVD_SET(material, dynamicFriction, *m, m->getDynamicFriction()); - OMNI_PVD_SET(material, restitution, *m, m->getRestitution()); + OMNI_PVD_CREATE(PxMaterial, *m); + OMNI_PVD_SET(PxMaterial, flags, *m, m->getFlags()); + OMNI_PVD_SET(PxMaterial, frictionCombineMode, *m, m->getFrictionCombineMode()); + OMNI_PVD_SET(PxMaterial, restitutionCombineMode, *m, m->getRestitutionCombineMode()); + OMNI_PVD_SET(PxMaterial, staticFriction, *m, m->getStaticFriction()); + OMNI_PVD_SET(PxMaterial, dynamicFriction, *m, m->getDynamicFriction()); + OMNI_PVD_SET(PxMaterial, restitution, *m, m->getRestitution()); +} + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + OMNI_PVD_SETB(PxShape, materials, *shapePtr, mats, sizeof(PxMaterial*) * nbrMaterials); } -void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxMaterial** mats, physx::PxU32 nbrMaterials) +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFEMClothMaterial* const * mats, physx::PxU32 nbrMaterials) { - OMNI_PVD_SETB(shape, materials, *shapePtr, mats, sizeof(PxMaterial*) * nbrMaterials); + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); } +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFEMMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); +} + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFEMSoftBodyMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); +} + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFLIPMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); +} + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxMPMMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); +} + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxParticleMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); +} + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxPBDMaterial* const * mats, physx::PxU32 nbrMaterials) +{ + PX_UNUSED(shapePtr); + PX_UNUSED(mats); + PX_UNUSED(nbrMaterials); +} + + void streamShape(const physx::PxShape* shape) { - OMNI_PVD_CREATE(shape, *shape); - OMNI_PVD_SET(shape, isExclusive, *shape, shape->isExclusive()); - OMNI_PVD_SET(shape, geom, *shape, &shape->getGeometry()); - OMNI_PVD_SET(shape, contactOffset, *shape, shape->getContactOffset()); - OMNI_PVD_SET(shape, restOffset, *shape, shape->getRestOffset()); - OMNI_PVD_SET(shape, densityForFluid, *shape, shape->getDensityForFluid()); - OMNI_PVD_SET(shape, torsionalPatchRadius, *shape, shape->getTorsionalPatchRadius()); - OMNI_PVD_SET(shape, minTorsionalPatchRadius, *shape, shape->getMinTorsionalPatchRadius()); - OMNI_PVD_SET(shape, shapeFlags, *shape, shape->getFlags()); - OMNI_PVD_SET(shape, simulationFilterData, *shape, shape->getSimulationFilterData()); - OMNI_PVD_SET(shape, queryFilterData, *shape, shape->getQueryFilterData()); + OMNI_PVD_CREATE(PxShape, *shape); + OMNI_PVD_SET(PxShape, isExclusive, *shape, shape->isExclusive()); + OMNI_PVD_SET(PxShape, geom, *shape, &shape->getGeometry()); + OMNI_PVD_SET(PxShape, contactOffset, *shape, shape->getContactOffset()); + OMNI_PVD_SET(PxShape, restOffset, *shape, shape->getRestOffset()); + OMNI_PVD_SET(PxShape, densityForFluid, *shape, shape->getDensityForFluid()); + OMNI_PVD_SET(PxShape, torsionalPatchRadius, *shape, shape->getTorsionalPatchRadius()); + OMNI_PVD_SET(PxShape, minTorsionalPatchRadius, *shape, shape->getMinTorsionalPatchRadius()); + OMNI_PVD_SET(PxShape, shapeFlags, *shape, shape->getFlags()); + OMNI_PVD_SET(PxShape, simulationFilterData, *shape, shape->getSimulationFilterData()); + OMNI_PVD_SET(PxShape, queryFilterData, *shape, shape->getQueryFilterData()); const int nbrMaterials = shape->getNbMaterials(); PxMaterial** tmpMaterials = (PxMaterial**)PX_ALLOC(sizeof(PxMaterial*) * nbrMaterials, "tmpMaterials"); physx::PxU32 nbrMats = shape->getMaterials(tmpMaterials, nbrMaterials); - streamShapeMaterials((PxShape*)shape, tmpMaterials, nbrMats); + streamShapeMaterials(const_cast(shape), tmpMaterials, nbrMats); PX_FREE(tmpMaterials); } void streamBVH(const physx::PxBVH* bvh) { - OMNI_PVD_CREATE(bvh, *bvh); + OMNI_PVD_CREATE(PxBVH, *bvh); } void streamSoBoMesh(const physx::PxSoftBodyMesh* mesh) { - OMNI_PVD_CREATE(softbodymesh, *mesh); - OMNI_PVD_SET(softbodymesh, collisionMesh, *mesh, mesh->getCollisionMesh()); - OMNI_PVD_SET(softbodymesh, simulationMesh, *mesh, mesh->getSimulationMesh()); + OMNI_PVD_CREATE(PxSoftBodyMesh, *mesh); + OMNI_PVD_SET(PxSoftBodyMesh, collisionMesh, *mesh, mesh->getCollisionMesh()); + OMNI_PVD_SET(PxSoftBodyMesh, simulationMesh, *mesh, mesh->getSimulationMesh()); } void streamTetMesh(const physx::PxTetrahedronMesh* mesh) { - OMNI_PVD_CREATE(tetrahedronmesh, *mesh); + OMNI_PVD_CREATE(PxTetrahedronMesh, *mesh); //this gets done at the bottom now const physx::PxU32 tetrahedronCount = mesh->getNbTetrahedrons(); const physx::PxU32 has16BitIndices = mesh->getTetrahedronMeshFlags() & physx::PxTetrahedronMeshFlag::e16_BIT_INDICES; @@ -678,8 +736,8 @@ void streamTetMesh(const physx::PxTetrahedronMesh* mesh) tmpIndices[i] = intIndices[i]; } } - OMNI_PVD_SETB(tetrahedronmesh, verts, *mesh, tmpVerts, sizeof(float) * 3 * nbrVerts); - OMNI_PVD_SETB(tetrahedronmesh, tets, *mesh, tmpIndices, sizeof(int) * 4 * nbrTets); + OMNI_PVD_SETB(PxTetrahedronMesh, verts, *mesh, tmpVerts, sizeof(float) * 3 * nbrVerts); + OMNI_PVD_SETB(PxTetrahedronMesh, tets, *mesh, tmpIndices, sizeof(int) * 4 * nbrTets); PX_FREE(tmpVerts); PX_FREE(tmpIndices); } @@ -688,7 +746,7 @@ void streamTriMesh(const physx::PxTriangleMesh* mesh) { if (samplerInternals->addSharedMeshIfNotSeen(mesh, OmniPvdSharedMeshEnum::eOmniPvdTriMesh)) { - OMNI_PVD_CREATE(trianglemesh, *mesh); + OMNI_PVD_CREATE(PxTriangleMesh, *mesh); //this gets done at the bottom now const physx::PxU32 triangleCount = mesh->getNbTriangles(); const physx::PxU32 has16BitIndices = mesh->getTriangleMeshFlags() & physx::PxTriangleMeshFlag::e16_BIT_INDICES; @@ -724,22 +782,20 @@ void streamTriMesh(const physx::PxTriangleMesh* mesh) tmpIndices[i] = intIndices[i]; } } - OMNI_PVD_SETB(trianglemesh, verts, *mesh, tmpVerts, sizeof(float) * 3 * nbrVerts); - OMNI_PVD_SETB(trianglemesh, tris, *mesh, tmpIndices, sizeof(int) * 3 * nbrTris); + OMNI_PVD_SETB(PxTriangleMesh, verts, *mesh, tmpVerts, sizeof(float) * 3 * nbrVerts); + OMNI_PVD_SETB(PxTriangleMesh, tris, *mesh, tmpIndices, sizeof(int) * 3 * nbrTris); PX_FREE(tmpVerts); PX_FREE(tmpIndices); } } -void streamTriMeshGeometry(const physx::PxGeometry& g) +void streamTriMeshGeometry(const physx::PxTriangleMeshGeometry& g) { - PxGeometryHolder gh(g); - OMNI_PVD_CREATE(geomtrianglemesh, g); - const physx::PxTriangleMeshGeometry& geometry = gh.triangleMesh(); - physx::PxTriangleMesh const * mesh = geometry.triangleMesh; - OMNI_PVD_SET(geomtrianglemesh, scale, g, geometry.scale.scale); + OMNI_PVD_CREATE(PxTriangleMeshGeometry, g); + physx::PxTriangleMesh const * mesh = g.triangleMesh; + OMNI_PVD_SET(PxTriangleMeshGeometry, scale, g, g.scale.scale); streamTriMesh(mesh); - OMNI_PVD_SET(geomtrianglemesh, triangleMesh, g, mesh); + OMNI_PVD_SET(PxTriangleMeshGeometry, triangleMesh, g, mesh); } void OmniPvdPxSampler::streamSceneContacts(physx::NpScene& scene) @@ -769,7 +825,7 @@ void OmniPvdPxSampler::streamSceneContacts(physx::NpScene& scene) pairsActors.pushBack(pair->getActor0()); pairsActors.pushBack(pair->getActor1()); ++pairCount; - firstContact = false; + firstContact = false; } ++pairContactCount; pairsContactPoints.pushBack(contact->point); @@ -788,28 +844,28 @@ void OmniPvdPxSampler::streamSceneContacts(physx::NpScene& scene) if (pairCount == 0) return; - OMNI_PVD_SET(scene, pairCount, scene, pairCount); + OMNI_PVD_SET(PxScene, pairCount, scene, pairCount); PxU32 actorsSize = pairsActors.size() * sizeof(PxActor*); PxActor** actors = actorsSize ? &pairsActors[0] : NULL; - OMNI_PVD_SETB(scene, pairsActors, scene, actors, actorsSize); + OMNI_PVD_SETB(PxScene, pairsActors, scene, actors, actorsSize); PxU32 contactCountsSize = pairsContactCounts.size() * sizeof(PxU32); PxU32* contactCounts = contactCountsSize ? &pairsContactCounts[0] : NULL; - OMNI_PVD_SETB(scene, pairsContactCounts, scene, contactCounts, contactCountsSize); + OMNI_PVD_SETB(PxScene, pairsContactCounts, scene, contactCounts, contactCountsSize); PxU32 contactPointsSize = pairsContactPoints.size() * sizeof(PxVec3); PxReal* contactPoints = contactPointsSize ? &pairsContactPoints[0].x : NULL; - OMNI_PVD_SETB(scene, pairsContactPoints, scene, contactPoints, contactPointsSize); + OMNI_PVD_SETB(PxScene, pairsContactPoints, scene, contactPoints, contactPointsSize); PxU32 contactNormalsSize = pairsContactNormals.size() * sizeof(PxVec3); PxReal* contactNormals = contactNormalsSize ? &pairsContactNormals[0].x : NULL; - OMNI_PVD_SETB(scene, pairsContactNormals, scene, contactNormals, contactNormalsSize); + OMNI_PVD_SETB(PxScene, pairsContactNormals, scene, contactNormals, contactNormalsSize); PxU32 contactSeparationsSize = pairsContactSeparations.size() * sizeof(PxReal); PxReal* contactSeparations = contactSeparationsSize ? &pairsContactSeparations[0] : NULL; - OMNI_PVD_SETB(scene, pairsContactSeparations, scene, contactSeparations, contactSeparationsSize); + OMNI_PVD_SETB(PxScene, pairsContactSeparations, scene, contactSeparations, contactSeparationsSize); PxU32 contactShapesSize = pairsContactShapes.size() * sizeof(PxShape*); PxShape** contactShapes = contactShapesSize ? &pairsContactShapes[0] : NULL; - OMNI_PVD_SETB(scene, pairsContactShapes, scene, contactShapes, contactShapesSize); + OMNI_PVD_SETB(PxScene, pairsContactShapes, scene, contactShapes, contactShapesSize); PxU32 contactFacesIndicesSize = pairsContactFacesIndices.size() * sizeof(PxU32); PxU32* contactFacesIndices = contactFacesIndicesSize ? &pairsContactFacesIndices[0] : NULL; - OMNI_PVD_SETB(scene, pairsContactFacesIndices, scene, contactFacesIndices, contactFacesIndicesSize); + OMNI_PVD_SETB(PxScene, pairsContactFacesIndices, scene, contactFacesIndices, contactFacesIndicesSize); } OmniPvdPxSampler::OmniPvdPxSampler() @@ -820,18 +876,18 @@ OmniPvdPxSampler::OmniPvdPxSampler() samplerInternals->mIsSampling = false; //TODO: this could be done better - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT8] = 1; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT16] = 2; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT32] = 4; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT64] = 8; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT8] = 1; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT16] = 2; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT32] = 4; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT64] = 8; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eFLOAT32] = 4; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eFLOAT64] = 8; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eSTRING] = 1; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eOBJECT_HANDLE] = sizeof(uint64_t); + sizeOfOmniPvdTypes[OmniPvdDataType::eINT8] = 1; + sizeOfOmniPvdTypes[OmniPvdDataType::eINT16] = 2; + sizeOfOmniPvdTypes[OmniPvdDataType::eINT32] = 4; + sizeOfOmniPvdTypes[OmniPvdDataType::eINT64] = 8; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT8] = 1; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT16] = 2; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT32] = 4; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT64] = 8; + sizeOfOmniPvdTypes[OmniPvdDataType::eFLOAT32] = 4; + sizeOfOmniPvdTypes[OmniPvdDataType::eFLOAT64] = 8; + sizeOfOmniPvdTypes[OmniPvdDataType::eSTRING] = 1; + sizeOfOmniPvdTypes[OmniPvdDataType::eOBJECT_HANDLE] = sizeof(uint64_t); } OmniPvdPxSampler::~OmniPvdPxSampler() @@ -878,37 +934,37 @@ void createGeometry(const physx::PxGeometry & pxGeom) { case physx::PxGeometryType::eSPHERE: { - streamSphere(pxGeom); + streamSphere((const physx::PxSphereGeometry &)pxGeom); } break; case physx::PxGeometryType::eCAPSULE: { - streamCapsule(pxGeom); + streamCapsule((const physx::PxCapsuleGeometry &)pxGeom); } break; case physx::PxGeometryType::eBOX: { - streamBox(pxGeom); + streamBox((const physx::PxBoxGeometry &)pxGeom); } break; case physx::PxGeometryType::eTRIANGLEMESH: { - streamTriMeshGeometry(pxGeom); + streamTriMeshGeometry((const physx::PxTriangleMeshGeometry &)pxGeom); } break; case physx::PxGeometryType::eCONVEXMESH: { - streamConvexMeshGeometry(pxGeom); + streamConvexMeshGeometry((const physx::PxConvexMeshGeometry &)pxGeom); } break; case physx::PxGeometryType::eHEIGHTFIELD: { - streamHeightFieldGeometry(pxGeom); + streamHeightFieldGeometry((const physx::PxHeightFieldGeometry &)pxGeom); } break; case physx::PxGeometryType::ePLANE: { - streamPlane(pxGeom); + streamPlane((const physx::PxPlaneGeometry &)pxGeom); } break; default: @@ -923,37 +979,37 @@ void destroyGeometry(const physx::PxGeometry & pxGeom) { case physx::PxGeometryType::eSPHERE: { - OMNI_PVD_DESTROY(geomsphere, pxGeom); + OMNI_PVD_DESTROY(PxGeomSphere, pxGeom); } break; case physx::PxGeometryType::eCAPSULE: { - OMNI_PVD_DESTROY(geomcapsule, pxGeom); + OMNI_PVD_DESTROY(PxGeomCapsule, pxGeom); } break; case physx::PxGeometryType::eBOX: { - OMNI_PVD_DESTROY(geombox, pxGeom); + OMNI_PVD_DESTROY(PxGeomBox, pxGeom); } break; case physx::PxGeometryType::eTRIANGLEMESH: { - OMNI_PVD_DESTROY(geomtrianglemesh, pxGeom); + OMNI_PVD_DESTROY(PxGeomTriangleMesh, pxGeom); } break; case physx::PxGeometryType::eCONVEXMESH: { - OMNI_PVD_DESTROY(geomconvexmesh, pxGeom); + OMNI_PVD_DESTROY(PxGeomConvexMesh, pxGeom); } break; case physx::PxGeometryType::eHEIGHTFIELD: { - OMNI_PVD_DESTROY(geomheightfield, pxGeom); + OMNI_PVD_DESTROY(PxGeomHeightField, pxGeom); } break; case physx::PxGeometryType::ePLANE: { - OMNI_PVD_DESTROY(geomplane, pxGeom); + OMNI_PVD_DESTROY(PxGeomPlane, pxGeom); } break; default: @@ -978,84 +1034,80 @@ void OmniPvdPxSampler::onObjectAdd(const physx::PxBase* object) { case physx::PxConcreteType::eHEIGHTFIELD: streamHeightField(static_cast(object)); - OMNI_PVD_ADD(physics, heightFields, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, heightFields, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eCONVEX_MESH: streamConvexMesh(static_cast(object)); - OMNI_PVD_ADD(physics, convexMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, convexMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eTRIANGLE_MESH_BVH33: case physx::PxConcreteType::eTRIANGLE_MESH_BVH34: streamTriMesh(static_cast(object)); - OMNI_PVD_ADD(physics, triangleMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, triangleMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eTETRAHEDRON_MESH: streamTetMesh(static_cast(object)); - OMNI_PVD_ADD(physics, tetrahedronMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, tetrahedronMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eSOFTBODY_MESH: streamSoBoMesh(static_cast(object)); - OMNI_PVD_ADD(physics, softBodyMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, softBodyMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eBVH: streamBVH(static_cast(object)); - OMNI_PVD_ADD(physics, bvhs, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, bvhs, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eSHAPE: createGeometry(static_cast(object)->getGeometry()); streamShape(static_cast(object)); - OMNI_PVD_ADD(physics, shapes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, shapes, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eMATERIAL: streamMaterial(static_cast(object)); - OMNI_PVD_ADD(physics, materials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, materials, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eSOFTBODY_MATERIAL: streamFEMSoBoMaterial(static_cast(object)); - OMNI_PVD_ADD(physics, FEMSoftBodyMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, FEMSoftBodyMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eCLOTH_MATERIAL: streamFEMClothMaterial(static_cast(object)); - OMNI_PVD_ADD(physics, FEMClothMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, FEMClothMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::ePBD_MATERIAL: streamPBDMaterial(static_cast(object)); - OMNI_PVD_ADD(physics, PBDMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, PBDMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eFLIP_MATERIAL: streamFLIPMaterial(static_cast(object)); - OMNI_PVD_ADD(physics, FLIPMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, FLIPMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eMPM_MATERIAL: streamMPMMaterial(static_cast(object)); - OMNI_PVD_ADD(physics, MPMMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - break; - case physx::PxConcreteType::eSOFT_BODY: - streamSoBo(static_cast(object)); - OMNI_PVD_ADD(physics, softBodies, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, MPMMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eAGGREGATE: streamAggregate(static_cast(object)); - OMNI_PVD_ADD(physics, aggregates, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, aggregates, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eARTICULATION_REDUCED_COORDINATE: streamArticulation(static_cast(object)); - OMNI_PVD_ADD(physics, articulations, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, articulations, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eARTICULATION_LINK: streamArticulationLink(static_cast(object)); - OMNI_PVD_ADD(articulation, links, static_cast(object)->getArticulation(), static_cast(*object)); + OMNI_PVD_ADD(PxArticulationReducedCoordinate, links, static_cast(object)->getArticulation(), static_cast(*object)); break; case physx::PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE: streamArticulationJoint(static_cast(object)); break; case physx::PxConcreteType::eRIGID_DYNAMIC: streamRigidDynamic(static_cast(object)); - OMNI_PVD_ADD(physics, rigidDynamics, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, rigidDynamics, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; case physx::PxConcreteType::eRIGID_STATIC: streamRigidStatic(static_cast(object)); - OMNI_PVD_ADD(physics, rigidStatics, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_ADD(PxPhysics, rigidStatics, static_cast(NpPhysics::getInstance()), static_cast(*object)); break; } } @@ -1066,84 +1118,80 @@ void OmniPvdPxSampler::onObjectRemove(const physx::PxBase* object) switch (object->getConcreteType()) { case physx::PxConcreteType::eHEIGHTFIELD: - OMNI_PVD_REMOVE(physics, heightFields, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(heightfield, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, heightFields, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxHeightField, static_cast(*object)); break; case physx::PxConcreteType::eCONVEX_MESH: - OMNI_PVD_REMOVE(physics, convexMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(convexmesh, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, convexMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxConvexMesh, static_cast(*object)); break; case physx::PxConcreteType::eTRIANGLE_MESH_BVH33: case physx::PxConcreteType::eTRIANGLE_MESH_BVH34: - OMNI_PVD_REMOVE(physics, triangleMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(trianglemesh, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, triangleMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxTriangleMesh, static_cast(*object)); break; case physx::PxConcreteType::eTETRAHEDRON_MESH: - OMNI_PVD_REMOVE(physics, tetrahedronMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(tetrahedronmesh, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, tetrahedronMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxTetrahedronMesh, static_cast(*object)); break; case physx::PxConcreteType::eSOFTBODY_MESH: - OMNI_PVD_REMOVE(physics, softBodyMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(softbodymesh, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, softBodyMeshes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxSoftBodyMesh, static_cast(*object)); break; case physx::PxConcreteType::eBVH: - OMNI_PVD_REMOVE(physics, bvhs, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(bvh, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, bvhs, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxBVH, static_cast(*object)); break; case physx::PxConcreteType::eSHAPE: - OMNI_PVD_REMOVE(physics, shapes, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(shape, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, shapes, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxShape, static_cast(*object)); destroyGeometry(static_cast(*object).getGeometry()); break; case physx::PxConcreteType::eMATERIAL: - OMNI_PVD_REMOVE(physics, materials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(material, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, materials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxMaterial, static_cast(*object)); break; case physx::PxConcreteType::eSOFTBODY_MATERIAL: - OMNI_PVD_REMOVE(physics, FEMSoftBodyMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(femsoftbodymaterial, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, FEMSoftBodyMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxFEMSoftBodyMaterial, static_cast(*object)); break; case physx::PxConcreteType::eCLOTH_MATERIAL: - OMNI_PVD_REMOVE(physics, FEMClothMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(femclothmaterial, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, FEMClothMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxFEMClothMaterial, static_cast(*object)); break; case physx::PxConcreteType::ePBD_MATERIAL: - OMNI_PVD_REMOVE(physics, PBDMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(pbdmaterial, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, PBDMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxPBDMaterial, static_cast(*object)); break; case physx::PxConcreteType::eFLIP_MATERIAL: - OMNI_PVD_REMOVE(physics, FLIPMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(flipmaterial, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, FLIPMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxFLIPMaterial, static_cast(*object)); break; case physx::PxConcreteType::eMPM_MATERIAL: - OMNI_PVD_REMOVE(physics, MPMMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(mpmmaterial, static_cast(*object)); - break; - case physx::PxConcreteType::eSOFT_BODY: - OMNI_PVD_REMOVE(physics, softBodies, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(actor, static_cast(*object)); // @@@ + OMNI_PVD_REMOVE(PxPhysics, MPMMaterials, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxMPMMaterial, static_cast(*object)); break; case physx::PxConcreteType::eAGGREGATE: - OMNI_PVD_REMOVE(physics, aggregates, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(aggregate, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, aggregates, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxAggregate, static_cast(*object)); break; case physx::PxConcreteType::eARTICULATION_REDUCED_COORDINATE: - OMNI_PVD_REMOVE(physics, articulations, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(articulation, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, articulations, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxArticulationReducedCoordinate, static_cast(*object)); break; case physx::PxConcreteType::eARTICULATION_LINK: - OMNI_PVD_DESTROY(actor, static_cast(*object)); + OMNI_PVD_DESTROY(PxActor, static_cast(*object)); break; case physx::PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE: - OMNI_PVD_DESTROY(articulationjoint, static_cast(*object)); + OMNI_PVD_DESTROY(PxArticulationJointReducedCoordinate, static_cast(*object)); break; case physx::PxConcreteType::eRIGID_DYNAMIC: - OMNI_PVD_REMOVE(physics, rigidDynamics, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(actor, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, rigidDynamics, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxActor, static_cast(*object)); break; case physx::PxConcreteType::eRIGID_STATIC: - OMNI_PVD_REMOVE(physics, rigidStatics, static_cast(NpPhysics::getInstance()), static_cast(*object)); - OMNI_PVD_DESTROY(actor, static_cast(*object)); + OMNI_PVD_REMOVE(PxPhysics, rigidStatics, static_cast(NpPhysics::getInstance()), static_cast(*object)); + OMNI_PVD_DESTROY(PxActor, static_cast(*object)); break; } } @@ -1195,24 +1243,24 @@ template void OmniPvdPxSampler::destroyObject(ClassType con template void OmniPvdPxSampler::setAttribute(OmniPvdAttributeHandle ah, const ClassType & objectId, const AttributeType & value) { - samplerInternals->mPvdStream.mWriter->setAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&value, sizeof(AttributeType)); + samplerInternals->mPvdStream.mWriter->setAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&value, sizeof(AttributeType)); } template void OmniPvdPxSampler::setAttributeBytes(OmniPvdAttributeHandle ah, ClassType const & objectId, const AttributeType * value, unsigned nBytes) { - samplerInternals->mPvdStream.mWriter->setAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)value, nBytes); + samplerInternals->mPvdStream.mWriter->setAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)value, nBytes); } -template void OmniPvdPxSampler::addToSet(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) +template void OmniPvdPxSampler::addToUniqueList(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) { const AttributeType * atp = &value; - samplerInternals->mPvdStream.mWriter->addToSetAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp)); + samplerInternals->mPvdStream.mWriter->addToUniqueListAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp)); } -template void OmniPvdPxSampler::removeFromSet(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) +template void OmniPvdPxSampler::removeFromUniqueList(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) { const AttributeType * atp = &value; - samplerInternals->mPvdStream.mWriter->removeFromSetAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp) ); + samplerInternals->mPvdStream.mWriter->removeFromUniqueListAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp) ); } /////////////////////////////////////////////////////////////////////////////// diff --git a/physx/source/physx/src/omnipvd/OmniPvdPxSampler.h b/physx/source/physx/src/omnipvd/OmniPvdPxSampler.h index 25c219bb7..e4d103a36 100644 --- a/physx/source/physx/src/omnipvd/OmniPvdPxSampler.h +++ b/physx/source/physx/src/omnipvd/OmniPvdPxSampler.h @@ -40,30 +40,92 @@ The below helper macros are to be used in SDK code to send information to PVD as Even if the code works by passing in different equivalent pointer types, this will generate unnecessary duplicate template code. */ #if PX_SUPPORT_OMNI_PVD + // You can use this in conditional statements to check for a connection #define OMNI_PVD_ACTIVE (::OmniPvdPxSampler::getInstance() != NULL) -// Create object reference o of PVD type c. Example: OMNI_PVD_CREATE(scene, static_cast(*npScene)); - #define OMNI_PVD_CREATE(c, o) if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->createObject(OmniPvdPxSampler::classHandle_##c, o); } -// Destroy object reference o of PVD type c. Example: OMNI_PVD_DESTROY(scene, static_cast(*npScene)); - #define OMNI_PVD_DESTROY(c, o) if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->destroyObject(o); } -// Set PVD attribute a of object reference o of PVD type c to value v. v is passed as reference to value; PVD object handles are passed as reference to POINTER here! -// Example: OMNI_PVD_SET(actor, isdynamic, a, false) - #define OMNI_PVD_SET(c, a, o, v) if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->setAttribute(OmniPvdPxSampler::attributeHandle_##c##_##a, o, v); } + +// Create object reference o of PVD type classT. Example: OMNI_PVD_CREATE(scene, static_cast(*npScene)); +#if PX_GCC_FAMILY + #define OMNI_PVD_CREATE(classT, o) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->createObject(OmniPvdPxSampler::classHandle_##classT, o); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_CREATE(classT, o) \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->createObject(OmniPvdPxSampler::classHandle_##classT, o); } +#endif + +// Destroy object reference o of PVD type classT. Example: OMNI_PVD_DESTROY(scene, static_cast(*npScene)); +#if PX_GCC_FAMILY + #define OMNI_PVD_DESTROY(classT, o) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->destroyObject(o); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_DESTROY(classT, o) \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->destroyObject(o); } +#endif + +// Set PVD attribute a of object reference o of PVD type classT to value v. v is passed as reference to value; PVD object handles are passed as reference to POINTER here! +// Example: OMNI_PVD_SET(PxActor, isdynamic, a, false) +#if PX_GCC_FAMILY + #define OMNI_PVD_SET(classT, a, o, v) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->setAttribute(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, v); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_SET(classT, a, o, v) \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->setAttribute(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, v); } +#endif + // Same as set, but for variable length attributes like vertex buffers. pv is the address of the data, and n is the size in bytes. - #define OMNI_PVD_SETB(c, a, o, pv, n)if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->setAttributeBytes(OmniPvdPxSampler::attributeHandle_##c##_##a, o, pv, n); } +#if PX_GCC_FAMILY + #define OMNI_PVD_SETB(classT, a, o, pv, n) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->setAttributeBytes(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, pv, n); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_SETB(classT, a, o, pv, n) \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->setAttributeBytes(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, pv, n); } +#endif + // Same as set, but for attribute sets of unique things like an array of references. v is passed as a REFERENCE. - #define OMNI_PVD_ADD(c, a, o, v) if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->addToSet(OmniPvdPxSampler::attributeHandle_##c##_##a, o, v); } +#if PX_GCC_FAMILY + #define OMNI_PVD_ADD(classT, a, o, v) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->addToUniqueList(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, v); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_ADD(classT, a, o, v) \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->addToUniqueList(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, v); } +#endif + // TO remove a member handle from the set. - #define OMNI_PVD_REMOVE(c, a, o, v) if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->removeFromSet(OmniPvdPxSampler::attributeHandle_##c##_##a, o, v); } +#if PX_GCC_FAMILY + #define OMNI_PVD_REMOVE(classT, a, o, v) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->removeFromUniqueList(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, v); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_REMOVE(classT, a, o, v) \ + if (::OmniPvdPxSampler::getInstance() != NULL) {::OmniPvdPxSampler::getInstance()->removeFromUniqueList(OmniPvdPxSampler::attributeHandle_##classT##_##a, o, v); } +#endif + #else #define OMNI_PVD_ACTIVE (false) - #define OMNI_PVD_CREATE(c, p) - #define OMNI_PVD_DESTROY(c, p) - #define OMNI_PVD_SET(c, a, p, v) - #define OMNI_PVD_SETB(c, a, p, v, n) - #define OMNI_PVD_ADD(c, a, p, v) - #define OMNI_PVD_REMOVE(c, a, p, v) + #define OMNI_PVD_CREATE(classT, p) + #define OMNI_PVD_DESTROY(classT, p) + #define OMNI_PVD_SET(classT, a, p, v) + #define OMNI_PVD_SETB(classT, a, p, v, n) + #define OMNI_PVD_ADD(classT, a, p, v) + #define OMNI_PVD_REMOVE(classT, a, p, v) #endif @@ -93,10 +155,29 @@ namespace physx class PxJoint; class PxShape; class PxMaterial; + + class PxFEMClothMaterial; + class PxFEMMaterial; + class PxFEMSoftBodyMaterial; + class PxFLIPMaterial; + class PxMPMMaterial; + class PxParticleMaterial; + class PxPBDMaterial; } extern void streamActorName(physx::PxActor & a, const char* name); -extern void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxMaterial** mats, physx::PxU32 nbrMaterials); +extern void streamSceneName(physx::PxScene & s, const char* name); + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxMaterial* const * mats, physx::PxU32 nbrMaterials); + +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFEMClothMaterial* const * mats, physx::PxU32 nbrMaterials); +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFEMMaterial* const * mats, physx::PxU32 nbrMaterials); +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFEMSoftBodyMaterial* const * mats, physx::PxU32 nbrMaterials); +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxFLIPMaterial* const * mats, physx::PxU32 nbrMaterials); +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxMPMMaterial* const * mats, physx::PxU32 nbrMaterials); +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxParticleMaterial* const * mats, physx::PxU32 nbrMaterials); +void streamShapeMaterials(physx::PxShape* shapePtr, physx::PxPBDMaterial* const * mats, physx::PxU32 nbrMaterials); + enum OmniPvdSharedMeshEnum { eOmniPvdTriMesh = 0, @@ -137,29 +218,27 @@ class OmniPvdPxSampler : public physx::PxUserAllocated template void destroyObject(ClassType const & objectId); template void setAttribute(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); template void setAttributeBytes(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const * value, unsigned nBytes); - template void addToSet(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); - template void removeFromSet(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); + template void addToUniqueList(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); + template void removeFromUniqueList(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); //handles for all SDK classes and attributes -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) static OmniPvdClassHandle classHandle_##c; -#define OMNI_PVD_CLASS(c, classT) static OmniPvdClassHandle classHandle_##c; -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_ENUM(c, classT) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_ENUM_VALUE(c, a, v) -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) static OmniPvdAttributeHandle attributeHandle_##c##_##a; -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) static OmniPvdAttributeHandle attributeHandle_##c##_##a; -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) static OmniPvdAttributeHandle attributeHandle_##c##_##a; +#define OMNI_PVD_CLASS(classT) static OmniPvdClassHandle classHandle_##classT; +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_ENUM(classT) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_ENUM_VALUE(classT, a) +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) static OmniPvdAttributeHandle attributeHandle_##classT##_##a; +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) static OmniPvdAttributeHandle attributeHandle_##classT##_##a; +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) static OmniPvdAttributeHandle attributeHandle_##classT##_##a; #include "OmniPvdTypes.h" //SDK classes and attributes declared here #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST #undef OMNI_PVD_ATTRIBUTE_FLAG static OmniPvdPxSampler* getInstance(); diff --git a/physx/source/physx/src/omnipvd/OmniPvdTypes.h b/physx/source/physx/src/omnipvd/OmniPvdTypes.h index 0106faaa8..7b87cfcdf 100644 --- a/physx/source/physx/src/omnipvd/OmniPvdTypes.h +++ b/physx/source/physx/src/omnipvd/OmniPvdTypes.h @@ -30,468 +30,511 @@ // The last two attribute parameters could now be derived from the other data, so could be removed in a refactor, // though explicit control may be better. // Note that HANDLE attributes have to use (Type const *) style, otherwise it won't compile! -// Note also that if we update the PVD USD reader code to not need different names than we use in the source code we don't need to pass both e.g. "scene" and "PxScene" and we can simplify - //////////////////////////////////////////////////////////////////////////////// // Bitfields //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_ENUM (sceneflag, PxSceneFlag) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_ACTIVE_ACTORS, PxSceneFlag::eENABLE_ACTIVE_ACTORS) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_CCD, PxSceneFlag::eENABLE_CCD) -OMNI_PVD_ENUM_VALUE (sceneflag, eDISABLE_CCD_RESWEEP, PxSceneFlag::eDISABLE_CCD_RESWEEP) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_PCM, PxSceneFlag::eENABLE_PCM) -OMNI_PVD_ENUM_VALUE (sceneflag, eDISABLE_CONTACT_REPORT_BUFFER_RESIZE, PxSceneFlag::eDISABLE_CONTACT_REPORT_BUFFER_RESIZE) -OMNI_PVD_ENUM_VALUE (sceneflag, eDISABLE_CONTACT_CACHE, PxSceneFlag::eDISABLE_CONTACT_CACHE) -OMNI_PVD_ENUM_VALUE (sceneflag, eREQUIRE_RW_LOCK, PxSceneFlag::eREQUIRE_RW_LOCK) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_STABILIZATION, PxSceneFlag::eENABLE_STABILIZATION) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_AVERAGE_POINT, PxSceneFlag::eENABLE_AVERAGE_POINT) -OMNI_PVD_ENUM_VALUE (sceneflag, eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS, PxSceneFlag::eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_GPU_DYNAMICS, PxSceneFlag::eENABLE_GPU_DYNAMICS) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_ENHANCED_DETERMINISM, PxSceneFlag::eENABLE_ENHANCED_DETERMINISM) -OMNI_PVD_ENUM_VALUE (sceneflag, eENABLE_FRICTION_EVERY_ITERATION, PxSceneFlag::eENABLE_FRICTION_EVERY_ITERATION) -OMNI_PVD_ENUM_VALUE (sceneflag, eSUPPRESS_READBACK, PxSceneFlag::eSUPPRESS_READBACK) -OMNI_PVD_ENUM_VALUE (sceneflag, eFORCE_READBACK, PxSceneFlag::eFORCE_READBACK) - -OMNI_PVD_ENUM (materialflag, PxMaterialFlag) -OMNI_PVD_ENUM_VALUE (materialflag, eDISABLE_FRICTION, PxMaterialFlag::eDISABLE_FRICTION) -OMNI_PVD_ENUM_VALUE (materialflag, eDISABLE_STRONG_FRICTION,PxMaterialFlag::eDISABLE_STRONG_FRICTION) -OMNI_PVD_ENUM_VALUE (materialflag, eIMPROVED_PATCH_FRICTION,PxMaterialFlag::eIMPROVED_PATCH_FRICTION) - -OMNI_PVD_ENUM (actorflag, PxActorFlag) -OMNI_PVD_ENUM_VALUE (actorflag, eVISUALIZATION, PxActorFlag::eVISUALIZATION) -OMNI_PVD_ENUM_VALUE (actorflag, eDISABLE_GRAVITY, PxActorFlag::eDISABLE_GRAVITY) -OMNI_PVD_ENUM_VALUE (actorflag, eSEND_SLEEP_NOTIFIES, PxActorFlag::eSEND_SLEEP_NOTIFIES) -OMNI_PVD_ENUM_VALUE (actorflag, eDISABLE_SIMULATION, PxActorFlag::eDISABLE_SIMULATION) - -OMNI_PVD_ENUM (rigidbodyflag, PxRigidBodyFlag) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eKINEMATIC, PxRigidBodyFlag::eKINEMATIC) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES, PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eENABLE_CCD, PxRigidBodyFlag::eENABLE_CCD) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eENABLE_CCD_FRICTION, PxRigidBodyFlag::eENABLE_CCD_FRICTION) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eENABLE_POSE_INTEGRATION_PREVIEW, PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eENABLE_SPECULATIVE_CCD, PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eENABLE_CCD_MAX_CONTACT_IMPULSE, PxRigidBodyFlag::eENABLE_CCD_MAX_CONTACT_IMPULSE) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eRETAIN_ACCELERATIONS, PxRigidBodyFlag::eRETAIN_ACCELERATIONS) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eFORCE_KINE_KINE_NOTIFICATIONS, PxRigidBodyFlag::eFORCE_KINE_KINE_NOTIFICATIONS) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eFORCE_STATIC_KINE_NOTIFICATIONS, PxRigidBodyFlag::eFORCE_STATIC_KINE_NOTIFICATIONS) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eENABLE_GYROSCOPIC_FORCES, PxRigidBodyFlag::eENABLE_GYROSCOPIC_FORCES) -OMNI_PVD_ENUM_VALUE (rigidbodyflag, eRESERVED, PxRigidBodyFlag::eRESERVED) - -OMNI_PVD_ENUM (articulationflag, PxArticulationFlag) -OMNI_PVD_ENUM_VALUE (articulationflag, eFIX_BASE, PxArticulationFlag::eFIX_BASE) -OMNI_PVD_ENUM_VALUE (articulationflag, eDRIVE_LIMITS_ARE_FORCES, PxArticulationFlag::eDRIVE_LIMITS_ARE_FORCES) -OMNI_PVD_ENUM_VALUE (articulationflag, eDISABLE_SELF_COLLISION, PxArticulationFlag::eDISABLE_SELF_COLLISION) -OMNI_PVD_ENUM_VALUE (articulationflag, eCOMPUTE_JOINT_FORCES, PxArticulationFlag::eCOMPUTE_JOINT_FORCES) - -OMNI_PVD_ENUM (rigiddynamiclockflag, PxRigidDynamicLockFlag) -OMNI_PVD_ENUM_VALUE (rigiddynamiclockflag, eLOCK_LINEAR_X, PxRigidDynamicLockFlag::eLOCK_LINEAR_X) -OMNI_PVD_ENUM_VALUE (rigiddynamiclockflag, eLOCK_LINEAR_Y, PxRigidDynamicLockFlag::eLOCK_LINEAR_Y) -OMNI_PVD_ENUM_VALUE (rigiddynamiclockflag, eLOCK_LINEAR_Z, PxRigidDynamicLockFlag::eLOCK_LINEAR_Z) -OMNI_PVD_ENUM_VALUE (rigiddynamiclockflag, eLOCK_ANGULAR_X, PxRigidDynamicLockFlag::eLOCK_ANGULAR_X) -OMNI_PVD_ENUM_VALUE (rigiddynamiclockflag, eLOCK_ANGULAR_Y, PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y) -OMNI_PVD_ENUM_VALUE (rigiddynamiclockflag, eLOCK_ANGULAR_Z, PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z) - -OMNI_PVD_ENUM (shapeflag, PxShapeFlag) -OMNI_PVD_ENUM_VALUE (shapeflag, eSIMULATION_SHAPE, PxShapeFlag::eSIMULATION_SHAPE) -OMNI_PVD_ENUM_VALUE (shapeflag, eSCENE_QUERY_SHAPE, PxShapeFlag::eSCENE_QUERY_SHAPE) -OMNI_PVD_ENUM_VALUE (shapeflag, eTRIGGER_SHAPE, PxShapeFlag::eTRIGGER_SHAPE) -OMNI_PVD_ENUM_VALUE (shapeflag, eVISUALIZATION, PxShapeFlag::eVISUALIZATION) +OMNI_PVD_ENUM (PxSceneFlag) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_ACTIVE_ACTORS) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_CCD) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eDISABLE_CCD_RESWEEP) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_PCM) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eDISABLE_CONTACT_REPORT_BUFFER_RESIZE) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eDISABLE_CONTACT_CACHE) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eREQUIRE_RW_LOCK) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_STABILIZATION) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_AVERAGE_POINT) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_GPU_DYNAMICS) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_ENHANCED_DETERMINISM) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_FRICTION_EVERY_ITERATION) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eENABLE_DIRECT_GPU_API) +OMNI_PVD_ENUM_VALUE (PxSceneFlag, eFORCE_READBACK) + +OMNI_PVD_ENUM (PxMaterialFlag) +OMNI_PVD_ENUM_VALUE (PxMaterialFlag, eDISABLE_FRICTION) +OMNI_PVD_ENUM_VALUE (PxMaterialFlag, eDISABLE_STRONG_FRICTION) +OMNI_PVD_ENUM_VALUE (PxMaterialFlag, eIMPROVED_PATCH_FRICTION) + +OMNI_PVD_ENUM (PxActorFlag) +OMNI_PVD_ENUM_VALUE (PxActorFlag, eVISUALIZATION) +OMNI_PVD_ENUM_VALUE (PxActorFlag, eDISABLE_GRAVITY) +OMNI_PVD_ENUM_VALUE (PxActorFlag, eSEND_SLEEP_NOTIFIES) +OMNI_PVD_ENUM_VALUE (PxActorFlag, eDISABLE_SIMULATION) + +OMNI_PVD_ENUM (PxRigidBodyFlag) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eKINEMATIC) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eENABLE_CCD) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eENABLE_CCD_FRICTION) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eENABLE_POSE_INTEGRATION_PREVIEW) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eENABLE_SPECULATIVE_CCD) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eENABLE_CCD_MAX_CONTACT_IMPULSE) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eRETAIN_ACCELERATIONS) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eFORCE_KINE_KINE_NOTIFICATIONS) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eFORCE_STATIC_KINE_NOTIFICATIONS) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eENABLE_GYROSCOPIC_FORCES) +OMNI_PVD_ENUM_VALUE (PxRigidBodyFlag, eRESERVED) + +OMNI_PVD_ENUM (PxArticulationFlag) +OMNI_PVD_ENUM_VALUE (PxArticulationFlag, eFIX_BASE) +OMNI_PVD_ENUM_VALUE (PxArticulationFlag, eDRIVE_LIMITS_ARE_FORCES) +OMNI_PVD_ENUM_VALUE (PxArticulationFlag, eDISABLE_SELF_COLLISION) +OMNI_PVD_ENUM_VALUE (PxArticulationFlag, eCOMPUTE_JOINT_FORCES) + +OMNI_PVD_ENUM (PxRigidDynamicLockFlag) +OMNI_PVD_ENUM_VALUE (PxRigidDynamicLockFlag, eLOCK_LINEAR_X) +OMNI_PVD_ENUM_VALUE (PxRigidDynamicLockFlag, eLOCK_LINEAR_Y) +OMNI_PVD_ENUM_VALUE (PxRigidDynamicLockFlag, eLOCK_LINEAR_Z) +OMNI_PVD_ENUM_VALUE (PxRigidDynamicLockFlag, eLOCK_ANGULAR_X) +OMNI_PVD_ENUM_VALUE (PxRigidDynamicLockFlag, eLOCK_ANGULAR_Y) +OMNI_PVD_ENUM_VALUE (PxRigidDynamicLockFlag, eLOCK_ANGULAR_Z) + +OMNI_PVD_ENUM (PxShapeFlag) +OMNI_PVD_ENUM_VALUE (PxShapeFlag, eSIMULATION_SHAPE) +OMNI_PVD_ENUM_VALUE (PxShapeFlag, eSCENE_QUERY_SHAPE) +OMNI_PVD_ENUM_VALUE (PxShapeFlag, eTRIGGER_SHAPE) +OMNI_PVD_ENUM_VALUE (PxShapeFlag, eVISUALIZATION) //////////////////////////////////////////////////////////////////////////////// // Single value enums //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_ENUM (frictiontype, PxFrictionType) -OMNI_PVD_ENUM_VALUE (frictiontype, ePATCH, PxFrictionType::ePATCH) -OMNI_PVD_ENUM_VALUE (frictiontype, eONE_DIRECTIONAL, PxFrictionType::eONE_DIRECTIONAL) -OMNI_PVD_ENUM_VALUE (frictiontype, eTWO_DIRECTIONAL, PxFrictionType::eTWO_DIRECTIONAL) - -OMNI_PVD_ENUM (broadphasetype, PxBroadPhaseType) -OMNI_PVD_ENUM_VALUE (broadphasetype, eSAP, PxBroadPhaseType::eSAP) -OMNI_PVD_ENUM_VALUE (broadphasetype, eMBP, PxBroadPhaseType::eMBP) -OMNI_PVD_ENUM_VALUE (broadphasetype, eABP, PxBroadPhaseType::eABP) -OMNI_PVD_ENUM_VALUE (broadphasetype, eGPU, PxBroadPhaseType::eGPU) - -OMNI_PVD_ENUM (solvertype, PxSolverType) -OMNI_PVD_ENUM_VALUE (solvertype, ePGS, PxSolverType::ePGS) -OMNI_PVD_ENUM_VALUE (solvertype, eTGS, PxSolverType::eTGS) - -OMNI_PVD_ENUM (pairfilteringmode, PxPairFilteringMode) -OMNI_PVD_ENUM_VALUE (pairfilteringmode, eKEEP, PxPairFilteringMode::eKEEP) -OMNI_PVD_ENUM_VALUE (pairfilteringmode, eSUPPRESS, PxPairFilteringMode::eSUPPRESS) -OMNI_PVD_ENUM_VALUE (pairfilteringmode, eKILL, PxPairFilteringMode::eKILL) - -OMNI_PVD_ENUM (combinemode, PxCombineMode) -OMNI_PVD_ENUM_VALUE (combinemode, eAVERAGE, PxCombineMode::eAVERAGE) -OMNI_PVD_ENUM_VALUE (combinemode, eMIN, PxCombineMode::eMIN) -OMNI_PVD_ENUM_VALUE (combinemode, eMULTIPLY, PxCombineMode::eMULTIPLY) -OMNI_PVD_ENUM_VALUE (combinemode, eMAX, PxCombineMode::eMAX) - -OMNI_PVD_ENUM (actortype, PxActorType) -OMNI_PVD_ENUM_VALUE (actortype, eRIGID_STATIC, PxActorType::eRIGID_STATIC) -OMNI_PVD_ENUM_VALUE (actortype, eRIGID_DYNAMIC, PxActorType::eRIGID_DYNAMIC) -OMNI_PVD_ENUM_VALUE (actortype, eARTICULATION_LINK, PxActorType::eARTICULATION_LINK) -OMNI_PVD_ENUM_VALUE (actortype, eSOFTBODY, PxActorType::eSOFTBODY) -OMNI_PVD_ENUM_VALUE (actortype, eFEMCLOTH, PxActorType::eFEMCLOTH) -OMNI_PVD_ENUM_VALUE (actortype, ePBD_PARTICLESYSTEM, PxActorType::ePBD_PARTICLESYSTEM) -OMNI_PVD_ENUM_VALUE (actortype, eFLIP_PARTICLESYSTEM, PxActorType::eFLIP_PARTICLESYSTEM) -OMNI_PVD_ENUM_VALUE (actortype, eMPM_PARTICLESYSTEM, PxActorType::eMPM_PARTICLESYSTEM) -OMNI_PVD_ENUM_VALUE (actortype, eCUSTOM_PARTICLESYSTEM, PxActorType::eCUSTOM_PARTICLESYSTEM) -OMNI_PVD_ENUM_VALUE (actortype, eHAIRSYSTEM, PxActorType::eHAIRSYSTEM) - -OMNI_PVD_ENUM (articulationjointtype, PxArticulationJointType) -OMNI_PVD_ENUM_VALUE (articulationjointtype, eFIX, PxArticulationJointType::eFIX) -OMNI_PVD_ENUM_VALUE (articulationjointtype, ePRISMATIC, PxArticulationJointType::ePRISMATIC) -OMNI_PVD_ENUM_VALUE (articulationjointtype, eREVOLUTE, PxArticulationJointType::eREVOLUTE) -OMNI_PVD_ENUM_VALUE (articulationjointtype, eREVOLUTE_UNWRAPPED, PxArticulationJointType::eREVOLUTE_UNWRAPPED) -OMNI_PVD_ENUM_VALUE (articulationjointtype, eSPHERICAL, PxArticulationJointType::eSPHERICAL) -OMNI_PVD_ENUM_VALUE (articulationjointtype, eUNDEFINED, PxArticulationJointType::eUNDEFINED) - -OMNI_PVD_ENUM (articulationmotion, PxArticulationMotion) -OMNI_PVD_ENUM_VALUE (articulationmotion, eLOCKED, PxArticulationMotion::eLOCKED) -OMNI_PVD_ENUM_VALUE (articulationmotion, eLIMITED, PxArticulationMotion::eLIMITED) -OMNI_PVD_ENUM_VALUE (articulationmotion, eFREE, PxArticulationMotion::eFREE) - -OMNI_PVD_ENUM (articulationdrivetype, PxArticulationDriveType) -OMNI_PVD_ENUM_VALUE (articulationdrivetype, eFORCE, PxArticulationDriveType::eFORCE) -OMNI_PVD_ENUM_VALUE (articulationdrivetype, eACCELERATION, PxArticulationDriveType::eACCELERATION) -OMNI_PVD_ENUM_VALUE (articulationdrivetype, eTARGET, PxArticulationDriveType::eTARGET) -OMNI_PVD_ENUM_VALUE (articulationdrivetype, eVELOCITY, PxArticulationDriveType::eVELOCITY) -OMNI_PVD_ENUM_VALUE (articulationdrivetype, eNONE, PxArticulationDriveType::eNONE) +OMNI_PVD_ENUM (PxFrictionType) +OMNI_PVD_ENUM_VALUE (PxFrictionType, ePATCH) +OMNI_PVD_ENUM_VALUE (PxFrictionType, eONE_DIRECTIONAL) +OMNI_PVD_ENUM_VALUE (PxFrictionType, eTWO_DIRECTIONAL) + +OMNI_PVD_ENUM (PxBroadPhaseType) +OMNI_PVD_ENUM_VALUE (PxBroadPhaseType, eSAP) +OMNI_PVD_ENUM_VALUE (PxBroadPhaseType, eMBP) +OMNI_PVD_ENUM_VALUE (PxBroadPhaseType, eABP) +OMNI_PVD_ENUM_VALUE (PxBroadPhaseType, eGPU) + +OMNI_PVD_ENUM (PxSolverType) +OMNI_PVD_ENUM_VALUE (PxSolverType, ePGS) +OMNI_PVD_ENUM_VALUE (PxSolverType, eTGS) + +OMNI_PVD_ENUM (PxPairFilteringMode) +OMNI_PVD_ENUM_VALUE (PxPairFilteringMode, eKEEP) +OMNI_PVD_ENUM_VALUE (PxPairFilteringMode, eSUPPRESS) +OMNI_PVD_ENUM_VALUE (PxPairFilteringMode, eKILL) + +OMNI_PVD_ENUM (PxCombineMode) +OMNI_PVD_ENUM_VALUE (PxCombineMode, eAVERAGE) +OMNI_PVD_ENUM_VALUE (PxCombineMode, eMIN) +OMNI_PVD_ENUM_VALUE (PxCombineMode, eMULTIPLY) +OMNI_PVD_ENUM_VALUE (PxCombineMode, eMAX) + +OMNI_PVD_ENUM (PxActorType) +OMNI_PVD_ENUM_VALUE (PxActorType, eRIGID_STATIC) +OMNI_PVD_ENUM_VALUE (PxActorType, eRIGID_DYNAMIC) +OMNI_PVD_ENUM_VALUE (PxActorType, eARTICULATION_LINK) +OMNI_PVD_ENUM_VALUE (PxActorType, eSOFTBODY) +OMNI_PVD_ENUM_VALUE (PxActorType, eFEMCLOTH) +OMNI_PVD_ENUM_VALUE (PxActorType, ePBD_PARTICLESYSTEM) +OMNI_PVD_ENUM_VALUE (PxActorType, eFLIP_PARTICLESYSTEM) +OMNI_PVD_ENUM_VALUE (PxActorType, eMPM_PARTICLESYSTEM) +OMNI_PVD_ENUM_VALUE (PxActorType, eHAIRSYSTEM) + +OMNI_PVD_ENUM (PxArticulationJointType) +OMNI_PVD_ENUM_VALUE (PxArticulationJointType, eFIX) +OMNI_PVD_ENUM_VALUE (PxArticulationJointType, ePRISMATIC) +OMNI_PVD_ENUM_VALUE (PxArticulationJointType, eREVOLUTE) +OMNI_PVD_ENUM_VALUE (PxArticulationJointType, eREVOLUTE_UNWRAPPED) +OMNI_PVD_ENUM_VALUE (PxArticulationJointType, eSPHERICAL) +OMNI_PVD_ENUM_VALUE (PxArticulationJointType, eUNDEFINED) + +OMNI_PVD_ENUM (PxArticulationMotion) +OMNI_PVD_ENUM_VALUE (PxArticulationMotion, eLOCKED) +OMNI_PVD_ENUM_VALUE (PxArticulationMotion, eLIMITED) +OMNI_PVD_ENUM_VALUE (PxArticulationMotion, eFREE) + +OMNI_PVD_ENUM (PxArticulationDriveType) +OMNI_PVD_ENUM_VALUE (PxArticulationDriveType, eFORCE) +OMNI_PVD_ENUM_VALUE (PxArticulationDriveType, eACCELERATION) +OMNI_PVD_ENUM_VALUE (PxArticulationDriveType, eTARGET) +OMNI_PVD_ENUM_VALUE (PxArticulationDriveType, eVELOCITY) +OMNI_PVD_ENUM_VALUE (PxArticulationDriveType, eNONE) //////////////////////////////////////////////////////////////////////////////// // Classes //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// PVD name, PVD attr, Px classT, Px attrT, PVD basicT, PVD basicTsize -//////////////////////////////////////////////////////////////////////////////// - -//////////////////////////////////////////////////////////////////////////////// -// Physics -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (physics, PxPhysics) -OMNI_PVD_ATTRIBUTE_SET (physics, scenes, PxPhysics, PxScene) -OMNI_PVD_ATTRIBUTE_SET (physics, heightFields, PxPhysics, PxHeightField) -OMNI_PVD_ATTRIBUTE_SET (physics, convexMeshes, PxPhysics, PxConvexMesh) -OMNI_PVD_ATTRIBUTE_SET (physics, triangleMeshes, PxPhysics, PxTriangleMesh) -OMNI_PVD_ATTRIBUTE_SET (physics, tetrahedronMeshes, PxPhysics, PxTetrahedronMesh) -OMNI_PVD_ATTRIBUTE_SET (physics, softBodyMeshes, PxPhysics, PxSoftBodyMesh) -OMNI_PVD_ATTRIBUTE_SET (physics, shapes, PxPhysics, PxShape) -OMNI_PVD_ATTRIBUTE_SET (physics, bvhs, PxPhysics, PxBVH) -OMNI_PVD_ATTRIBUTE_SET (physics, materials, PxPhysics, PxMaterial) -OMNI_PVD_ATTRIBUTE_SET (physics, FEMSoftBodyMaterials, PxPhysics, PxFEMSoftBodyMaterial) -OMNI_PVD_ATTRIBUTE_SET (physics, FEMClothMaterials, PxPhysics, PxFEMClothMaterial) -OMNI_PVD_ATTRIBUTE_SET (physics, PBDMaterials, PxPhysics, PxPBDMaterial) -OMNI_PVD_ATTRIBUTE_SET (physics, FLIPMaterials, PxPhysics, PxFLIPMaterial) -OMNI_PVD_ATTRIBUTE_SET (physics, MPMMaterials, PxPhysics, PxMPMMaterial) -OMNI_PVD_ATTRIBUTE_SET (physics, softBodies, PxPhysics, PxActor) -OMNI_PVD_ATTRIBUTE_SET (physics, rigidDynamics, PxPhysics, PxActor) -OMNI_PVD_ATTRIBUTE_SET (physics, rigidStatics, PxPhysics, PxActor) -OMNI_PVD_ATTRIBUTE_SET (physics, aggregates, PxPhysics, PxAggregate) -OMNI_PVD_ATTRIBUTE_SET (physics, articulations, PxPhysics, PxArticulationReducedCoordinate) -OMNI_PVD_ATTRIBUTE (physics, tolerancesScale, PxPhysics, PxTolerancesScale, OmniPvdDataTypeEnum::eFLOAT32, 2) - -//////////////////////////////////////////////////////////////////////////////// -// Scene -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (scene, PxScene) -OMNI_PVD_ATTRIBUTE_SET (scene, actors, PxScene, PxActor) -OMNI_PVD_ATTRIBUTE_SET (scene, articulations, PxScene, PxArticulationReducedCoordinate) -OMNI_PVD_ATTRIBUTE_SET (scene, aggregates, PxScene, PxAggregate) -OMNI_PVD_ATTRIBUTE_FLAG (scene, flags, PxScene, PxSceneFlags, sceneflag) -OMNI_PVD_ATTRIBUTE_FLAG (scene, frictionType,PxScene, PxFrictionType::Enum, frictiontype) -OMNI_PVD_ATTRIBUTE_FLAG (scene, broadPhaseType,PxScene, PxBroadPhaseType::Enum, broadphasetype) -OMNI_PVD_ATTRIBUTE_FLAG (scene, kineKineFilteringMode, PxScene, PxPairFilteringMode::Enum, pairfilteringmode) -OMNI_PVD_ATTRIBUTE_FLAG (scene, staticKineFilteringMode,PxScene, PxPairFilteringMode::Enum, pairfilteringmode) -OMNI_PVD_ATTRIBUTE_FLAG (scene, solverType, PxScene, PxSolverType::Enum, solvertype) -OMNI_PVD_ATTRIBUTE (scene, gravity, PxScene, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (scene, bounceThresholdVelocity,PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, frictionOffsetThreshold,PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, frictionCorrelationDistance, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, solverOffsetSlop, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, solverBatchSize, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, solverArticulationBatchSize, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, nbContactDataBlocks, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, maxNbContactDataBlocks, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, maxBiasCoefficient, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, contactReportStreamBufferSize, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, ccdMaxPasses, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, ccdThreshold, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, ccdMaxSeparation, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, wakeCounterResetValue, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (scene, hasCPUDispatcher, PxScene, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, hasCUDAContextManager, PxScene, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, hasSimulationEventCallback, PxScene,bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, hasContactModifyCallback, PxScene, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, hasCCDContactModifyCallback, PxScene,bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, hasBroadPhaseCallback, PxScene, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, hasFilterCallback, PxScene, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbActors, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbBodies, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbStaticShapes,PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbDynamicShapes,PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbAggregates, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbConstraints,PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbRegions, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, limitsMaxNbBroadPhaseOverlaps,PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, sanityBounds, PxScene, PxBounds3, OmniPvdDataTypeEnum::eFLOAT32, 6) -OMNI_PVD_ATTRIBUTE (scene, gpuDynamicsConfig, PxScene, PxgDynamicsMemoryConfig, OmniPvdDataTypeEnum::eUINT32, 12) -OMNI_PVD_ATTRIBUTE (scene, gpuMaxNumPartitions, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, gpuMaxNumStaticPartitions,PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, gpuComputeVersion, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, contactPairSlabSize, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, tolerancesScale, PxScene, PxTolerancesScale, OmniPvdDataTypeEnum::eFLOAT32, 2) -//OMNI_PVD_SET(scene, sceneQuerySystem, PxScene, npScene->getSQAPI())//needs class - -OMNI_PVD_ATTRIBUTE (scene, pairCount, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (scene, pairsActors, PxScene, PxActor*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 0) // 2 for each pair -OMNI_PVD_ATTRIBUTE (scene, pairsContactCounts, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 0) // 1 for each pair -OMNI_PVD_ATTRIBUTE (scene, pairsContactPoints, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) // 3 for each contact -OMNI_PVD_ATTRIBUTE (scene, pairsContactNormals, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) // 3 for each contact -OMNI_PVD_ATTRIBUTE (scene, pairsContactSeparations, PxScene, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) // 1 for each contact -OMNI_PVD_ATTRIBUTE (scene, pairsContactShapes, PxScene, PxShape*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 0) // 2 for each contact -OMNI_PVD_ATTRIBUTE (scene, pairsContactFacesIndices, PxScene, PxU32, OmniPvdDataTypeEnum::eUINT32, 0) // 2 for each contact - -//////////////////////////////////////////////////////////////////////////////// -// Material -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (material, PxMaterial) -OMNI_PVD_ATTRIBUTE_FLAG (material, flags, PxMaterial, PxMaterialFlags, materialflag) -OMNI_PVD_ATTRIBUTE_FLAG (material, frictionCombineMode, PxMaterial, PxCombineMode::Enum, combinemode) -OMNI_PVD_ATTRIBUTE_FLAG (material, restitutionCombineMode, PxMaterial, PxCombineMode::Enum, combinemode) -OMNI_PVD_ATTRIBUTE (material, staticFriction, PxMaterial, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (material, dynamicFriction, PxMaterial, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (material, restitution, PxMaterial, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (material, damping, PxMaterial, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) - -//////////////////////////////////////////////////////////////////////////////// -// FEMSoftBodyMaterial -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (femsoftbodymaterial, PxFEMSoftBodyMaterial) - -//////////////////////////////////////////////////////////////////////////////// -// FEMClothMaterial -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (femclothmaterial, PxFEMClothMaterial) - -//////////////////////////////////////////////////////////////////////////////// -// PBDMaterial -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (pbdmaterial, PxPBDMaterial) - -//////////////////////////////////////////////////////////////////////////////// -// FLIPMaterial -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (flipmaterial, PxFLIPMaterial) - -//////////////////////////////////////////////////////////////////////////////// -// MPMMaterial -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (mpmmaterial, PxMPMMaterial) - -//////////////////////////////////////////////////////////////////////////////// -// Aggregate -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (aggregate, PxAggregate) -OMNI_PVD_ATTRIBUTE_SET (aggregate, actors, PxAggregate, PxActor) -OMNI_PVD_ATTRIBUTE (aggregate, selfCollision, PxAggregate, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (aggregate, maxNbShapes, PxAggregate, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (aggregate, scene, PxAggregate, PxScene const*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) - -//////////////////////////////////////////////////////////////////////////////// -// Actor -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (actor, PxActor) -//name - is there a string type? -OMNI_PVD_ATTRIBUTE_FLAG (actor, type, PxActor, PxActorType::Enum, actortype) -OMNI_PVD_ATTRIBUTE_FLAG (actor, flags, PxActor, PxActorFlags, actorflag) -OMNI_PVD_ATTRIBUTE_FLAG (actor, rigidBodyFlags, PxActor, PxRigidBodyFlags, rigidbodyflag) -OMNI_PVD_ATTRIBUTE (actor, name, PxActor, char, OmniPvdDataTypeEnum::eSTRING, 1) -OMNI_PVD_ATTRIBUTE (actor, dominance, PxActor, PxDominanceGroup, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (actor, ownerClient, PxActor, PxClientID, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (actor, translation, PxActor, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (actor, rotation, PxActor, PxQuat, OmniPvdDataTypeEnum::eFLOAT32, 4) -OMNI_PVD_ATTRIBUTE (actor, scale, PxActor, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (actor, cMassLocalPose, PxActor, PxTransform, OmniPvdDataTypeEnum::eFLOAT32, 7) -OMNI_PVD_ATTRIBUTE (actor, mass, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, massSpaceInertiaTensor, PxActor, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (actor, linearDamping, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, angularDamping, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, linearVelocity, PxActor, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (actor, angularVelocity, PxActor, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (actor, maxLinearVelocity, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, maxAngularVelocity, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, minAdvancedCCDCoefficient, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, maxDepenetrationVelocity, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, maxContactImpulse, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, contactSlopCoefficient, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_SET (actor, shapes, PxActor, PxShape) -OMNI_PVD_ATTRIBUTE (actor, articulation, PxActor, PxArticulationReducedCoordinate const*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (actor, worldBounds, PxActor, PxBounds3, OmniPvdDataTypeEnum::eFLOAT32, 6) -OMNI_PVD_ATTRIBUTE (actor, isSleeping, PxActor, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (actor, sleepThreshold, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, wakeCounter, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, stabilizationThreshold, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, positionIterations, PxActor, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (actor, velocityIterations, PxActor, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (actor, rigidDynamicLockFlags, PxActor, PxRigidDynamicLockFlags, rigiddynamiclockflag) -OMNI_PVD_ATTRIBUTE (actor, contactReportThreshold, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, CFMScale, PxActor, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (actor, inboundJointDOF, PxActor, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) +// PxPhysics +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxPhysics) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, scenes, PxScene) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, heightFields, PxHeightField) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, convexMeshes, PxConvexMesh) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, triangleMeshes, PxTriangleMesh) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, tetrahedronMeshes, PxTetrahedronMesh) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, softBodyMeshes, PxSoftBodyMesh) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, shapes, PxShape) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, bvhs, PxBVH) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, materials, PxMaterial) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, FEMSoftBodyMaterials, PxFEMSoftBodyMaterial) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, FEMClothMaterials, PxFEMClothMaterial) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, PBDMaterials, PxPBDMaterial) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, FLIPMaterials, PxFLIPMaterial) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, MPMMaterials, PxMPMMaterial) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, rigidDynamics, PxActor) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, rigidStatics, PxActor) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, aggregates, PxAggregate) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxPhysics, articulations, PxArticulationReducedCoordinate) +OMNI_PVD_ATTRIBUTE (PxPhysics, tolerancesScale, PxTolerancesScale, OmniPvdDataType::eFLOAT32, 2) + +//////////////////////////////////////////////////////////////////////////////// +// PxScene +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxScene) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxScene, actors, PxActor) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxScene, articulations, PxArticulationReducedCoordinate) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxScene, aggregates, PxAggregate) +OMNI_PVD_ATTRIBUTE_FLAG (PxScene, flags, PxSceneFlags, PxSceneFlag) +OMNI_PVD_ATTRIBUTE_FLAG (PxScene, frictionType, PxFrictionType::Enum, PxFrictionType) +OMNI_PVD_ATTRIBUTE_FLAG (PxScene, broadPhaseType, PxBroadPhaseType::Enum, PxBroadPhaseType) +OMNI_PVD_ATTRIBUTE_FLAG (PxScene, kineKineFilteringMode, PxPairFilteringMode::Enum, PxPairFilteringMode) +OMNI_PVD_ATTRIBUTE_FLAG (PxScene, staticKineFilteringMode,PxPairFilteringMode::Enum, PxPairFilteringMode) +OMNI_PVD_ATTRIBUTE_FLAG (PxScene, solverType, PxSolverType::Enum, PxSolverType) +OMNI_PVD_ATTRIBUTE (PxScene, name, char, OmniPvdDataType::eSTRING, 1) +OMNI_PVD_ATTRIBUTE (PxScene, gravity, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxScene, bounceThresholdVelocity,PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, frictionOffsetThreshold,PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, frictionCorrelationDistance, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, solverOffsetSlop, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, solverBatchSize, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, solverArticulationBatchSize, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, nbContactDataBlocks, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, maxNbContactDataBlocks, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, maxBiasCoefficient, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, contactReportStreamBufferSize, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, ccdMaxPasses, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, ccdThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, ccdMaxSeparation, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, wakeCounterResetValue, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasCPUDispatcher, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasCUDAContextManager, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasSimulationEventCallback, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasContactModifyCallback, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasCCDContactModifyCallback, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasBroadPhaseCallback, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, hasFilterCallback, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbActors, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbBodies, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbStaticShapes,PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbDynamicShapes, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbAggregates, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbConstraints, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbRegions, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, limitsMaxNbBroadPhaseOverlaps, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, sanityBounds, PxBounds3, OmniPvdDataType::eFLOAT32, 6) +OMNI_PVD_ATTRIBUTE (PxScene, gpuDynamicsConfig, PxgDynamicsMemoryConfig, OmniPvdDataType::eUINT32, 12) +OMNI_PVD_ATTRIBUTE (PxScene, gpuMaxNumPartitions, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, gpuMaxNumStaticPartitions, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, gpuComputeVersion, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, contactPairSlabSize, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, tolerancesScale, PxTolerancesScale, OmniPvdDataType::eFLOAT32, 2) +OMNI_PVD_ATTRIBUTE (PxScene, pairCount, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxScene, pairsActors, PxActor*, OmniPvdDataType::eOBJECT_HANDLE, 0) // 2 for each pair +OMNI_PVD_ATTRIBUTE (PxScene, pairsContactCounts, PxU32, OmniPvdDataType::eUINT32, 0) // 1 for each pair +OMNI_PVD_ATTRIBUTE (PxScene, pairsContactPoints, PxReal, OmniPvdDataType::eFLOAT32, 0) // 3 for each contact +OMNI_PVD_ATTRIBUTE (PxScene, pairsContactNormals, PxReal, OmniPvdDataType::eFLOAT32, 0) // 3 for each contact +OMNI_PVD_ATTRIBUTE (PxScene, pairsContactSeparations, PxReal, OmniPvdDataType::eFLOAT32, 0) // 1 for each contact +OMNI_PVD_ATTRIBUTE (PxScene, pairsContactShapes, PxShape*, OmniPvdDataType::eOBJECT_HANDLE, 0) // 2 for each contact +OMNI_PVD_ATTRIBUTE (PxScene, pairsContactFacesIndices, PxU32, OmniPvdDataType::eUINT32, 0) // 2 for each contact + + +//////////////////////////////////////////////////////////////////////////////// +// PxBaseMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxBaseMaterial) + +//////////////////////////////////////////////////////////////////////////////// +// PxMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxMaterial, PxBaseMaterial) +OMNI_PVD_ATTRIBUTE_FLAG (PxMaterial, flags, PxMaterialFlags, PxMaterialFlag) +OMNI_PVD_ATTRIBUTE_FLAG (PxMaterial, frictionCombineMode, PxCombineMode::Enum, PxCombineMode) +OMNI_PVD_ATTRIBUTE_FLAG (PxMaterial, restitutionCombineMode,PxCombineMode::Enum, PxCombineMode) +OMNI_PVD_ATTRIBUTE (PxMaterial, staticFriction, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxMaterial, dynamicFriction, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxMaterial, restitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxMaterial, damping, PxReal, OmniPvdDataType::eFLOAT32, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxFEMSoftBodyMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxFEMSoftBodyMaterial, PxBaseMaterial) + +//////////////////////////////////////////////////////////////////////////////// +// PxFEMClothMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxFEMClothMaterial, PxBaseMaterial) + +//////////////////////////////////////////////////////////////////////////////// +// PxPBDMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxPBDMaterial, PxBaseMaterial) + +//////////////////////////////////////////////////////////////////////////////// +// PxFLIPMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxFLIPMaterial, PxBaseMaterial) + +//////////////////////////////////////////////////////////////////////////////// +// PxMPMMaterial +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxMPMMaterial, PxBaseMaterial) + +//////////////////////////////////////////////////////////////////////////////// +// PxAggregate +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxAggregate) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxAggregate, actors, PxActor) +OMNI_PVD_ATTRIBUTE (PxAggregate, selfCollision, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxAggregate, maxNbShapes, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxAggregate, scene, PxScene const*, OmniPvdDataType::eOBJECT_HANDLE, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxActor +// Missing +// aggregate? +// scene? +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxActor) +OMNI_PVD_ATTRIBUTE_FLAG (PxActor, type, PxActorType::Enum, PxActorType) +OMNI_PVD_ATTRIBUTE_FLAG (PxActor, flags, PxActorFlags, PxActorFlag) +OMNI_PVD_ATTRIBUTE (PxActor, name, char, OmniPvdDataType::eSTRING, 1) +OMNI_PVD_ATTRIBUTE (PxActor, worldBounds, PxBounds3, OmniPvdDataType::eFLOAT32, 6) +OMNI_PVD_ATTRIBUTE (PxActor, dominance, PxDominanceGroup, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxActor, ownerClient, PxClientID, OmniPvdDataType::eUINT8, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxRigidActor +// Missing +// internalActorIndex? +// constraints? +// Remap +// translation + rotation -> globalPose? +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxRigidActor, PxActor) +OMNI_PVD_ATTRIBUTE (PxRigidActor, translation, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxRigidActor, rotation, PxQuat, OmniPvdDataType::eFLOAT32, 4) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxRigidActor, shapes, PxShape) //////////////////////////////////////////////////////////////////////////////// -// Articulation +// PxRigidStatic //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (articulation, PxArticulationReducedCoordinate) -OMNI_PVD_ATTRIBUTE (articulation, positionIterations, PxArticulationReducedCoordinate, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (articulation, velocityIterations, PxArticulationReducedCoordinate, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) -OMNI_PVD_ATTRIBUTE (articulation, isSleeping, PxArticulationReducedCoordinate, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (articulation, sleepThreshold, PxArticulationReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (articulation, stabilizationThreshold, PxArticulationReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (articulation, wakeCounter, PxArticulationReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (articulation, maxLinVelocity, PxArticulationReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (articulation, maxAngVelocity, PxArticulationReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_SET (articulation, links, PxArticulationReducedCoordinate, PxArticulationLink) -OMNI_PVD_ATTRIBUTE (articulation, worldBounds, PxArticulationReducedCoordinate, PxBounds3, OmniPvdDataTypeEnum::eFLOAT32, 6) -OMNI_PVD_ATTRIBUTE_FLAG (articulation, articulationFlags, PxArticulationReducedCoordinate, PxArticulationFlags, articulationflag) -OMNI_PVD_ATTRIBUTE (articulation, dofs, PxArticulationReducedCoordinate, PxU32, OmniPvdDataTypeEnum::eUINT32, 1) +OMNI_PVD_CLASS_DERIVED (PxRigidStatic, PxRigidActor) //////////////////////////////////////////////////////////////////////////////// -// Articulation Joint +// PxRigidBody +// Missing +// islandNodeIndex? +// force? +// torque? +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxRigidBody, PxRigidActor) +OMNI_PVD_ATTRIBUTE (PxRigidBody, cMassLocalPose, PxTransform, OmniPvdDataType::eFLOAT32, 7) +OMNI_PVD_ATTRIBUTE (PxRigidBody, mass, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, massSpaceInertiaTensor, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxRigidBody, linearDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, angularDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, linearVelocity, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxRigidBody, angularVelocity, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxRigidBody, maxLinearVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, maxAngularVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxRigidBody, rigidBodyFlags, PxRigidBodyFlags, PxRigidBodyFlag) +OMNI_PVD_ATTRIBUTE (PxRigidBody, minAdvancedCCDCoefficient, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, maxDepenetrationVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, maxContactImpulse, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidBody, contactSlopCoefficient, PxReal, OmniPvdDataType::eFLOAT32, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxRigidDynamic +// Missing +// kinematicTarget? +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxRigidDynamic, PxRigidBody) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, isSleeping, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, sleepThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, stabilizationThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxRigidDynamic, rigidDynamicLockFlags, PxRigidDynamicLockFlags, PxRigidDynamicLockFlag) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, wakeCounter, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, positionIterations, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, velocityIterations, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxRigidDynamic, contactReportThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxArticulationLink +// Missing +// inboundJoint? +// children? +// linkIndex? +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxArticulationLink, PxRigidBody) +OMNI_PVD_ATTRIBUTE (PxArticulationLink, articulation, PxArticulationReducedCoordinate const*, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationLink, inboundJointDOF, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationLink, CFMScale, PxReal, OmniPvdDataType::eFLOAT32, 1) + //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (articulationjoint, PxArticulationJointReducedCoordinate) -OMNI_PVD_ATTRIBUTE (articulationjoint, parentLink, PxArticulationJointReducedCoordinate, PxArticulationLink const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (articulationjoint, childLink, PxArticulationJointReducedCoordinate, PxArticulationLink const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (articulationjoint, parentTranslation, PxArticulationJointReducedCoordinate, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (articulationjoint, parentRotation, PxArticulationJointReducedCoordinate, PxQuat, OmniPvdDataTypeEnum::eFLOAT32, 4) -OMNI_PVD_ATTRIBUTE (articulationjoint, childTranslation, PxArticulationJointReducedCoordinate, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (articulationjoint, childRotation, PxArticulationJointReducedCoordinate, PxQuat, OmniPvdDataTypeEnum::eFLOAT32, 4) -OMNI_PVD_ATTRIBUTE_FLAG (articulationjoint, type, PxArticulationJointReducedCoordinate, PxArticulationJointType::Enum, articulationjointtype) -OMNI_PVD_ATTRIBUTE (articulationjoint, motion, PxArticulationJointReducedCoordinate, PxArticulationMotion::Enum, OmniPvdDataTypeEnum::eUINT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, armature, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, frictionCoefficient, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (articulationjoint, maxJointVelocity, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (articulationjoint, jointPosition, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, jointVelocity, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, concreteTypeName, PxArticulationJointReducedCoordinate, char, OmniPvdDataTypeEnum::eSTRING, 1) -OMNI_PVD_ATTRIBUTE (articulationjoint, limitLow, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, limitHigh, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, driveStiffness, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, driveDamping, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, driveMaxForce, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, driveType, PxArticulationJointReducedCoordinate, PxArticulationDriveType::Enum, OmniPvdDataTypeEnum::eUINT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, driveTarget, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (articulationjoint, driveVelocity, PxArticulationJointReducedCoordinate, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) +// PxArticulationReducedCoordinate +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxArticulationReducedCoordinate) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, positionIterations, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, velocityIterations, PxU32, OmniPvdDataType::eUINT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, isSleeping, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, sleepThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, stabilizationThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, wakeCounter, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, maxLinearVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, maxAngularVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_UNIQUE_LIST (PxArticulationReducedCoordinate, links, PxArticulationLink) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, worldBounds, PxBounds3, OmniPvdDataType::eFLOAT32, 6) +OMNI_PVD_ATTRIBUTE_FLAG (PxArticulationReducedCoordinate, articulationFlags, PxArticulationFlags, PxArticulationFlag) +OMNI_PVD_ATTRIBUTE (PxArticulationReducedCoordinate, dofs, PxU32, OmniPvdDataType::eUINT32, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxArticulationJointReducedCoordinate +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxArticulationJointReducedCoordinate) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, parentLink, PxArticulationLink const *, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, childLink, PxArticulationLink const *, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, parentTranslation, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, parentRotation, PxQuat, OmniPvdDataType::eFLOAT32, 4) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, childTranslation, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, childRotation, PxQuat, OmniPvdDataType::eFLOAT32, 4) +OMNI_PVD_ATTRIBUTE_FLAG (PxArticulationJointReducedCoordinate, type, PxArticulationJointType::Enum, PxArticulationJointType) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, motion, PxArticulationMotion::Enum, OmniPvdDataType::eUINT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, armature, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, frictionCoefficient, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, maxJointVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, jointPosition, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, jointVelocity, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, concreteTypeName, char, OmniPvdDataType::eSTRING, 1) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, limitLow, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, limitHigh, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, driveStiffness, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, driveDamping, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, driveMaxForce, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, driveType, PxArticulationDriveType::Enum, OmniPvdDataType::eUINT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, driveTarget, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxArticulationJointReducedCoordinate, driveVelocity, PxReal, OmniPvdDataType::eFLOAT32, 0) + +//////////////////////////////////////////////////////////////////////////////// +// PxShape +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxShape) +OMNI_PVD_ATTRIBUTE (PxShape, translation, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxShape, rotation, PxQuat, OmniPvdDataType::eFLOAT32, 4) +OMNI_PVD_ATTRIBUTE (PxShape, isExclusive, bool, OmniPvdDataType::eUINT8, 1) +OMNI_PVD_ATTRIBUTE (PxShape, geom, PxGeometry const *, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxShape, contactOffset, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxShape, restOffset, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxShape, densityForFluid, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxShape, torsionalPatchRadius, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxShape, minTorsionalPatchRadius, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxShape, shapeFlags, PxShapeFlags, PxShapeFlag) +OMNI_PVD_ATTRIBUTE (PxShape, simulationFilterData, PxFilterData, OmniPvdDataType::eUINT32, 4) +OMNI_PVD_ATTRIBUTE (PxShape, queryFilterData, PxFilterData, OmniPvdDataType::eUINT32, 4) +OMNI_PVD_ATTRIBUTE (PxShape, materials, PxMaterial const *, OmniPvdDataType::eOBJECT_HANDLE, 0) + //////////////////////////////////////////////////////////////////////////////// -// Shape +// PxGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (shape, PxShape) -OMNI_PVD_ATTRIBUTE (shape, translation, PxShape, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (shape, rotation, PxShape, PxQuat, OmniPvdDataTypeEnum::eFLOAT32, 4) -OMNI_PVD_ATTRIBUTE (shape, scale, PxShape, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (shape, isExclusive, PxShape, bool, OmniPvdDataTypeEnum::eUINT8, 1) -OMNI_PVD_ATTRIBUTE (shape, geom, PxShape, PxGeometry const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (shape, contactOffset, PxShape, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (shape, restOffset, PxShape, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (shape, densityForFluid, PxShape, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (shape, torsionalPatchRadius, PxShape, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (shape, minTorsionalPatchRadius, PxShape, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (shape, shapeFlags, PxShape, PxShapeFlags, shapeflag) -OMNI_PVD_ATTRIBUTE (shape, simulationFilterData, PxShape, PxFilterData, OmniPvdDataTypeEnum::eUINT32, 4) -OMNI_PVD_ATTRIBUTE (shape, queryFilterData, PxShape, PxFilterData, OmniPvdDataTypeEnum::eUINT32, 4) -OMNI_PVD_ATTRIBUTE (shape, materials, PxShape, PxMaterial const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 0) +OMNI_PVD_CLASS (PxGeometry) //////////////////////////////////////////////////////////////////////////////// -// GeomSphere +// PxSphereGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomsphere, PxGeometry, PxGeomSphere) -OMNI_PVD_ATTRIBUTE (geomsphere, radius, PxGeometry, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) +OMNI_PVD_CLASS_DERIVED (PxSphereGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxSphereGeometry, radius, PxReal, OmniPvdDataType::eFLOAT32, 1) //////////////////////////////////////////////////////////////////////////////// -// GeomCapsule +// PxCapsuleGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomcapsule, PxGeometry, PxGeomCapsule) -OMNI_PVD_ATTRIBUTE (geomcapsule, halfHeight,PxGeometry,PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (geomcapsule, radius, PxGeometry, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) +OMNI_PVD_CLASS_DERIVED (PxCapsuleGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxCapsuleGeometry, halfHeight, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxCapsuleGeometry, radius, PxReal, OmniPvdDataType::eFLOAT32, 1) //////////////////////////////////////////////////////////////////////////////// -// GeomBox +// PxBoxGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geombox, PxGeometry, PxGeomBox) -OMNI_PVD_ATTRIBUTE (geombox, halfExtents,PxGeometry, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) +OMNI_PVD_CLASS_DERIVED (PxBoxGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxBoxGeometry, halfExtents, PxVec3, OmniPvdDataType::eFLOAT32, 3) //////////////////////////////////////////////////////////////////////////////// -// GeomPlane +// PxPlaneGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomplane, PxGeometry, PxGeomPlane) +OMNI_PVD_CLASS_DERIVED (PxPlaneGeometry, PxGeometry) //////////////////////////////////////////////////////////////////////////////// -// GeomConvexMesh +// PxConvexMeshGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomconvexmesh, PxGeometry, PxGeomConvexMesh) -OMNI_PVD_ATTRIBUTE (geomconvexmesh, scale, PxGeometry, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (geomconvexmesh, convexMesh, PxGeometry, PxConvexMesh const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) +OMNI_PVD_CLASS_DERIVED (PxConvexMeshGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxConvexMeshGeometry, scale, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxConvexMeshGeometry, convexMesh, PxConvexMesh const *, OmniPvdDataType::eOBJECT_HANDLE, 1) //////////////////////////////////////////////////////////////////////////////// -// ConvexMesh +// PxConvexMesh //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (convexmesh, PxConvexMesh) -OMNI_PVD_ATTRIBUTE (convexmesh, verts, PxConvexMesh, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (convexmesh, tris, PxConvexMesh, PxU32, OmniPvdDataTypeEnum::eUINT32, 0) +OMNI_PVD_CLASS (PxConvexMesh) +OMNI_PVD_ATTRIBUTE (PxConvexMesh, verts, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxConvexMesh, tris, PxU32, OmniPvdDataType::eUINT32, 0) //////////////////////////////////////////////////////////////////////////////// -// GeomHeightfield +// PxHeightFieldGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomheightfield, PxGeometry, PxGeomHeightField) -OMNI_PVD_ATTRIBUTE (geomheightfield, scale,PxGeometry, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (geomheightfield, heightField, PxGeometry,PxHeightField const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) +OMNI_PVD_CLASS_DERIVED (PxHeightFieldGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxHeightFieldGeometry, scale, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxHeightFieldGeometry, heightField, PxHeightField const *, OmniPvdDataType::eOBJECT_HANDLE, 1) //////////////////////////////////////////////////////////////////////////////// -// Heightfield +// PxHeightField //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (heightfield, PxHeightField) -OMNI_PVD_ATTRIBUTE (heightfield, verts, PxHeightField, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (heightfield, tris, PxHeightField, PxU32, OmniPvdDataTypeEnum::eUINT32, 0) +OMNI_PVD_CLASS (PxHeightField) +OMNI_PVD_ATTRIBUTE (PxHeightField, verts, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxHeightField, tris, PxU32, OmniPvdDataType::eUINT32, 0) //////////////////////////////////////////////////////////////////////////////// -// GeomTriangleMesh +// PxTriangleMeshGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomtrianglemesh, PxGeometry, PxGeomTriangleMesh) -OMNI_PVD_ATTRIBUTE (geomtrianglemesh, scale,PxGeometry, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (geomtrianglemesh, triangleMesh, PxGeometry, PxTriangleMesh const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) +OMNI_PVD_CLASS_DERIVED (PxTriangleMeshGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxTriangleMeshGeometry, scale, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxTriangleMeshGeometry, triangleMesh, PxTriangleMesh const *, OmniPvdDataType::eOBJECT_HANDLE, 1) //////////////////////////////////////////////////////////////////////////////// -// TriangleMesh +// PxTriangleMesh //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (trianglemesh, PxTriangleMesh) -OMNI_PVD_ATTRIBUTE (trianglemesh, verts, PxTriangleMesh, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (trianglemesh, tris, PxTriangleMesh, PxU32, OmniPvdDataTypeEnum::eUINT32, 0) +OMNI_PVD_CLASS (PxTriangleMesh) +OMNI_PVD_ATTRIBUTE (PxTriangleMesh, verts, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxTriangleMesh, tris, PxU32, OmniPvdDataType::eUINT32, 0) //////////////////////////////////////////////////////////////////////////////// -// GeomTetrahedronMesh +// PxTetrahedronMeshGeometry //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_FAKE_CLASS (geomtetrahedronmesh, PxGeometry, PxGeomTetrahedronMesh) -OMNI_PVD_ATTRIBUTE (geomtetrahedronmesh, tetrahedronMesh, PxGeometry, PxTetrahedronMesh const *, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) +OMNI_PVD_CLASS_DERIVED (PxTetrahedronMeshGeometry, PxGeometry) +OMNI_PVD_ATTRIBUTE (PxTetrahedronMeshGeometry, tetrahedronMesh, PxTetrahedronMesh const *, OmniPvdDataType::eOBJECT_HANDLE, 1) //////////////////////////////////////////////////////////////////////////////// -// TetrahedronMesh +// PxTetrahedronMesh //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (tetrahedronmesh, PxTetrahedronMesh) -OMNI_PVD_ATTRIBUTE (tetrahedronmesh, verts, PxTetrahedronMesh, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (tetrahedronmesh, tets, PxTetrahedronMesh, PxU32, OmniPvdDataTypeEnum::eUINT32, 0) +OMNI_PVD_CLASS (PxTetrahedronMesh) +OMNI_PVD_ATTRIBUTE (PxTetrahedronMesh, verts, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxTetrahedronMesh, tets, PxU32, OmniPvdDataType::eUINT32, 0) //////////////////////////////////////////////////////////////////////////////// -// SoftBodyMesh +// PxSoftBodyMesh //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (softbodymesh, PxSoftBodyMesh) -OMNI_PVD_ATTRIBUTE (softbodymesh, collisionMesh, PxSoftBodyMesh, PxTetrahedronMesh*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (softbodymesh, simulationMesh, PxSoftBodyMesh, PxTetrahedronMesh*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) +OMNI_PVD_CLASS (PxSoftBodyMesh) +OMNI_PVD_ATTRIBUTE (PxSoftBodyMesh, collisionMesh, PxTetrahedronMesh*, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxSoftBodyMesh, simulationMesh,PxTetrahedronMesh*, OmniPvdDataType::eOBJECT_HANDLE, 1) //////////////////////////////////////////////////////////////////////////////// -// BVH +// PxBVH //////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (bvh, PxBVH) +OMNI_PVD_CLASS (PxBVH) diff --git a/physx/source/physxcharacterkinematic/src/CctBoxController.cpp b/physx/source/physxcharacterkinematic/src/CctBoxController.cpp index 872f6ed51..d093dae44 100644 --- a/physx/source/physxcharacterkinematic/src/CctBoxController.cpp +++ b/physx/source/physxcharacterkinematic/src/CctBoxController.cpp @@ -114,9 +114,9 @@ bool BoxController::updateKinematicProxy() { PxShape* shape = getKineShape(); - PX_ASSERT(shape->getGeometryType() == PxGeometryType::eBOX); - PxBoxGeometry bg; - shape->getBoxGeometry(bg); + const PxGeometry& geom = shape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eBOX); + PxBoxGeometry bg = static_cast(geom); bg.halfExtents = CCTtoProxyExtents(mHalfHeight, mHalfSideExtent, mHalfForwardExtent, mProxyScaleCoeff); shape->setGeometry(bg); @@ -156,14 +156,14 @@ bool BoxController::setHalfForwardExtent(PxF32 halfForwardExtent) PxExtendedVec3 BoxController::getFootPosition() const { PxExtendedVec3 groundPosition = mPosition; // Middle of the CCT - groundPosition -= mUserParams.mUpDirection * (mHalfHeight + mUserParams.mContactOffset); // Ground + sub(groundPosition, mUserParams.mUpDirection * (mHalfHeight + mUserParams.mContactOffset)); // Ground return groundPosition; } bool BoxController::setFootPosition(const PxExtendedVec3& position) { PxExtendedVec3 centerPosition = position; - centerPosition += mUserParams.mUpDirection * (mHalfHeight + mUserParams.mContactOffset); + add(centerPosition, mUserParams.mUpDirection * (mHalfHeight + mUserParams.mContactOffset)); return setPosition(centerPosition); } @@ -189,7 +189,7 @@ void BoxController::resize(PxReal height) const float delta = height - oldHeight; PxExtendedVec3 pos = getPosition(); - pos += mUserParams.mUpDirection * delta; + add(pos, mUserParams.mUpDirection * delta); setPosition(pos); } diff --git a/physx/source/physxcharacterkinematic/src/CctCapsuleController.cpp b/physx/source/physxcharacterkinematic/src/CctCapsuleController.cpp index 944a01be9..2a88f90a9 100644 --- a/physx/source/physxcharacterkinematic/src/CctCapsuleController.cpp +++ b/physx/source/physxcharacterkinematic/src/CctCapsuleController.cpp @@ -96,9 +96,9 @@ bool CapsuleController::setRadius(PxF32 r) { PxShape* shape = getKineShape(); - PX_ASSERT(shape->getGeometryType() == PxGeometryType::eCAPSULE); - PxCapsuleGeometry cg; - shape->getCapsuleGeometry(cg); + const PxGeometry& geom = shape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); + PxCapsuleGeometry cg = static_cast(geom); cg.radius = CCTtoProxyRadius(r, mProxyScaleCoeff); shape->setGeometry(cg); @@ -118,9 +118,9 @@ bool CapsuleController::setHeight(PxF32 h) { PxShape* shape = getKineShape(); - PX_ASSERT(shape->getGeometryType() == PxGeometryType::eCAPSULE); - PxCapsuleGeometry cg; - shape->getCapsuleGeometry(cg); + const PxGeometry& geom = shape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); + PxCapsuleGeometry cg = static_cast(geom); cg.halfHeight = CCTtoProxyHeight(h, mProxyScaleCoeff); shape->setGeometry(cg); @@ -147,15 +147,15 @@ bool CapsuleController::setClimbingMode(PxCapsuleClimbingMode::Enum mode) PxExtendedVec3 CapsuleController::getFootPosition() const { - PxExtendedVec3 groundPosition = mPosition; // Middle of the CCT - groundPosition -= mUserParams.mUpDirection * (mUserParams.mContactOffset+mRadius+mHeight*0.5f); // Ground + PxExtendedVec3 groundPosition = mPosition; // Middle of the CCT + sub(groundPosition, mUserParams.mUpDirection * (mUserParams.mContactOffset+mRadius+mHeight*0.5f)); // Ground return groundPosition; } bool CapsuleController::setFootPosition(const PxExtendedVec3& position) { PxExtendedVec3 centerPosition = position; - centerPosition += mUserParams.mUpDirection * (mUserParams.mContactOffset+mRadius+mHeight*0.5f); + add(centerPosition, mUserParams.mUpDirection * (mUserParams.mContactOffset+mRadius+mHeight*0.5f)); return setPosition(centerPosition); } @@ -167,8 +167,8 @@ void CapsuleController::getCapsule(PxExtendedCapsule& capsule) const PxExtendedVec3 p0 = mPosition; PxExtendedVec3 p1 = mPosition; const PxVec3 extents = mUserParams.mUpDirection*mHeight*0.5f; - p0 -= extents; - p1 += extents; + sub(p0, extents); + add(p1, extents); capsule.p0 = p0; capsule.p1 = p1; @@ -184,7 +184,7 @@ void CapsuleController::resize(PxReal height) const float delta = height - oldHeight; PxExtendedVec3 pos = getPosition(); - pos += mUserParams.mUpDirection * delta * 0.5f; + add(pos, mUserParams.mUpDirection * delta * 0.5f); setPosition(pos); } diff --git a/physx/source/physxcharacterkinematic/src/CctCharacterController.cpp b/physx/source/physxcharacterkinematic/src/CctCharacterController.cpp index ebc972ad9..e1765f46c 100644 --- a/physx/source/physxcharacterkinematic/src/CctCharacterController.cpp +++ b/physx/source/physxcharacterkinematic/src/CctCharacterController.cpp @@ -145,20 +145,20 @@ static PX_INLINE void collisionResponse(PxExtendedVec3& targetPosition, const Px decomposeVector(normalCompo, tangentCompo, reflectDir, hitNormal); // Compute new destination position - const PxF32 amplitude = (targetPosition - currentPosition).magnitude(); + const PxF32 amplitude = diff(targetPosition, currentPosition).magnitude(); targetPosition = currentPosition; if(bump!=0.0f) { if(normalize) normalCompo.normalize(); - targetPosition += normalCompo*bump*amplitude; + add(targetPosition, normalCompo*bump*amplitude); } if(friction!=0.0f) { if(normalize) tangentCompo.normalize(); - targetPosition += tangentCompo*friction*amplitude; + add(targetPosition, tangentCompo*friction*amplitude); } } @@ -1144,8 +1144,8 @@ void SweepTest::onObstacleUpdated(PxObstacleHandle index, const PxObstacleContex void SweepTest::onOriginShift(const PxVec3& shift) { - mCacheBounds.minimum -= shift; - mCacheBounds.maximum -= shift; + sub(mCacheBounds.minimum, shift); + sub(mCacheBounds.maximum, shift); if(mTouchedShape) { @@ -1174,7 +1174,7 @@ void SweepTest::onOriginShift(const PxVec3& shift) { TouchedGeom* currentGeom = reinterpret_cast(data); - currentGeom->mOffset -= shift; + sub(currentGeom->mOffset, shift); PxU8* ptr = reinterpret_cast(data); ptr += GeomSizes[currentGeom->mType]; @@ -1338,14 +1338,14 @@ void SweepTest::updateTouchedGeoms( const InternalCBData_FindTouchedGeom* userDa if(1 && !sideVector.isZero()) { const PxVec3 sn = sideVector.getNormalized(); - float dp0 = PxAbs((worldTemporalBox.maximum - worldTemporalBox.minimum).dot(sn)); - float dp1 = PxAbs((mCacheBounds.maximum - mCacheBounds.minimum).dot(sn)); + float dp0 = PxAbs(diff(worldTemporalBox.maximum, worldTemporalBox.minimum).dot(sn)); + float dp1 = PxAbs(diff(mCacheBounds.maximum, mCacheBounds.minimum).dot(sn)); dp1 -= dp0; dp1 *= 0.5f * 0.9f; const PxVec3 offset = sn * dp1; // printf("%f %f %f\n", offset.x, offset.y, offset.z); - mCacheBounds.minimum += offset; - mCacheBounds.maximum += offset; + add(mCacheBounds.minimum, offset); + add(mCacheBounds.maximum, offset); add(mCacheBounds, worldTemporalBox); PX_ASSERT(worldTemporalBox.isInside(mCacheBounds)); } @@ -1434,14 +1434,14 @@ bool SweepTest::doSweepTest(const InternalCBData_FindTouchedGeom* userData, PxExtendedVec3 currentPosition = swept_volume.mCenter; PxExtendedVec3 targetOrientation = swept_volume.mCenter; - targetOrientation += direction; + add(targetOrientation, direction); PxU32 NbCollisions = 0; while(max_iter--) { mNbIterations++; // Compute current direction - PxVec3 currentDirection = targetOrientation - currentPosition; + PxVec3 currentDirection = diff(targetOrientation, currentPosition); // Make sure the new TBV is still valid { @@ -1662,7 +1662,7 @@ bool SweepTest::doSweepTest(const InternalCBData_FindTouchedGeom* userData, const float DynSkin = mUserParams.mContactOffset; if(C.mDistance>DynSkin/*+0.01f*/) - currentPosition += currentDirection*(C.mDistance-DynSkin); + add(currentPosition, currentDirection*(C.mDistance-DynSkin)); // DE6513 /* else if(sweepPass==SWEEP_PASS_SIDE) { @@ -1734,7 +1734,7 @@ PxControllerCollisionFlags SweepTest::moveCharacter( // Save initial height const PxVec3& upDirection = mUserParams.mUpDirection; - const PxExtended originalHeight = volume.mCenter.dot(upDirection); + const PxExtended originalHeight = dot(volume.mCenter, upDirection); const PxExtended originalBottomPoint = originalHeight - PxExtended(volume.mHalfHeight); // UBI // TEST! Disable auto-step when flying. Not sure this is really useful. @@ -1850,7 +1850,7 @@ PxControllerCollisionFlags SweepTest::moveCharacter( CollisionFlags |= PxControllerCollisionFlag::eCOLLISION_UP; // Clamp step offset to make sure we don't undo more than what we did - float Delta = float(volume.mCenter.dot(upDirection) - originalHeight); + float Delta = float(dot(volume.mCenter, upDirection) - originalHeight); if(Delta originalHeight ? float(tmp - originalHeight) : 0.0f; Delta += fabsf(direction.dot(upDirection)); float Recover = Delta; @@ -2571,7 +2571,7 @@ PxControllerCollisionFlags Controller::move(SweptVolume& volume, const PxVec3& o // Update kinematic actor if(mKineActor) { - const PxVec3 delta = Backup - volume.mCenter; + const PxVec3 delta = diff(Backup, volume.mCenter); const PxF32 deltaM2 = delta.magnitudeSquared(); if(deltaM2!=0.0f) { diff --git a/physx/source/physxcharacterkinematic/src/CctCharacterControllerCallbacks.cpp b/physx/source/physxcharacterkinematic/src/CctCharacterControllerCallbacks.cpp index 6e2eef651..5c37133e9 100644 --- a/physx/source/physxcharacterkinematic/src/CctCharacterControllerCallbacks.cpp +++ b/physx/source/physxcharacterkinematic/src/CctCharacterControllerCallbacks.cpp @@ -39,6 +39,7 @@ #include "common/PxRenderOutput.h" #include "foundation/PxMathUtils.h" #include "foundation/PxAlloca.h" +#include "foundation/PxSIMDHelpers.h" #include "extensions/PxTriangleMeshExt.h" #include "PxScene.h" #include "CctInternalStructs.h" @@ -200,7 +201,7 @@ static void tessellateTriangle(PxU32& nbNewTris, const PxTrianglePadded& tr, PxU static void outputPlaneToStream(PxShape* planeShape, const PxRigidActor* actor, const PxTransform& globalPose, IntArray& geomStream, TriArray& worldTriangles, IntArray& triIndicesArray, const PxExtendedVec3& origin, const PxBounds3& tmpBounds, const CCTParams& params, PxRenderBuffer* renderBuffer) { - PX_ASSERT(planeShape->getGeometryType() == PxGeometryType::ePLANE); + PX_ASSERT(planeShape->getGeometry().getType() == PxGeometryType::ePLANE); const PxF32 length = (tmpBounds.maximum - tmpBounds.minimum).magnitude(); PxVec3 center = toVec3(origin); @@ -250,11 +251,11 @@ static void outputPlaneToStream(PxShape* planeShape, const PxRigidActor* actor, static void outputSphereToStream(PxShape* sphereShape, const PxRigidActor* actor, const PxTransform& globalPose, IntArray& geomStream, const PxExtendedVec3& origin) { - PX_ASSERT(sphereShape->getGeometryType() == PxGeometryType::eSPHERE); + const PxGeometry& geom = sphereShape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eSPHERE); PxExtendedSphere WorldSphere; { - PxSphereGeometry sg; - sphereShape->getSphereGeometry(sg); + const PxSphereGeometry& sg = static_cast(geom); WorldSphere.radius = sg.radius; WorldSphere.center.x = PxExtended(globalPose.p.x); @@ -294,11 +295,11 @@ static void outputCustomToStream(PxShape* customShape, const PxRigidActor* actor static void outputCapsuleToStream(PxShape* capsuleShape, const PxRigidActor* actor, const PxTransform& globalPose, IntArray& geomStream, const PxExtendedVec3& origin) { - PX_ASSERT(capsuleShape->getGeometryType() == PxGeometryType::eCAPSULE); + const PxGeometry& geom = capsuleShape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); PxExtendedCapsule WorldCapsule; { - PxCapsuleGeometry cg; - capsuleShape->getCapsuleGeometry(cg); + const PxCapsuleGeometry& cg = static_cast(geom); PxVec3 p0 = cg.halfHeight * globalPose.q.getBasisVector0(); PxVec3 p1 = -p0; @@ -333,9 +334,9 @@ static void outputCapsuleToStream(PxShape* capsuleShape, const PxRigidActor* act static void outputBoxToStream( PxShape* boxShape, const PxRigidActor* actor, const PxTransform& globalPose, IntArray& geomStream, TriArray& worldTriangles, IntArray& triIndicesArray, const PxExtendedVec3& origin, const PxBounds3& tmpBounds, const CCTParams& params, PxU16& nbTessellation) { - PX_ASSERT(boxShape->getGeometryType() == PxGeometryType::eBOX); - PxBoxGeometry bg; - boxShape->getBoxGeometry(bg); + const PxGeometry& geom = boxShape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eBOX); + const PxBoxGeometry& bg = static_cast(geom); //8 verts in local space. const PxF32 dx = bg.halfExtents.x; @@ -505,11 +506,11 @@ static PxU32 createInvisibleWalls(const CCTParams& params, const PxTriangle& cur static void outputMeshToStream( PxShape* meshShape, const PxRigidActor* actor, const PxTransform& meshPose, IntArray& geomStream, TriArray& worldTriangles, IntArray& triIndicesArray, const PxExtendedVec3& origin, const PxBounds3& tmpBounds, const CCTParams& params, PxRenderBuffer* renderBuffer, PxU16& nbTessellation) { - PX_ASSERT(meshShape->getGeometryType() == PxGeometryType::eTRIANGLEMESH); + const PxGeometry& geom = meshShape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eTRIANGLEMESH); // Do AABB-mesh query - PxTriangleMeshGeometry triGeom; - meshShape->getTriangleMeshGeometry(triGeom); + const PxTriangleMeshGeometry& triGeom = static_cast(geom); const PxBoxGeometry boxGeom(tmpBounds.getExtents()); const PxTransform boxPose(tmpBounds.getCenter()); @@ -649,11 +650,11 @@ static void outputMeshToStream( PxShape* meshShape, const PxRigidActor* actor, c static void outputHeightFieldToStream( PxShape* hfShape, const PxRigidActor* actor, const PxTransform& heightfieldPose, IntArray& geomStream, TriArray& worldTriangles, IntArray& triIndicesArray, const PxExtendedVec3& origin, const PxBounds3& tmpBounds, const CCTParams& params, PxRenderBuffer* renderBuffer, PxU16& nbTessellation) { - PX_ASSERT(hfShape->getGeometryType() == PxGeometryType::eHEIGHTFIELD); + const PxGeometry& geom = hfShape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eHEIGHTFIELD); // Do AABB-mesh query - PxHeightFieldGeometry hfGeom; - hfShape->getHeightFieldGeometry(hfGeom); + const PxHeightFieldGeometry& hfGeom = static_cast(geom); const PxBoxGeometry boxGeom(tmpBounds.getExtents()); const PxTransform boxPose(tmpBounds.getCenter()); @@ -789,9 +790,9 @@ static void outputHeightFieldToStream( PxShape* hfShape, const PxRigidActor* act static void outputConvexToStream(PxShape* convexShape, const PxRigidActor* actor, const PxTransform& absPose_, IntArray& geomStream, TriArray& worldTriangles, IntArray& triIndicesArray, const PxExtendedVec3& origin, const PxBounds3& tmpBounds, const CCTParams& params, PxRenderBuffer* renderBuffer, PxU16& nbTessellation) { - PX_ASSERT(convexShape->getGeometryType() == PxGeometryType::eCONVEXMESH); - PxConvexMeshGeometry cg; - convexShape->getConvexMeshGeometry(cg); + const PxGeometry& geom = convexShape->getGeometry(); + PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH); + const PxConvexMeshGeometry& cg = static_cast(geom); PX_ASSERT(cg.convexMesh); // Do AABB-mesh query @@ -842,13 +843,13 @@ static void outputConvexToStream(PxShape* convexShape, const PxRigidActor* actor } // PT: you can't use PxTransform with a non-uniform scaling - const PxMat33 rot = PxMat33(absPose_.q) * cg.scale.toMat33(); + const PxMat33 rot = PxMat33Padded(absPose_.q) * cg.scale.toMat33(); const PxMat44 absPose(rot, absPose_.p); const PxVec3 absPosTmp = absPose.getPosition(); const PxExtendedVec3 absPos(PxExtended(absPosTmp.x), PxExtended(absPosTmp.y), PxExtended(absPosTmp.z)); - const PxVec3 MeshOffset(absPos - origin); // LOSS OF ACCURACY + const PxVec3 MeshOffset(diff(absPos, origin)); // LOSS OF ACCURACY const PxVec3 offset(float(-origin.x), float(-origin.y), float(-origin.z)); @@ -976,8 +977,12 @@ void Cct::findTouchedGeometry( PxOverlapBuffer hitBuffer(hits, size); sceneQueryFilterData.flags |= PxQueryFlag::eNO_BLOCK; // fix for DE8255 - scene->overlap(PxBoxGeometry(extents), PxTransform(center), hitBuffer, sceneQueryFilterData, filter.mFilterCallback); - PxU32 numberHits = hitBuffer.getNbAnyHits(); + PxU32 numberHits = 0; + if (extents.x > 0.0f && extents.y > 0.0f && extents.z > 0.0f) + { + scene->overlap(PxBoxGeometry(extents), PxTransform(center), hitBuffer, sceneQueryFilterData, filter.mFilterCallback); + numberHits = hitBuffer.getNbAnyHits(); + } for(PxU32 i = 0; i < numberHits; i++) { const PxOverlapHit& hit = hitBuffer.getAnyHit(i); @@ -1002,7 +1007,7 @@ void Cct::findTouchedGeometry( // Output shape to stream const PxTransform globalPose = getShapeGlobalPose(*shape, *actor); - const PxGeometryType::Enum type = shape->getGeometryType(); // ### VIRTUAL! + const PxGeometryType::Enum type = shape->getGeometry().getType(); // ### VIRTUAL! if(type==PxGeometryType::eSPHERE) outputSphereToStream (shape, actor, globalPose, geomStream, Origin); else if(type==PxGeometryType::eCAPSULE) outputCapsuleToStream (shape, actor, globalPose, geomStream, Origin); else if(type==PxGeometryType::eBOX) outputBoxToStream (shape, actor, globalPose, geomStream, worldTriangles, triIndicesArray, Origin, tmpBounds, params, nbTessellation); diff --git a/physx/source/physxcharacterkinematic/src/CctController.cpp b/physx/source/physxcharacterkinematic/src/CctController.cpp index 9174a977e..687f58e13 100644 --- a/physx/source/physxcharacterkinematic/src/CctController.cpp +++ b/physx/source/physxcharacterkinematic/src/CctController.cpp @@ -106,7 +106,7 @@ void Controller::onRelease(const PxBase& observed) void Controller::onOriginShift(const PxVec3& shift) { - mPosition -= shift; + sub(mPosition, shift); if(mManager && mManager->mLockingEnabled) mWriteLock.lock(); diff --git a/physx/source/physxcharacterkinematic/src/CctObstacleContext.cpp b/physx/source/physxcharacterkinematic/src/CctObstacleContext.cpp index 9ae34b681..cf205911e 100644 --- a/physx/source/physxcharacterkinematic/src/CctObstacleContext.cpp +++ b/physx/source/physxcharacterkinematic/src/CctObstacleContext.cpp @@ -529,8 +529,8 @@ const PxObstacle* ObstacleContext::raycastSingle(PxGeomRaycastHit& hit, const Px void ObstacleContext::onOriginShift(const PxVec3& shift) { for(PxU32 i=0; i < mBoxObstacles.size(); i++) - mBoxObstacles[i].mData.mPos -= shift; + sub(mBoxObstacles[i].mData.mPos, shift); for(PxU32 i=0; i < mCapsuleObstacles.size(); i++) - mCapsuleObstacles[i].mData.mPos -= shift; + sub(mCapsuleObstacles[i].mData.mPos, shift); } diff --git a/physx/source/physxcharacterkinematic/src/CctSweptVolume.cpp b/physx/source/physxcharacterkinematic/src/CctSweptVolume.cpp index 7d106b109..5fdd9ab64 100644 --- a/physx/source/physxcharacterkinematic/src/CctSweptVolume.cpp +++ b/physx/source/physxcharacterkinematic/src/CctSweptVolume.cpp @@ -55,7 +55,7 @@ void Cct::computeTemporalBox(PxExtendedBounds3& _box, float radius, float height { PxExtendedBounds3 destBox; PxExtendedVec3 tmp = center; - tmp += direction; + add(tmp, direction); setCenterExtents(destBox, tmp, extents); add(box, destBox); } @@ -64,7 +64,7 @@ void Cct::computeTemporalBox(PxExtendedBounds3& _box, float radius, float height { PxExtendedBounds3 destBox; PxExtendedVec3 tmp = center; - tmp -= upDirection * maxJumpHeight; + sub(tmp, upDirection * maxJumpHeight); setCenterExtents(destBox, tmp, extents); add(box, destBox); } diff --git a/physx/source/physxcharacterkinematic/src/CctUtils.h b/physx/source/physxcharacterkinematic/src/CctUtils.h index cee5a3c90..53f6f4fdb 100644 --- a/physx/source/physxcharacterkinematic/src/CctUtils.h +++ b/physx/source/physxcharacterkinematic/src/CctUtils.h @@ -64,6 +64,21 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) #ifdef PX_BIG_WORLDS + PX_INLINE void add(PxExtendedVec3& p, const PxVec3& e) + { + p += PxExtendedVec3(PxExtended(e.x), PxExtended(e.y), PxExtended(e.z)); + } + + PX_INLINE void sub(PxExtendedVec3& p, const PxVec3& e) + { + p -= PxExtendedVec3(PxExtended(e.x), PxExtended(e.y), PxExtended(e.z)); + } + + PX_INLINE PxExtended dot(const PxExtendedVec3& p, const PxVec3& e) + { + return p.dot(PxExtendedVec3(PxExtended(e.x), PxExtended(e.y), PxExtended(e.z))); + } + class PxExtendedBox { public: @@ -97,7 +112,7 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) PX_INLINE void computeDirection(PxVec3& dir) const { - dir = p1 - p0; + dir = diff(p1, p0); } PX_INLINE void computePoint(PxExtendedVec3& pt, PxExtended t) const @@ -131,8 +146,8 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) PX_INLINE void set(PxExtended minx, PxExtended miny, PxExtended minz, PxExtended maxx, PxExtended maxy, PxExtended maxz) { - minimum.set(minx, miny, minz); - maximum.set(maxx, maxy, maxz); + minimum = PxExtendedVec3(minx, miny, minz); + maximum = PxExtendedVec3(maxx, maxy, maxz); } PX_INLINE bool isInside(const PxExtendedBounds3& box) const @@ -156,14 +171,15 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) PX_INLINE void getExtents(const PxExtendedBounds3& b, PxVec3& extents) { - extents = b.maximum - b.minimum; + extents = diff(b.maximum, b.minimum); extents *= 0.5f; } PX_INLINE void setCenterExtents(PxExtendedBounds3& b, const PxExtendedVec3& c, const PxVec3& e) { - b.minimum = c; b.minimum -= e; - b.maximum = c; b.maximum += e; + const PxExtendedVec3 eExt(PxExtended(e.x), PxExtended(e.y), PxExtended(e.z)); + b.minimum = c - eExt; + b.maximum = c + eExt; } PX_INLINE void add(PxExtendedBounds3& b, const PxExtendedBounds3& b2) @@ -171,8 +187,8 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) // - if we're empty, minimum = MAX,MAX,MAX => minimum will be b2 in all cases => it will copy b2, ok // - if b2 is empty, the opposite happens => keep us unchanged => ok // => same behaviour as before, automatically - b.minimum.minimum(b2.minimum); - b.maximum.maximum(b2.maximum); + b.minimum = b.minimum.minimum(b2.minimum); + b.maximum = b.maximum.maximum(b2.maximum); } #else @@ -187,14 +203,6 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) typedef Gu::Capsule PxExtendedCapsule; typedef PxBounds3 PxExtendedBounds3; - PX_INLINE PxExtended distance(const PxVec3& v2, const PxVec3& v) - { - const PxExtended dx = v2.x - v.x; - const PxExtended dy = v2.y - v.y; - const PxExtended dz = v2.z - v.z; - return PxSqrt(dx * dx + dy * dy + dz * dz); - } - PX_INLINE void getCenter(const PxBounds3& b, PxVec3& center) { center = b.minimum + b.maximum; @@ -218,8 +226,8 @@ PX_FORCE_INLINE bool isAlmostZero(const PxVec3& v) // - if we're empty, minimum = MAX,MAX,MAX => minimum will be b2 in all cases => it will copy b2, ok // - if b2 is empty, the opposite happens => keep us unchanged => ok // => same behaviour as before, automatically - b.minimum.minimum(b2.minimum); - b.maximum.maximum(b2.maximum); + b.minimum = b.minimum.minimum(b2.minimum); + b.maximum = b.maximum.maximum(b2.maximum); } #endif diff --git a/physx/source/physxcooking/src/Cooking.cpp b/physx/source/physxcooking/src/Cooking.cpp index e1fc7ae77..d16dd81ec 100644 --- a/physx/source/physxcooking/src/Cooking.cpp +++ b/physx/source/physxcooking/src/Cooking.cpp @@ -35,204 +35,22 @@ using namespace physx; using namespace Gu; -/////////////////////////////////////////////////////////////////////////////// - -void Cooking::setParams(const PxCookingParams& params) -{ - mParams = params; -} - -const PxCookingParams& Cooking::getParams() const -{ - return mParams; -} - -/////////////////////////////////////////////////////////////////////////////// - -bool Cooking::platformMismatch() const -{ - return immediateCooking::platformMismatch(); -} - -/////////////////////////////////////////////////////////////////////////////// - -void Cooking::release() -{ - PX_DELETE_THIS; - - PxDecFoundationRefCount(); -} - -/////////////////////////////////////////////////////////////////////////////// - -bool Cooking::validateTriangleMesh(const PxTriangleMeshDesc& desc) const -{ - return immediateCooking::validateTriangleMesh(mParams, desc); -} - -bool Cooking::cookTriangleMesh(const PxTriangleMeshDesc& desc, PxOutputStream& stream, PxTriangleMeshCookingResult::Enum* condition) const -{ - return immediateCooking::cookTriangleMesh(mParams, desc, stream, condition); -} - -PxTriangleMesh* Cooking::createTriangleMesh(const PxTriangleMeshDesc& desc, PxInsertionCallback& insertionCallback, PxTriangleMeshCookingResult::Enum* condition) const -{ - return immediateCooking::createTriangleMesh(mParams, desc, insertionCallback, condition); -} - -/////////////////////////////////////////////////////////////////////////////// - -PxTetrahedronMesh* Cooking::createTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxInsertionCallback& insertionCallback) const -{ - return immediateCooking::createTetrahedronMesh(mParams, meshDesc, insertionCallback); -} - -bool Cooking::cookTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxOutputStream& stream) const -{ - return immediateCooking::cookTetrahedronMesh(mParams, meshDesc, stream); -} - -/////////////////////////////////////////////////////////////////////////////// - -bool Cooking::cookSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, - const PxSoftBodySimulationDataDesc& softbodyDataDesc, PxOutputStream& stream) const -{ - return immediateCooking::cookSoftBodyMesh(mParams, simulationMeshDesc, collisionMeshDesc, softbodyDataDesc, stream); -} - -PxCollisionMeshMappingData* Cooking::computeModelsMapping(PxTetrahedronMeshData& simulationMesh, const PxTetrahedronMeshData& collisionMesh, const PxSoftBodyCollisionData& collisionData, const PxBoundedData* vertexToTet) const -{ - return immediateCooking::computeModelsMapping(mParams, simulationMesh, collisionMesh, collisionData, vertexToTet); -} - -PxCollisionTetrahedronMeshData* Cooking::computeCollisionData(const PxTetrahedronMeshDesc& collisionMeshDesc) const -{ - return immediateCooking::computeCollisionData(mParams, collisionMeshDesc); -} - -PxSimulationTetrahedronMeshData* Cooking::computeSimulationData(const PxTetrahedronMeshDesc& simulationMeshDesc) const -{ - return immediateCooking::computeSimulationData(mParams, simulationMeshDesc); -} - -PxSoftBodyMesh* Cooking::assembleSoftBodyMesh(PxTetrahedronMeshData& simulationMesh, PxSoftBodySimulationData& simulationData, PxTetrahedronMeshData& collisionMesh, - PxSoftBodyCollisionData& collisionData, PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const -{ - return immediateCooking::assembleSoftBodyMesh(simulationMesh, simulationData, collisionMesh, collisionData, mappingData, insertionCallback); -} - -PxSoftBodyMesh* Cooking::assembleSoftBodyMesh(PxSimulationTetrahedronMeshData& simulationMesh, PxCollisionTetrahedronMeshData& collisionMesh, PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const -{ - return immediateCooking::assembleSoftBodyMesh_Sim(simulationMesh, collisionMesh, mappingData, insertionCallback); -} - -PxSoftBodyMesh* Cooking::createSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, - const PxSoftBodySimulationDataDesc& softbodyDataDesc, PxInsertionCallback& insertionCallback) const -{ - return immediateCooking::createSoftBodyMesh(mParams, simulationMeshDesc, collisionMeshDesc, softbodyDataDesc, insertionCallback); -} - -/////////////////////////////////////////////////////////////////////////////// - -// cook convex mesh from given desc, save the results into stream -bool Cooking::cookConvexMesh(const PxConvexMeshDesc& desc, PxOutputStream& stream, PxConvexMeshCookingResult::Enum* condition) const -{ - return immediateCooking::cookConvexMesh(mParams, desc, stream, condition); -} - -// cook convex mesh from given desc, copy the results into internal convex mesh -// and insert the mesh into PxPhysics -PxConvexMesh* Cooking::createConvexMesh(const PxConvexMeshDesc& desc, PxInsertionCallback& insertionCallback, PxConvexMeshCookingResult::Enum* condition) const -{ - return immediateCooking::createConvexMesh(mParams, desc, insertionCallback, condition); -} - -bool Cooking::validateConvexMesh(const PxConvexMeshDesc& desc) const -{ - return immediateCooking::validateConvexMesh(mParams, desc); -} - -bool Cooking::computeHullPolygons(const PxSimpleTriangleMesh& mesh, PxAllocatorCallback& inCallback,PxU32& nbVerts, PxVec3*& vertices, - PxU32& nbIndices, PxU32*& indices, PxU32& nbPolygons, PxHullPolygon*& hullPolygons) const -{ - return immediateCooking::computeHullPolygons(mParams, mesh, inCallback, nbVerts, vertices, nbIndices, indices, nbPolygons, hullPolygons); -} - -/////////////////////////////////////////////////////////////////////////////// - -bool Cooking::cookHeightField(const PxHeightFieldDesc& desc, PxOutputStream& stream) const -{ - return immediateCooking::cookHeightField(desc, stream); -} - -PxHeightField* Cooking::createHeightField(const PxHeightFieldDesc& desc, PxInsertionCallback& insertionCallback) const -{ - return immediateCooking::createHeightField(desc, insertionCallback); -} - -/////////////////////////////////////////////////////////////////////////////// - -bool Cooking::cookBVH(const PxBVHDesc& desc, PxOutputStream& stream) const -{ - return immediateCooking::cookBVH(desc, stream); -} - -PxBVH* Cooking::createBVH(const PxBVHDesc& desc, PxInsertionCallback& insertionCallback) const -{ - return immediateCooking::createBVH(desc, insertionCallback); -} - -/////////////////////////////////////////////////////////////////////////////// - -PxInsertionCallback& Cooking::getStandaloneInsertionCallback() -{ - return *immediateCooking::getInsertionCallback(); -} - -/////////////////////////////////////////////////////////////////////////////// - -PxCooking* PxCreateCooking(PxU32 /*version*/, PxFoundation& foundation, const PxCookingParams& params) -{ - PX_ASSERT(&foundation == &PxGetFoundation()); - PX_UNUSED(foundation); - - PxIncFoundationRefCount(); - - return PX_NEW(Cooking)(params); -} - -/////////////////////////////////////////////////////////////////////////////// - -// PT: temporary for Kit - #include "cooking/PxCookingInternal.h" #include "GuTriangleMeshBV4.h" -PxTriangleMesh* Cooking::createTriangleMesh(const PxTriangleMeshInternalData& data) const +physx::PxTriangleMesh* PxCreateTriangleMeshInternal(const physx::PxTriangleMeshInternalData& data) { TriangleMesh* np; PX_NEW_SERIALIZED(np, BV4TriangleMesh)(data); return np; } -PxBVH* Cooking::createBVH(const PxBVHInternalData& data) const +physx::PxBVH* PxCreateBVHInternal(const physx::PxBVHInternalData& data) { BVH* np; PX_NEW_SERIALIZED(np, BVH)(data); return np; } -physx::PxTriangleMesh* PxCreateTriangleMeshInternal(const physx::PxTriangleMeshInternalData& data, const physx::PxCooking& cooking) -{ - return static_cast(cooking).createTriangleMesh(data); -} - -physx::PxBVH* PxCreateBVHInternal(const physx::PxBVHInternalData& data, const physx::PxCooking& cooking) -{ - return static_cast(cooking).createBVH(data); -} - -//~ PT: temporary for Kit - /////////////////////////////////////////////////////////////////////////////// PxInsertionCallback* PxGetStandaloneInsertionCallback() diff --git a/physx/source/physxcooking/src/Cooking.h b/physx/source/physxcooking/src/Cooking.h index fef1f4d44..fb76eb055 100644 --- a/physx/source/physxcooking/src/Cooking.h +++ b/physx/source/physxcooking/src/Cooking.h @@ -43,53 +43,6 @@ class ConvexHullLib; class PxInsertionCallback; struct PxTriangleMeshInternalData; struct PxBVHInternalData; - -class Cooking : public PxCooking, public PxUserAllocated -{ -public: - Cooking(const PxCookingParams& params): mParams(params) {} - - virtual void release(); - virtual void setParams(const PxCookingParams& params); - virtual const PxCookingParams& getParams() const; - virtual bool platformMismatch() const; - virtual bool cookTriangleMesh(const PxTriangleMeshDesc& desc, PxOutputStream& stream, PxTriangleMeshCookingResult::Enum* condition = NULL) const; - virtual PxTriangleMesh* createTriangleMesh(const PxTriangleMeshDesc& desc, PxInsertionCallback& insertionCallback, PxTriangleMeshCookingResult::Enum* condition = NULL) const; - virtual bool validateTriangleMesh(const PxTriangleMeshDesc& desc) const; - - virtual bool cookSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, - const PxSoftBodySimulationDataDesc& softbodyDataDesc, PxOutputStream& stream) const; - virtual PxSoftBodyMesh* createSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, - const PxSoftBodySimulationDataDesc& softbodyDataDesc, PxInsertionCallback& insertionCallback) const; - - virtual bool cookTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxOutputStream& stream) const; - virtual PxTetrahedronMesh* createTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxInsertionCallback& insertionCallback) const; - - virtual PxCollisionMeshMappingData* computeModelsMapping(PxTetrahedronMeshData& simulationMesh, const PxTetrahedronMeshData& collisionMesh, const PxSoftBodyCollisionData& collisionData, const PxBoundedData* vertexToTet) const; - virtual PxCollisionTetrahedronMeshData* computeCollisionData(const PxTetrahedronMeshDesc& collisionMeshDesc) const; - virtual PxSimulationTetrahedronMeshData* computeSimulationData(const PxTetrahedronMeshDesc& simulationMeshDesc) const; - virtual PxSoftBodyMesh* assembleSoftBodyMesh(PxTetrahedronMeshData& simulationMesh, PxSoftBodySimulationData& simulationData, PxTetrahedronMeshData& collisionMesh, - PxSoftBodyCollisionData& collisionData, PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const; - virtual PxSoftBodyMesh* assembleSoftBodyMesh(PxSimulationTetrahedronMeshData& simulationMesh, PxCollisionTetrahedronMeshData& collisionMesh, PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const; - - virtual bool cookConvexMesh(const PxConvexMeshDesc& desc, PxOutputStream& stream, PxConvexMeshCookingResult::Enum* condition) const; - virtual PxConvexMesh* createConvexMesh(const PxConvexMeshDesc& desc, PxInsertionCallback& insertionCallback, PxConvexMeshCookingResult::Enum* condition) const; - virtual bool validateConvexMesh(const PxConvexMeshDesc& desc) const; - virtual bool computeHullPolygons(const PxSimpleTriangleMesh& mesh, PxAllocatorCallback& inCallback,PxU32& nbVerts, PxVec3*& vertices, - PxU32& nbIndices, PxU32*& indices, PxU32& nbPolygons, PxHullPolygon*& hullPolygons) const; - virtual bool cookHeightField(const PxHeightFieldDesc& desc, PxOutputStream& stream) const; - virtual PxHeightField* createHeightField(const PxHeightFieldDesc& desc, PxInsertionCallback& insertionCallback) const; - virtual bool cookBVH(const PxBVHDesc& desc, PxOutputStream& stream) const; - virtual PxBVH* createBVH(const PxBVHDesc& desc, PxInsertionCallback& insertionCallback) const; - virtual PxInsertionCallback& getStandaloneInsertionCallback(); - - PxTriangleMesh* createTriangleMesh(const PxTriangleMeshInternalData& data) const; - PxBVH* createBVH(const PxBVHInternalData& data) const; - -private: - PxCookingParams mParams; -}; - } #endif diff --git a/physx/source/physxextensions/src/ExtConstraintHelper.h b/physx/source/physxextensions/src/ExtConstraintHelper.h index 084338550..5984ae167 100644 --- a/physx/source/physxextensions/src/ExtConstraintHelper.h +++ b/physx/source/physxextensions/src/ExtConstraintHelper.h @@ -43,86 +43,20 @@ namespace Ext { namespace joint { - PX_INLINE void computeJointFrames(PxTransform& cA2w, PxTransform& cB2w, const JointData& data, const PxTransform& bA2w, const PxTransform& bB2w) + PX_FORCE_INLINE void applyNeighborhoodOperator(const PxTransform32& cA2w, PxTransform32& cB2w) { - PX_ASSERT(bA2w.isValid() && bB2w.isValid()); - - cA2w = bA2w.transform(data.c2b[0]); - cB2w = bB2w.transform(data.c2b[1]); - - PX_ASSERT(cA2w.isValid() && cB2w.isValid()); + if(cA2w.q.dot(cB2w.q)<0.0f) // minimum dist quat (equiv to flipping cB2bB.q, which we don't use anywhere) + cB2w.q = -cB2w.q; } - PX_INLINE void computeDerived(const JointData& data, - const PxTransform& bA2w, const PxTransform& bB2w, - PxTransform& cA2w, PxTransform& cB2w, PxTransform& cB2cA, - bool useShortestPath=true) + PX_INLINE void computeJointFrames(PxTransform32& cA2w, PxTransform32& cB2w, const JointData& data, const PxTransform& bA2w, const PxTransform& bB2w) { - computeJointFrames(cA2w, cB2w, data, bA2w, bB2w); - - if(useShortestPath) - { - if(cA2w.q.dot(cB2w.q)<0.0f) // minimum error quat - cB2w.q = -cB2w.q; - } - - cB2cA = cA2w.transformInv(cB2w); - PX_ASSERT(cB2cA.isValid()); - } - - PX_INLINE PxVec3 truncateLinear(const PxVec3& in, PxReal tolerance, bool& truncated) - { - const PxReal m = in.magnitudeSquared(); - truncated = m>tolerance * tolerance; - return truncated ? in * PxRecipSqrt(m) * tolerance : in; - } - - PX_INLINE PxQuat truncateAngular(const PxQuat& in, PxReal sinHalfTol, PxReal cosHalfTol, bool& truncated) - { - truncated = false; - - if(sinHalfTol > 0.9999f) // fixes numerical tolerance issue of projecting because quat is not exactly normalized - return in; - - const PxQuat q = in.w>=0.0f ? in : -in; - - const PxVec3 im = q.getImaginaryPart(); - const PxReal m = im.magnitudeSquared(); - truncated = m>sinHalfTol*sinHalfTol; - if(!truncated) - return in; - - const PxVec3 outV = im * sinHalfTol * PxRecipSqrt(m); - return PxQuat(outV.x, outV.y, outV.z, cosHalfTol); - } - - PX_FORCE_INLINE void projectTransforms(PxTransform& bA2w, PxTransform& bB2w, - const PxTransform& cA2w, const PxTransform& cB2w, - const PxTransform& cB2cA, const JointData& data, bool projectToA) - { - PX_ASSERT(cB2cA.isValid()); - - // normalization here is unfortunate: long chains of projected constraints can result in - // accumulation of error in the quaternion which eventually leaves the quaternion - // magnitude outside the validation range. The approach here is slightly overconservative - // in that we could just normalize the quaternions which are out of range, but since we - // regard projection as an occasional edge case it shouldn't be perf-sensitive, and - // this way we maintain the invariant (also maintained by the dynamics integrator) that - // body quats are properly normalized up to FP error. + PX_ASSERT(bA2w.isValid() && bB2w.isValid()); - if(projectToA) - { - bB2w = cA2w.transform(cB2cA.transform(data.c2b[1].getInverse())); - bB2w.q.normalize(); - } - else - { - bA2w = cB2w.transform(cB2cA.transformInv(data.c2b[0].getInverse())); - bA2w.q.normalize(); - } + aos::transformMultiply(cA2w, bA2w, data.c2b[0]); + aos::transformMultiply(cB2w, bB2w, data.c2b[1]); - PX_ASSERT(bA2w.isValid()); - PX_ASSERT(bB2w.isValid()); + PX_ASSERT(cA2w.isValid() && cB2w.isValid()); } PX_INLINE void computeJacobianAxes(PxVec3 row[3], const PxQuat& qa, const PxQuat& qb) @@ -184,15 +118,17 @@ namespace Ext { Px1DConstraint* mConstraints; Px1DConstraint* mCurrent; - PxVec3 mRa, mRb; - PxVec3 mCA2w, mCB2w; + PX_ALIGN(16, PxVec3p mRa); + PX_ALIGN(16, PxVec3p mRb); + PX_ALIGN(16, PxVec3p mCA2w); + PX_ALIGN(16, PxVec3p mCB2w); public: ConstraintHelper(Px1DConstraint* c, const PxVec3& ra, const PxVec3& rb) : mConstraints(c), mCurrent(c), mRa(ra), mRb(rb) {} /*PX_NOINLINE*/ ConstraintHelper(Px1DConstraint* c, PxConstraintInvMassScale& invMassScale, - PxTransform& cA2w, PxTransform& cB2w, PxVec3p& body0WorldOffset, + PxTransform32& cA2w, PxTransform32& cB2w, PxVec3p& body0WorldOffset, const JointData& data, const PxTransform& bA2w, const PxTransform& bB2w) : mConstraints(c), mCurrent(c) { @@ -202,14 +138,33 @@ namespace Ext computeJointFrames(cA2w, cB2w, data, bA2w, bB2w); - const PxVec3 ra = cB2w.p - bA2w.p; - body0WorldOffset = ra; + if(1) + { + const Vec4V cB2wV = V4LoadA(&cB2w.p.x); + const Vec4V raV = V4Sub(cB2wV, V4LoadU(&bA2w.p.x)); // const PxVec3 ra = cB2w.p - bA2w.p; + + V4StoreU(raV, &body0WorldOffset.x); // body0WorldOffset = ra; + + V4StoreA(raV, &mRa.x); // mRa = ra; - mRa = ra; - mRb = cB2w.p - bB2w.p; + V4StoreA(V4Sub(cB2wV, V4LoadU(&bB2w.p.x)), &mRb.x); // mRb = cB2w.p - bB2w.p; - mCA2w = cA2w.p; - mCB2w = cB2w.p; + V4StoreA(V4LoadA(&cA2w.p.x), &mCA2w.x); // mCA2w = cA2w.p; + V4StoreA(cB2wV, &mCB2w.x); // mCB2w = cB2w.p; + } + else + { + const PxVec3 ra = cB2w.p - bA2w.p; + + body0WorldOffset = ra; + + mRa = ra; + + mRb = cB2w.p - bB2w.p; + + mCA2w = cA2w.p; + mCB2w = cB2w.p; + } } PX_FORCE_INLINE const PxVec3& getRa() const { return mRa; } @@ -231,18 +186,13 @@ namespace Ext // limited linear & angular PX_FORCE_INLINE void linearLimit(const PxVec3& axis, PxReal ordinate, PxReal limitValue, const PxJointLimitParameters& limit) { - const PxReal pad = limit.isSoft() ? 0.0f : limit.contactDistance_deprecated; - - if(ordinate + pad > limitValue) + if(!limit.isSoft() || ordinate > limitValue) addLimit(linear(axis, limitValue - ordinate, PxConstraintSolveHint::eNONE), limit); } - PX_FORCE_INLINE void angularLimit(const PxVec3& axis, PxReal ordinate, PxReal limitValue, PxReal pad, const PxJointLimitParameters& limit) + PX_FORCE_INLINE void angularLimit(const PxVec3& axis, PxReal ordinate, PxReal limitValue, const PxJointLimitParameters& limit) { - if(limit.isSoft()) - pad = 0.0f; - - if(ordinate + pad > limitValue) + if(!limit.isSoft() || ordinate > limitValue) addLimit(angular(axis, limitValue - ordinate, PxConstraintSolveHint::eNONE), limit); } @@ -251,15 +201,14 @@ namespace Ext addLimit(angular(axis, error, PxConstraintSolveHint::eNONE), limit); } - PX_FORCE_INLINE void anglePair(PxReal angle, PxReal lower, PxReal upper, PxReal pad, const PxVec3& axis, const PxJointLimitParameters& limit) + PX_FORCE_INLINE void anglePair(PxReal angle, PxReal lower, PxReal upper, const PxVec3& axis, const PxJointLimitParameters& limit) { PX_ASSERT(lower upper-pad) + if(!softLimit || angle > upper) angularLimit(axis, (upper - angle), limit); } @@ -277,7 +226,7 @@ namespace Ext PX_FORCE_INLINE PxU32 getCount() const { return PxU32(mCurrent - mConstraints); } - void prepareLockedAxes(const PxQuat& qA, const PxQuat& qB, const PxVec3& cB2cAp, PxU32 lin, PxU32 ang, PxVec3& raOut, PxVec3& rbOut) + void prepareLockedAxes(const PxQuat& qA, const PxQuat& qB, const PxVec3& cB2cAp, PxU32 lin, PxU32 ang, PxVec3& raOut, PxVec3& rbOut, PxVec3* axis=NULL) { Px1DConstraint* current = mCurrent; @@ -288,6 +237,8 @@ namespace Ext if(lin) { const PxMat33Padded axes(qA); + if(axis) + *axis = axes.column0; if(lin&1) errorVector -= axes.column0 * cB2cAp.x; if(lin&2) errorVector -= axes.column1 * cB2cAp.y; diff --git a/physx/source/physxextensions/src/ExtContactJoint.cpp b/physx/source/physxextensions/src/ExtContactJoint.cpp index ec6dc6b71..129807c3c 100644 --- a/physx/source/physxextensions/src/ExtContactJoint.cpp +++ b/physx/source/physxextensions/src/ExtContactJoint.cpp @@ -55,9 +55,8 @@ void ContactJoint::setContact(const PxVec3& contact) PX_CHECK_AND_RETURN(contact.isFinite(), "PxContactJoint::setContact: invalid parameter"); data().contact = contact; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, contactPoint, static_cast(*this), getContact()) -#endif + + OMNI_PVD_SET(PxContactJoint, point, static_cast(*this), getContact()) } PxVec3 ContactJoint::getContactNormal() const @@ -70,9 +69,8 @@ void ContactJoint::setContactNormal(const PxVec3& normal) PX_CHECK_AND_RETURN(normal.isFinite(), "PxContactJoint::setContactNormal: invalid parameter"); data().normal = normal; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, contactNormal, static_cast(*this), getContactNormal()) -#endif + + OMNI_PVD_SET(PxContactJoint, normal, static_cast(*this), getContactNormal()) } PxReal ContactJoint::getPenetration() const @@ -85,9 +83,8 @@ void ContactJoint::setPenetration(PxReal penetration) PX_CHECK_AND_RETURN(PxIsFinite(penetration), "ContactJoint::setPenetration: invalid parameter"); data().penetration = penetration; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, contactPenetration, static_cast(*this), getPenetration()) -#endif + + OMNI_PVD_SET(PxContactJoint, penetration, static_cast(*this), getPenetration()) } PxReal ContactJoint::getRestitution() const @@ -100,9 +97,8 @@ void ContactJoint::setRestitution(const PxReal restitution) PX_CHECK_AND_RETURN(PxIsFinite(restitution) && restitution >= 0.f && restitution <= 1.f, "ContactJoint::setRestitution: invalid parameter"); data().restitution = restitution; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, contactRestitution, static_cast(*this), getRestitution()) -#endif + + OMNI_PVD_SET(PxContactJoint, restitution, static_cast(*this), getRestitution()) } PxReal ContactJoint::getBounceThreshold() const @@ -115,9 +111,8 @@ void ContactJoint::setBounceThreshold(const PxReal bounceThreshold) PX_CHECK_AND_RETURN(PxIsFinite(bounceThreshold) && bounceThreshold > 0.f, "ContactJoint::setBounceThreshold: invalid parameter"); data().bounceThreshold = bounceThreshold; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, contactBounceThreshold, static_cast(*this), getBounceThreshold()) -#endif + + OMNI_PVD_SET(PxContactJoint, bounceThreshold, static_cast(*this), getBounceThreshold()) } void ContactJoint::computeJacobians(PxJacobianRow* jacobian) const @@ -155,11 +150,6 @@ PxU32 ContactJoint::getNbJacobianRows() const return 1; } -static void ContactJointProject(const void* /*constantBlock*/, PxTransform& /*bodyAToWorld*/, PxTransform& /*bodyBToWorld*/, bool /*projectToA*/) -{ - // Not required -} - static void ContactJointVisualize(PxConstraintVisualizer& /*viz*/, const void* /*constantBlock*/, const PxTransform& /*body0Transform*/, const PxTransform& /*body1Transform*/, PxU32 /*flags*/) { //TODO @@ -211,7 +201,7 @@ static PxU32 ContactJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gContactJointShaders = { ContactJointSolverPrep, ContactJointProject, ContactJointVisualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable gContactJointShaders = { ContactJointSolverPrep, ContactJointVisualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep ContactJoint::getPrep() const { return gContactJointShaders.solverPrep; } @@ -237,13 +227,15 @@ void ContactJoint::resolveReferences(PxDeserializationContext& context) template<> void physx::Ext::omniPvdInitJoint(ContactJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eCONTACT) - OMNI_PVD_SET(joint, contactPoint, j, joint->getContact()) - OMNI_PVD_SET(joint, contactNormal, j, joint->getContactNormal()) - OMNI_PVD_SET(joint, contactPenetration, j, joint->getPenetration()) - OMNI_PVD_SET(joint, contactRestitution, j, joint->getRestitution()) - OMNI_PVD_SET(joint, contactBounceThreshold, j, joint->getBounceThreshold()) + PxContactJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxContactJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eCONTACT); + + OMNI_PVD_SET(PxContactJoint, point, j, joint->getContact()) + OMNI_PVD_SET(PxContactJoint, normal, j, joint->getContactNormal()) + OMNI_PVD_SET(PxContactJoint, penetration, j, joint->getPenetration()) + OMNI_PVD_SET(PxContactJoint, restitution, j, joint->getRestitution()) + OMNI_PVD_SET(PxContactJoint, bounceThreshold, j, joint->getBounceThreshold()) } #endif diff --git a/physx/source/physxextensions/src/ExtCustomGeometryExt.cpp b/physx/source/physxextensions/src/ExtCustomGeometryExt.cpp index 40c4f62f2..f3c2a9f16 100644 --- a/physx/source/physxextensions/src/ExtCustomGeometryExt.cpp +++ b/physx/source/physxextensions/src/ExtCustomGeometryExt.cpp @@ -185,7 +185,7 @@ bool PxCustomGeometryExt::BaseConvexCallbacks::generateContacts(const PxGeometry { PxContactBuffer* contactBuffer; ContactRecorder(PxContactBuffer& _contactBuffer) : contactBuffer(&_contactBuffer) {} - virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 /*index*/) + virtual bool recordContacts(const PxContactPoint* contactPoints, PxU32 nbContacts, PxU32 /*index*/) { for (PxU32 i = 0; i < nbContacts; ++i) contactBuffer->contact(contactPoints[i]); @@ -217,10 +217,15 @@ bool PxCustomGeometryExt::BaseConvexCallbacks::generateContacts(const PxGeometry if (PxGjkQueryExt::generateContacts(*this, geomSupport, pose0, pose1, contactDistance, toleranceLength, contactBuffer)) { PxGeometryHolder substituteGeom; PxTransform preTransform; - if (useSubstituteGeometry(substituteGeom, preTransform, contactBuffer.contacts[contactBuffer.count - 1], pose0, PxGeometryQuery::getWorldBounds(geom1, pose1).getCenter())) + + PxBounds3 bounds; + PxGeometryQuery::computeGeomBounds(bounds, geom1, pose1, 0.0f, 1.01f); + + if (useSubstituteGeometry(substituteGeom, preTransform, contactBuffer.contacts[contactBuffer.count - 1], pose0, bounds.getCenter())) { const PxGeometry* pGeom0 = &substituteGeom.any(); const PxGeometry* pGeom1 = &geom1; + // PT:: tag: scalar transform*transform PxTransform pose = pose0.transform(preTransform); immediate::PxGenerateContacts(&pGeom0, &pGeom1, &pose, &pose1, &contactCache, 1, contactRecorder, contactDistance, meshContactMargin, toleranceLength, contactCacheAllocator); @@ -248,6 +253,7 @@ bool PxCustomGeometryExt::BaseConvexCallbacks::generateContacts(const PxGeometry { const PxGeometry* pGeom0 = &substituteGeom.any(); const PxGeometry* pGeom1 = &geom1; + // PT:: tag: scalar transform*transform PxTransform pose = pose0.transform(preTransform); immediate::PxGenerateContacts(&pGeom0, &pGeom1, &pose, &pose1, &contactCache, 1, contactRecorder, contactDistance, meshContactMargin, toleranceLength, contactCacheAllocator); @@ -279,6 +285,7 @@ bool PxCustomGeometryExt::BaseConvexCallbacks::generateContacts(const PxGeometry if (useSubstituteGeometry(substituteGeom, preTransform, contactBuffer.contacts[contactBuffer.count - 1], pose0, pos1)) { const PxGeometry& geom = substituteGeom.any(); + // PT:: tag: scalar transform*transform PxTransform pose = pose0.transform(preTransform); PxGeometryQuery::generateTriangleContacts(geom, pose, tri.verts, triangles[i], contactDistance, meshContactMargin, toleranceLength, contactBuffer); } @@ -303,12 +310,17 @@ bool PxCustomGeometryExt::BaseConvexCallbacks::generateContacts(const PxGeometry if (PxGjkQueryExt::generateContacts(*this, *custom1, pose0, pose1, contactDistance, toleranceLength, contactBuffer)) { PxGeometryHolder substituteGeom; PxTransform preTransform; - if (useSubstituteGeometry(substituteGeom, preTransform, contactBuffer.contacts[contactBuffer.count - 1], pose0, PxGeometryQuery::getWorldBounds(geom1, pose1).getCenter())) + + PxBounds3 bounds; + PxGeometryQuery::computeGeomBounds(bounds, geom1, pose1, 0.0f, 1.01f); + + if (useSubstituteGeometry(substituteGeom, preTransform, contactBuffer.contacts[contactBuffer.count - 1], pose0, bounds.getCenter())) { PxU32 oldCount = contactBuffer.count; const PxGeometry* pGeom0 = &substituteGeom.any(); const PxGeometry* pGeom1 = &geom1; + // PT:: tag: scalar transform*transform PxTransform pose = pose0.transform(preTransform); immediate::PxGenerateContacts(&pGeom1, &pGeom0, &pose1, &pose, &contactCache, 1, contactRecorder, contactDistance, meshContactMargin, toleranceLength, contactCacheAllocator); @@ -774,6 +786,7 @@ bool PxCustomGeometryExt::ConeCallbacks::useSubstituteGeometry(PxGeometryHolder& PxVec3 axisDir(PxZero); axisDir[axis] = 1.0f; float n1 = -locN[(axis + 1) % 3], n2 = -locN[(axis + 2) % 3]; float ang = atan2f(n2, n1); + // PT:: tag: scalar transform*transform preTransform = PxTransform(PxQuat(ang, axisDir)) * preTransform; return true; } diff --git a/physx/source/physxextensions/src/ExtD6Joint.cpp b/physx/source/physxextensions/src/ExtD6Joint.cpp index eecc990c6..3f8727d30 100644 --- a/physx/source/physxextensions/src/ExtD6Joint.cpp +++ b/physx/source/physxextensions/src/ExtD6Joint.cpp @@ -47,7 +47,7 @@ D6Joint::D6Joint(const PxTolerancesScale& scale, PxRigidActor* actor0, const PxT data->twistLimit = PxJointAngularLimitPair(-PxPi/2, PxPi/2); data->swingLimit = PxJointLimitCone(PxPi/2, PxPi/2); data->pyramidSwingLimit = PxJointLimitPyramid(-PxPi/2, PxPi/2, -PxPi/2, PxPi/2); - data->distanceLimit = PxJointLinearLimit(scale, PX_MAX_F32); + data->distanceLimit = PxJointLinearLimit(PX_MAX_F32); data->distanceMinDist = 1e-6f*scale.length; data->linearLimitX = PxJointLinearLimitPair(scale); @@ -61,9 +61,6 @@ D6Joint::D6Joint(const PxTolerancesScale& scale, PxRigidActor* actor0, const PxT data->driveLinearVelocity = PxVec3(0.0f); data->driveAngularVelocity = PxVec3(0.0f); - data->projectionLinearTolerance = 1e10f; - data->projectionAngularTolerance = PxPi; - data->mUseDistanceLimit = false; data->mUseNewLinearLimits = false; data->mUseConeLimit = false; @@ -84,7 +81,7 @@ void D6Joint::setMotion(PxD6Axis::Enum index, PxD6Motion::Enum t) PxD6Motion::Enum motions[6]; for (PxU32 i = 0; i < 6; ++i) motions[i] = getMotion(PxD6Axis::Enum(i)); - OMNI_PVD_SETB(joint, d6Motions, static_cast(*this), motions, sizeof(motions)) + OMNI_PVD_SETB(PxD6Joint, motions, static_cast(*this), motions, sizeof(motions)) #endif } @@ -116,23 +113,23 @@ void D6Joint::setDrive(PxD6Drive::Enum index, const PxD6JointDrive& d) mRecomputeMotion = true; markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); + const PxD6Joint& j = static_cast(*this); PxReal forceLimit[6]; for (PxU32 i = 0; i < 6; ++i) forceLimit[i] = getDrive(PxD6Drive::Enum(i)).forceLimit; - OMNI_PVD_SETB(joint, d6DriveForceLimit, j, forceLimit, sizeof(forceLimit)) + OMNI_PVD_SETB(PxD6Joint, driveForceLimit, j, forceLimit, sizeof(forceLimit)) PxD6JointDriveFlags flags[6]; for (PxU32 i = 0; i < 6; ++i) flags[i] = getDrive(PxD6Drive::Enum(i)).flags; - OMNI_PVD_SETB(joint, d6DriveFlags, j, flags, sizeof(flags)) + OMNI_PVD_SETB(PxD6Joint, driveFlags, j, flags, sizeof(flags)) PxReal stiffness[6]; for (PxU32 i = 0; i < 6; ++i) stiffness[i] = getDrive(PxD6Drive::Enum(i)).stiffness; - OMNI_PVD_SETB(joint, d6DriveStiffness, j, stiffness, sizeof(stiffness)) + OMNI_PVD_SETB(PxD6Joint, driveStiffness, j, stiffness, sizeof(stiffness)) PxReal damping[6]; for (PxU32 i = 0; i < 6; ++i) damping[i] = getDrive(PxD6Drive::Enum(i)).damping; - OMNI_PVD_SETB(joint, d6DriveDamping, j, damping, sizeof(damping)) + OMNI_PVD_SETB(PxD6Joint, driveDamping, j, damping, sizeof(damping)) #endif } @@ -143,13 +140,12 @@ void D6Joint::setDistanceLimit(const PxJointLinearLimit& l) data().mUseDistanceLimit = true; markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, d6DistanceLimitValue, j, l.value) - OMNI_PVD_SET(joint, d6DistanceLimitRestitution, j, l.restitution) - OMNI_PVD_SET(joint, d6DistanceLimitBounceThreshold, j, l.bounceThreshold) - OMNI_PVD_SET(joint, d6DistanceLimitStiffness, j, l.stiffness) - OMNI_PVD_SET(joint, d6DistanceLimitDamping, j, l.damping) - OMNI_PVD_SET(joint, d6DistanceLimitContactDistance, j, l.contactDistance_deprecated) + const PxD6Joint& j = static_cast(*this); + OMNI_PVD_SET(PxD6Joint, distanceLimitValue, j, l.value) + OMNI_PVD_SET(PxD6Joint, distanceLimitRestitution, j, l.restitution) + OMNI_PVD_SET(PxD6Joint, distanceLimitBounceThreshold, j, l.bounceThreshold) + OMNI_PVD_SET(PxD6Joint, distanceLimitStiffness, j, l.stiffness) + OMNI_PVD_SET(PxD6Joint, distanceLimitDamping, j, l.damping) #endif } @@ -174,29 +170,26 @@ void D6Joint::setLinearLimit(PxD6Axis::Enum axis, const PxJointLinearLimitPair& d.mUseNewLinearLimits = true; markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); + const PxD6Joint& j = static_cast(*this); PxReal values[3]; for (PxU32 i = 0; i < 3; ++i) values[i] = getLinearLimit(PxD6Axis::Enum(i)).lower; - OMNI_PVD_SETB(joint, d6LinearLimitLower, j, values, sizeof(values)) + OMNI_PVD_SETB(PxD6Joint, linearLimitLower, j, values, sizeof(values)) for (PxU32 i = 0; i < 3; ++i) values[i] = getLinearLimit(PxD6Axis::Enum(i)).upper; - OMNI_PVD_SETB(joint, d6LinearLimitUpper, j, values, sizeof(values)) + OMNI_PVD_SETB(PxD6Joint, linearLimitUpper, j, values, sizeof(values)) for (PxU32 i = 0; i < 3; ++i) values[i] = getLinearLimit(PxD6Axis::Enum(i)).restitution; - OMNI_PVD_SETB(joint, d6LinearLimitRestitution, j, values, sizeof(values)) + OMNI_PVD_SETB(PxD6Joint, linearLimitRestitution, j, values, sizeof(values)) for (PxU32 i = 0; i < 3; ++i) values[i] = getLinearLimit(PxD6Axis::Enum(i)).bounceThreshold; - OMNI_PVD_SETB(joint, d6LinearLimitBounceThreshold, j, values, sizeof(values)) + OMNI_PVD_SETB(PxD6Joint, linearLimitBounceThreshold, j, values, sizeof(values)) for (PxU32 i = 0; i < 3; ++i) values[i] = getLinearLimit(PxD6Axis::Enum(i)).stiffness; - OMNI_PVD_SETB(joint, d6LinearLimitStiffness, j, values, sizeof(values)) + OMNI_PVD_SETB(PxD6Joint, linearLimitStiffness, j, values, sizeof(values)) for (PxU32 i = 0; i < 3; ++i) values[i] = getLinearLimit(PxD6Axis::Enum(i)).damping; - OMNI_PVD_SETB(joint, d6LinearLimitDamping, j, values, sizeof(values)) - for (PxU32 i = 0; i < 3; ++i) - values[i] = getLinearLimit(PxD6Axis::Enum(i)).contactDistance_deprecated; - OMNI_PVD_SETB(joint, d6LinearLimitContactDistance, j, values, sizeof(values)) + OMNI_PVD_SETB(PxD6Joint, linearLimitDamping, j, values, sizeof(values)) #endif } @@ -230,14 +223,13 @@ void D6Joint::setTwistLimit(const PxJointAngularLimitPair& l) markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, d6TwistLimitLower, j, l.lower) - OMNI_PVD_SET(joint, d6TwistLimitUpper, j, l.upper) - OMNI_PVD_SET(joint, d6TwistLimitRestitution, j, l.restitution) - OMNI_PVD_SET(joint, d6TwistLimitBounceThreshold, j, l.bounceThreshold) - OMNI_PVD_SET(joint, d6TwistLimitStiffness, j, l.stiffness) - OMNI_PVD_SET(joint, d6TwistLimitDamping, j, l.damping) - OMNI_PVD_SET(joint, d6TwistLimitContactDistance, j, l.contactDistance_deprecated) + const PxD6Joint& j = static_cast(*this); + OMNI_PVD_SET(PxD6Joint, twistLimitLower, j, l.lower) + OMNI_PVD_SET(PxD6Joint, twistLimitUpper, j, l.upper) + OMNI_PVD_SET(PxD6Joint, twistLimitRestitution, j, l.restitution) + OMNI_PVD_SET(PxD6Joint, twistLimitBounceThreshold, j, l.bounceThreshold) + OMNI_PVD_SET(PxD6Joint, twistLimitStiffness, j, l.stiffness) + OMNI_PVD_SET(PxD6Joint, twistLimitDamping, j, l.damping) #endif } @@ -255,16 +247,15 @@ void D6Joint::setPyramidSwingLimit(const PxJointLimitPyramid& l) markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, d6PyramidSwingLimitYAngleMin, j, l.yAngleMin) - OMNI_PVD_SET(joint, d6PyramidSwingLimitYAngleMax, j, l.yAngleMax) - OMNI_PVD_SET(joint, d6PyramidSwingLimitZAngleMin, j, l.zAngleMin) - OMNI_PVD_SET(joint, d6PyramidSwingLimitZAngleMax, j, l.zAngleMax) - OMNI_PVD_SET(joint, d6PyramidSwingLimitRestitution, j, l.restitution) - OMNI_PVD_SET(joint, d6PyramidSwingLimitBounceThreshold, j, l.bounceThreshold) - OMNI_PVD_SET(joint, d6PyramidSwingLimitStiffness, j, l.stiffness) - OMNI_PVD_SET(joint, d6PyramidSwingLimitDamping, j, l.damping) - OMNI_PVD_SET(joint, d6PyramidSwingLimitContactDistance, j, l.contactDistance_deprecated) + const PxD6Joint& j = static_cast(*this); + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitYAngleMin, j, l.yAngleMin) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitYAngleMax, j, l.yAngleMax) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitZAngleMin, j, l.zAngleMin) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitZAngleMax, j, l.zAngleMax) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitRestitution, j, l.restitution) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitBounceThreshold, j, l.bounceThreshold) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitStiffness, j, l.stiffness) + OMNI_PVD_SET(PxD6Joint, pyramidSwingLimitDamping, j, l.damping) #endif } @@ -282,14 +273,13 @@ void D6Joint::setSwingLimit(const PxJointLimitCone& l) markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, d6SwingLimitYAngle, j, l.yAngle) - OMNI_PVD_SET(joint, d6SwingLimitZAngle, j, l.zAngle) - OMNI_PVD_SET(joint, d6SwingLimitRestitution, j, l.restitution) - OMNI_PVD_SET(joint, d6SwingLimitBounceThreshold, j, l.bounceThreshold) - OMNI_PVD_SET(joint, d6SwingLimitStiffness, j, l.stiffness) - OMNI_PVD_SET(joint, d6SwingLimitDamping, j, l.damping) - OMNI_PVD_SET(joint, d6SwingLimitContactDistance, j, l.contactDistance_deprecated) + const PxD6Joint& j = static_cast(*this); + OMNI_PVD_SET(PxD6Joint, swingLimitYAngle, j, l.yAngle) + OMNI_PVD_SET(PxD6Joint, swingLimitZAngle, j, l.zAngle) + OMNI_PVD_SET(PxD6Joint, swingLimitRestitution, j, l.restitution) + OMNI_PVD_SET(PxD6Joint, swingLimitBounceThreshold, j, l.bounceThreshold) + OMNI_PVD_SET(PxD6Joint, swingLimitStiffness, j, l.stiffness) + OMNI_PVD_SET(PxD6Joint, swingLimitDamping, j, l.damping) #endif } @@ -305,9 +295,8 @@ void D6Joint::setDrivePosition(const PxTransform& pose, bool autowake) if(autowake) wakeUpActors(); markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, d6DrivePosition, static_cast(*this), pose) -#endif + + OMNI_PVD_SET(PxD6Joint, drivePosition, static_cast(*this), pose) } void D6Joint::getDriveVelocity(PxVec3& linear, PxVec3& angular) const @@ -325,41 +314,12 @@ void D6Joint::setDriveVelocity(const PxVec3& linear, const PxVec3& angular, bool wakeUpActors(); markDirty(); #if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, d6DriveLinVelocity, static_cast(*this), linear) - OMNI_PVD_SET(joint, d6DriveAngVelocity, static_cast(*this), angular) -#endif -} - -void D6Joint::setProjectionAngularTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0 && tolerance <= PxPi, "PxD6Joint::setProjectionAngularTolerance: tolerance invalid"); - data().projectionAngularTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, d6ProjectionAngularTolerance, static_cast(*this), tolerance) -#endif -} - -PxReal D6Joint::getProjectionAngularTolerance() const -{ - return data().projectionAngularTolerance; -} - -void D6Joint::setProjectionLinearTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0, "PxD6Joint::setProjectionLinearTolerance: invalid parameter"); - data().projectionLinearTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, d6ProjectionLinearTolerance, static_cast(*this), tolerance) + const PxD6Joint& j = static_cast(*this); + OMNI_PVD_SET(PxD6Joint, driveLinVelocity, j, linear) + OMNI_PVD_SET(PxD6Joint, driveAngVelocity, j, angular) #endif } -PxReal D6Joint::getProjectionLinearTolerance() const -{ - return data().projectionLinearTolerance; -} - void* D6Joint::prepareData() { D6JointData& d = data(); @@ -407,111 +367,6 @@ void* D6Joint::prepareData() return mData; } -// Notes: -/* - -This used to be in the linear drive model: - - if(motion[PxD6Axis::eX+i] == PxD6Motion::eLIMITED) - { - if(data.driveLinearVelocity[i] < 0.0f && cB2cA.p[i] < -mLimits[PxD6Limit::eLINEAR].mValue || - data.driveLinearVelocity[i] > 0.0f && cB2cA.p[i] > mLimits[PxD6Limit::eLINEAR].mValue) - continue; - } - -it doesn't seem like a good idea though, because it turns off drive altogether, despite the fact that positional -drive might pull us back in towards the limit. Might be better to make the drive unilateral so it can only pull -us in from the limit - -This used to be in angular locked: - - // Angular locked - //TODO fix this properly. - if(PxAbs(cB2cA.q.x) < 0.0001f) cB2cA.q.x = 0; - if(PxAbs(cB2cA.q.y) < 0.0001f) cB2cA.q.y = 0; - if(PxAbs(cB2cA.q.z) < 0.0001f) cB2cA.q.z = 0; - if(PxAbs(cB2cA.q.w) < 0.0001f) cB2cA.q.w = 0; -*/ - -static PxQuat truncate(const PxQuat& qIn, PxReal minCosHalfTol, bool& truncated) -{ - const PxQuat q = qIn.w >= 0.0f ? qIn : -qIn; - truncated = q.w < minCosHalfTol; - if(!truncated) - return q; - const PxVec3 v = q.getImaginaryPart().getNormalized() * PxSqrt(1.0f - minCosHalfTol * minCosHalfTol); - return PxQuat(v.x, v.y, v.z, minCosHalfTol); -} - -// we decompose the quaternion as q1 * q2, where q1 is a rotation orthogonal to the unit axis, and q2 a rotation around it. -// (so for example if 'axis' is the twist axis, this is separateSwingTwist). -static PxQuat project(const PxQuat& q, const PxVec3& axis, PxReal cosHalfTol, bool& truncated) -{ - const PxReal a = q.getImaginaryPart().dot(axis); - const PxQuat q2 = PxAbs(a) >= 1e-6f ? PxQuat(a*axis.x, a*axis.y, a*axis.z, q.w).getNormalized() : PxQuat(PxIdentity); - const PxQuat q1 = q * q2.getConjugate(); - - PX_ASSERT(PxAbs(q1.getImaginaryPart().dot(q2.getImaginaryPart())) < 1e-6f); - - return truncate(q1, cosHalfTol, truncated) * q2; -} - -// Here's how the angular part works: -// * if no DOFs are locked, there's nothing to do. -// * if all DOFs are locked, we just truncate the rotation -// * if two DOFs are locked -// * we decompose the rotation into swing * twist, where twist is a rotation around the free DOF and swing is a rotation around an axis orthogonal to the free DOF -// * then we truncate swing -// The case of one locked DOF is currently unimplemented, but one option would be: -// * if one DOF is locked (the tricky case), we define the 'free' axis as follows (as the velocity solver prep function does) -// TWIST: cB[0] -// SWING1: cB[0].cross(cA[2]) -// SWING2: cB[0].cross(cA[1]) -// then, as above, we decompose into swing * free, and truncate the free rotation - -//export this in the physx namespace so we can unit test it -namespace physx -{ -PxQuat angularProject(PxU32 lockedDofs, const PxQuat& q, PxReal cosHalfTol, bool& truncated) -{ - PX_ASSERT(lockedDofs <= 7); - truncated = false; - - switch(lockedDofs) - { - case 0: return q; - case 1: return q; // currently unimplemented - case 2: return q; // currently unimplemented - case 3: return project(q, PxVec3(0.0f, 0.0f, 1.0f), cosHalfTol, truncated); - case 4: return q; // currently unimplemented - case 5: return project(q, PxVec3(0.0f, 1.0f, 0.0f), cosHalfTol, truncated); - case 6: return project(q, PxVec3(1.0f, 0.0f, 0.0f), cosHalfTol, truncated); - case 7: return truncate(q, cosHalfTol, truncated); - default: return PxQuat(PxIdentity); - } -} -} - -static void D6JointProject(const void* constantBlock, PxTransform& bodyAToWorld, PxTransform& bodyBToWorld, bool projectToA) -{ - const D6JointData& data = *reinterpret_cast(constantBlock); - - PxTransform cA2w, cB2w, cB2cA, projected; - joint::computeDerived(data, bodyAToWorld, bodyBToWorld, cA2w, cB2w, cB2cA, false); - - const PxVec3 v(data.locked & 1 ? cB2cA.p.x : 0.0f, - data.locked & 2 ? cB2cA.p.y : 0.0f, - data.locked & 4 ? cB2cA.p.z : 0.0f); - - bool linearTrunc, angularTrunc = false; - projected.p = joint::truncateLinear(v, data.projectionLinearTolerance, linearTrunc) + (cB2cA.p - v); - - projected.q = angularProject(data.locked >> 3, cB2cA.q, PxCos(data.projectionAngularTolerance / 2), angularTrunc); - - if(linearTrunc || angularTrunc) - joint::projectTransforms(bodyAToWorld, bodyBToWorld, cA2w, cB2w, projected, data, projectToA); -} - static PX_FORCE_INLINE PxReal computePhi(const PxQuat& q) { PxQuat twist = q; @@ -523,52 +378,32 @@ static PX_FORCE_INLINE PxReal computePhi(const PxQuat& q) return angle; } -static void visualizeAngularLimit(PxConstraintVisualizer& viz, const D6JointData& data, const PxTransform& t, float swingYZ, float swingW, float swingLimitYZ) +static void visualizeAngularLimit(PxConstraintVisualizer& viz, const PxTransform& t, float swingLimitYZ) { - bool active = PxAbs(computeSwingAngle(swingYZ, swingW)) > swingLimitYZ - data.swingLimit.contactDistance_deprecated; - viz.visualizeAngularLimit(t, -swingLimitYZ, swingLimitYZ, active); + viz.visualizeAngularLimit(t, -swingLimitYZ, swingLimitYZ); } -static void visualizeDoubleCone(PxConstraintVisualizer& viz, const D6JointData& data, const PxTransform& t, float sin, float swingLimitYZ) +static void visualizeDoubleCone(PxConstraintVisualizer& viz, const PxTransform& t, float swingLimitYZ) { - const PxReal angle = PxAsin(sin); - const PxReal pad = data.swingLimit.contactDistance_deprecated; - const PxReal low = -swingLimitYZ; - const PxReal high = swingLimitYZ; - - const bool active = isLimitActive(data.swingLimit, pad, angle, low, high); - viz.visualizeDoubleCone(t, swingLimitYZ, active); -} - -// PT: TODO: refactor with spherical joint code -static void visualizeCone(PxConstraintVisualizer& viz, const D6JointData& data, const PxQuat& swing, const PxTransform& cA2w) -{ - const PxVec3 swingAngle(0.0f, computeSwingAngle(swing.y, swing.w), computeSwingAngle(swing.z, swing.w)); - const PxReal pad = data.swingLimit.isSoft() ? 0.0f : data.swingLimit.contactDistance_deprecated; - Cm::ConeLimitHelperTanLess coneHelper(data.swingLimit.yAngle, data.swingLimit.zAngle, pad); - viz.visualizeLimitCone(cA2w, PxTan(data.swingLimit.zAngle / 4), PxTan(data.swingLimit.yAngle / 4), !coneHelper.contains(swingAngle)); + viz.visualizeDoubleCone(t, swingLimitYZ); } -static PX_FORCE_INLINE bool isLinearLimitActive(const PxJointLinearLimitPair& limit, float ordinate) +static void visualizeCone(PxConstraintVisualizer& viz, const D6JointData& data, const PxTransform& cA2w) { - const PxReal pad = limit.isSoft() ? 0.0f : limit.contactDistance_deprecated; - return (ordinate < limit.lower + pad) || (ordinate > limit.upper - pad); + viz.visualizeLimitCone(cA2w, PxTan(data.swingLimit.zAngle / 4), PxTan(data.swingLimit.yAngle / 4)); } -static void visualizeLine(PxConstraintVisualizer& viz, const PxVec3& origin, const PxVec3& axis, const PxJointLinearLimitPair& limit, float ordinate) +static void visualizeLine(PxConstraintVisualizer& viz, const PxVec3& origin, const PxVec3& axis, const PxJointLinearLimitPair& limit) { - const bool active = isLinearLimitActive(limit, ordinate); const PxVec3 p0 = origin + axis * limit.lower; const PxVec3 p1 = origin + axis * limit.upper; - viz.visualizeLine(p0, p1, active ? 0xff0000u : 0xffffffu); + viz.visualizeLine(p0, p1, PxU32(PxDebugColor::eARGB_YELLOW)); } -static void visualizeQuad(PxConstraintVisualizer& viz, const PxVec3& origin, const PxVec3& axis0, const PxJointLinearLimitPair& limit0, float ordinate0, - const PxVec3& axis1, const PxJointLinearLimitPair& limit1, float ordinate1) +static void visualizeQuad(PxConstraintVisualizer& viz, const PxVec3& origin, const PxVec3& axis0, const PxJointLinearLimitPair& limit0, + const PxVec3& axis1, const PxJointLinearLimitPair& limit1) { - const bool active0 = isLinearLimitActive(limit0, ordinate0); - const bool active1 = isLinearLimitActive(limit1, ordinate1); - const PxU32 color = (active0 || active1) ? 0xff0000u : 0xffffffu; + const PxU32 color = PxU32(PxDebugColor::eARGB_YELLOW); const PxVec3 l0 = axis0 * limit0.lower; const PxVec3 u0 = axis0 * limit0.upper; @@ -586,14 +421,11 @@ static void visualizeQuad(PxConstraintVisualizer& viz, const PxVec3& origin, con viz.visualizeLine(p3, p0, color); } -static void visualizeBox(PxConstraintVisualizer& viz, const PxVec3& origin, const PxVec3& axis0, const PxJointLinearLimitPair& limit0, float ordinate0, - const PxVec3& axis1, const PxJointLinearLimitPair& limit1, float ordinate1, - const PxVec3& axis2, const PxJointLinearLimitPair& limit2, float ordinate2) +static void visualizeBox(PxConstraintVisualizer& viz, const PxVec3& origin, const PxVec3& axis0, const PxJointLinearLimitPair& limit0, + const PxVec3& axis1, const PxJointLinearLimitPair& limit1, + const PxVec3& axis2, const PxJointLinearLimitPair& limit2) { - const bool active0 = isLinearLimitActive(limit0, ordinate0); - const bool active1 = isLinearLimitActive(limit1, ordinate1); - const bool active2 = isLinearLimitActive(limit2, ordinate2); - const PxU32 color = (active0 || active1 || active2) ? 0xff0000u : 0xffffffu; + const PxU32 color = PxU32(PxDebugColor::eARGB_YELLOW); const PxVec3 l0 = axis0 * limit0.lower; const PxVec3 u0 = axis0 * limit0.upper; @@ -639,65 +471,7 @@ static float computeLimitedDistance(const D6JointData& data, const PxTransform& return limitDir.magnitude(); } -void setRotX(PxMat33& m, PxReal angle) -{ - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[1][1] = m[2][2] = cos; - m[1][2] = sin; - m[2][1] = -sin; -} - -void setRotY(PxMat33& m, PxReal angle) -{ - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[2][2] = cos; - m[0][2] = -sin; - m[2][0] = sin; -} - -void setRotZ(PxMat33& m, PxReal angle) -{ - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[1][1] = cos; - m[0][1] = sin; - m[1][0] = -sin; -} - -PxQuat getRotXQuat(float angle) -{ - PxMat33 m; - setRotX(m, angle); - return PxQuat(m); -} - -PxQuat getRotYQuat(float angle) -{ - PxMat33 m; - setRotY(m, angle); - return PxQuat(m); -} - -PxQuat getRotZQuat(float angle) -{ - PxMat33 m; - setRotZ(m, angle); - return PxQuat(m); -} - - -static void drawPyramid(PxConstraintVisualizer& viz, const D6JointData& data, const PxTransform& cA2w, const PxQuat& swing, bool useY, bool useZ) +static void drawPyramid(PxConstraintVisualizer& viz, const D6JointData& data, const PxTransform& cA2w, const PxQuat& /*swing*/, bool /*useY*/, bool /*useZ*/) { struct Local { @@ -713,8 +487,8 @@ static void drawPyramid(PxConstraintVisualizer& viz, const D6JointData& data, co const float z = coeff*zmax + (1.0f-coeff)*zmin; const float r = 1.0f; - PxMat33 my; setRotZ(my, z); - PxMat33 mz; setRotY(mz, y); + PxMat33 my; PxSetRotZ(my, z); + PxMat33 mz; PxSetRotY(mz, y); const PxVec3 p0 = (my*mz).transform(PxVec3(r, 0.0f, 0.0f)); const PxVec3 p0w = _cA2w.transform(p0); _viz.visualizeLine(_cA2w.p, p0w, color); @@ -726,9 +500,7 @@ static void drawPyramid(PxConstraintVisualizer& viz, const D6JointData& data, co }; const PxJointLimitPyramid& l = data.pyramidSwingLimit; - const bool activeY = useY ? isLimitActive(l, l.contactDistance_deprecated, computeSwingAngle(swing.y, swing.w), l.yAngleMin, l.yAngleMax) : false; - const bool activeZ = useZ ? isLimitActive(l, l.contactDistance_deprecated, computeSwingAngle(swing.z, swing.w), l.zAngleMin, l.zAngleMax) : false; - const PxU32 color = (activeY||activeZ) ? PxDebugColor::eARGB_RED : PxDebugColor::eARGB_GREY; + const PxU32 color = PxU32(PxDebugColor::eARGB_YELLOW); Local::drawArc(viz, cA2w, l.yAngleMin, l.yAngleMin, l.zAngleMin, l.zAngleMax, color); Local::drawArc(viz, cA2w, l.yAngleMax, l.yAngleMax, l.zAngleMin, l.zAngleMax, color); @@ -750,45 +522,41 @@ static void D6JointVisualize(PxConstraintVisualizer& viz, const void* constantBl const D6JointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); if(flags & PxConstraintVisualizationFlag::eLOCAL_FRAMES) viz.visualizeJointFrames(cA2w, cB2w); if(flags & PxConstraintVisualizationFlag::eLIMITS) { - // PT: it is a mistake to use the neighborhood operator since it - // prevents us from using the quat's double-cover feature. -// if(cA2w.q.dot(cB2w.q)<0.0f) -// cB2w.q = -cB2w.q; - - const PxTransform cB2cA = cA2w.transformInv(cB2w); - const PxMat33 cA2w_m(cA2w.q), cB2w_m(cB2w.q); + const PxTransform cB2cA = cA2w.transformInv(cB2w); + const PxMat33Padded cA2w_m(cA2w.q); + const PxMat33Padded cB2w_m(cB2w.q); if(data.mUseNewLinearLimits) { switch(data.limited) { case 1<(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); const PxU32 SWING1_FLAG = 1<>3, ra, rb); cA2wOut = ra + bA2w.p; @@ -1130,7 +885,7 @@ static PxU32 D6JointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gD6JointShaders = { D6JointSolverPrep, D6JointProject, D6JointVisualize, /*PxConstraintFlag::Enum(0)*/PxConstraintFlag::eGPU_COMPATIBLE }; +static PxConstraintShaderTable gD6JointShaders = { D6JointSolverPrep, D6JointVisualize, /*PxConstraintFlag::Enum(0)*/PxConstraintFlag::eGPU_COMPATIBLE }; PxConstraintSolverPrep D6Joint::getPrep() const { return gD6JointShaders.solverPrep; } @@ -1155,56 +910,56 @@ void D6Joint::resolveReferences(PxDeserializationContext& context) void D6Joint::updateOmniPvdProperties() const { - const PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, d6TwistAngle, j, getTwistAngle()) - OMNI_PVD_SET(joint, d6SwingYAngle, j, getSwingYAngle()) - OMNI_PVD_SET(joint, d6SwingZAngle, j, getSwingZAngle()) + const PxD6Joint& j = static_cast(*this); + OMNI_PVD_SET(PxD6Joint, twistAngle, j, getTwistAngle()) + OMNI_PVD_SET(PxD6Joint, swingYAngle, j, getSwingYAngle()) + OMNI_PVD_SET(PxD6Joint, swingZAngle, j, getSwingZAngle()) } template<> void physx::Ext::omniPvdInitJoint(D6Joint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eD6) - OMNI_PVD_SET(joint, d6ProjectionLinearTolerance, j, joint->getProjectionLinearTolerance()) - OMNI_PVD_SET(joint, d6ProjectionAngularTolerance, j, joint->getProjectionAngularTolerance()) + const PxD6Joint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxD6Joint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eD6); PxD6Motion::Enum motions[6]; for (PxU32 i = 0; i < 6; ++i) motions[i] = joint->getMotion(PxD6Axis::Enum(i)); - OMNI_PVD_SETB(joint, d6Motions, j, motions, sizeof(motions)) - - //Set limits lazily in the corresponding setters. - //This reduces unused data in OVD and allows for testing for the attribute presence - //to figure out what limit approaches are used, instead of also serializing - //mUseDistanceLimit, mUseNewLinearLimits, mUseConeLimit and mUsePyramidLimits. + OMNI_PVD_SETB(PxD6Joint, motions, j, motions, sizeof(motions)) + PxReal forceLimit[6]; + for (PxU32 i = 0; i < 6; ++i) + forceLimit[i] = joint->getDrive(PxD6Drive::Enum(i)).forceLimit; + OMNI_PVD_SETB(PxD6Joint, driveForceLimit, j, forceLimit, sizeof(forceLimit)) + PxD6JointDriveFlags flags[6]; + for (PxU32 i = 0; i < 6; ++i) { - PxReal forceLimit[6]; - for (PxU32 i = 0; i < 6; ++i) - forceLimit[i] = joint->getDrive(PxD6Drive::Enum(i)).forceLimit; - OMNI_PVD_SETB(joint, d6DriveForceLimit, j, forceLimit, sizeof(forceLimit)) - PxD6JointDriveFlags flags[6]; - for (PxU32 i = 0; i < 6; ++i) - flags[i] = joint->getDrive(PxD6Drive::Enum(i)).flags; - OMNI_PVD_SETB(joint, d6DriveFlags, j, flags, sizeof(flags)) - PxReal stiffness[6]; - for (PxU32 i = 0; i < 6; ++i) - stiffness[i] = joint->getDrive(PxD6Drive::Enum(i)).stiffness; - OMNI_PVD_SETB(joint, d6DriveStiffness, j, stiffness, sizeof(stiffness)) - PxReal damping[6]; - for (PxU32 i = 0; i < 6; ++i) - damping[i] = joint->getDrive(PxD6Drive::Enum(i)).damping; - OMNI_PVD_SETB(joint, d6DriveDamping, j, damping, sizeof(damping)) + flags[i] = joint->getDrive(PxD6Drive::Enum(i)).flags; } - OMNI_PVD_SET(joint, d6DrivePosition, j, joint->getDrivePosition()) - PxVec3 driveLinVel, driveAngVel; joint->getDriveVelocity(driveLinVel, driveAngVel); - OMNI_PVD_SET(joint, d6DriveLinVelocity, j, driveLinVel) - OMNI_PVD_SET(joint, d6DriveAngVelocity, j, driveAngVel) - - OMNI_PVD_SET(joint, d6TwistAngle, j, joint->getTwistAngle()) - OMNI_PVD_SET(joint, d6SwingYAngle, j, joint->getSwingYAngle()) - OMNI_PVD_SET(joint, d6SwingZAngle, j, joint->getSwingZAngle()) + OMNI_PVD_SETB(PxD6Joint, driveFlags, j, flags, sizeof(flags)) + PxReal stiffness[6]; + for (PxU32 i = 0; i < 6; ++i) + { + stiffness[i] = joint->getDrive(PxD6Drive::Enum(i)).stiffness; + } + OMNI_PVD_SETB(PxD6Joint, driveStiffness, j, stiffness, sizeof(stiffness)) + PxReal damping[6]; + for (PxU32 i = 0; i < 6; ++i) + { + damping[i] = joint->getDrive(PxD6Drive::Enum(i)).damping; + } + OMNI_PVD_SETB(PxD6Joint, driveDamping, j, damping, sizeof(damping)) + OMNI_PVD_SET(PxD6Joint, drivePosition, j, joint->getDrivePosition()) + + PxVec3 driveLinVel, driveAngVel; + joint->getDriveVelocity(driveLinVel, driveAngVel); + OMNI_PVD_SET(PxD6Joint, driveLinVelocity, j, driveLinVel) + OMNI_PVD_SET(PxD6Joint, driveAngVelocity, j, driveAngVel) + + OMNI_PVD_SET(PxD6Joint, twistAngle, j, joint->getTwistAngle()) + OMNI_PVD_SET(PxD6Joint, swingYAngle, j, joint->getSwingYAngle()) + OMNI_PVD_SET(PxD6Joint, swingZAngle, j, joint->getSwingZAngle()) } #endif diff --git a/physx/source/physxextensions/src/ExtD6Joint.h b/physx/source/physxextensions/src/ExtD6Joint.h index 4fdee666a..6c01b34a1 100644 --- a/physx/source/physxextensions/src/ExtD6Joint.h +++ b/physx/source/physxextensions/src/ExtD6Joint.h @@ -40,13 +40,6 @@ namespace Ext { struct D6JointData : public JointData { - //= 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. - //================================================================================================== - PxD6Motion::Enum motion[6]; PxJointLinearLimit distanceLimit; PxJointLinearLimitPair linearLimitX; @@ -70,10 +63,6 @@ namespace Ext PxReal distanceMinDist; // distance limit minimum distance to get a good direction - // projection quantities - PxReal projectionLinearTolerance; - PxReal projectionAngularTolerance; - // PT: the PxD6Motion values are now shared for both kind of linear limits, so we need // an extra bool to know which one(s) should be actually used. bool mUseDistanceLimit; @@ -140,10 +129,6 @@ namespace Ext virtual PxTransform getDrivePosition() const PX_OVERRIDE; virtual void setDriveVelocity(const PxVec3& linear, const PxVec3& angular, bool autowake = true) PX_OVERRIDE; virtual void getDriveVelocity(PxVec3& linear, PxVec3& angular) const PX_OVERRIDE; - virtual void setProjectionLinearTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionLinearTolerance() const PX_OVERRIDE; - virtual void setProjectionAngularTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionAngularTolerance() const PX_OVERRIDE; //~PxD6Joint // PxConstraintConnector diff --git a/physx/source/physxextensions/src/ExtD6JointCreate.cpp b/physx/source/physxextensions/src/ExtD6JointCreate.cpp index 050c3fff4..bddf574bb 100644 --- a/physx/source/physxextensions/src/ExtD6JointCreate.cpp +++ b/physx/source/physxextensions/src/ExtD6JointCreate.cpp @@ -40,44 +40,6 @@ using namespace physx; static const PxVec3 gX(1.0f, 0.0f, 0.0f); -static void setRotY(PxMat33& m, PxReal angle) -{ - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[2][2] = cos; - m[0][2] = -sin; - m[2][0] = sin; -} - -static void setRotZ(PxMat33& m, PxReal angle) -{ - m = PxMat33(PxIdentity); - - const PxReal cos = cosf(angle); - const PxReal sin = sinf(angle); - - m[0][0] = m[1][1] = cos; - m[0][1] = sin; - m[1][0] = -sin; -} - -static PxQuat getRotYQuat(float angle) -{ - PxMat33 m; - setRotY(m, angle); - return PxQuat(m); -} - -static PxQuat getRotZQuat(float angle) -{ - PxMat33 m; - setRotZ(m, angle); - return PxQuat(m); -} - PxJoint* physx::PxD6JointCreate_Fixed(PxPhysics& physics, PxRigidActor* actor0, const PxVec3& localPos0, PxRigidActor* actor1, const PxVec3& localPos1, bool useD6) { const PxTransform jointFrame0(localPos0); @@ -104,7 +66,7 @@ PxJoint* physx::PxD6JointCreate_Distance(PxPhysics& physics, PxRigidActor* actor j->setMotion(PxD6Axis::eX, PxD6Motion::eLIMITED); j->setMotion(PxD6Axis::eY, PxD6Motion::eLIMITED); j->setMotion(PxD6Axis::eZ, PxD6Motion::eLIMITED); - j->setDistanceLimit(PxJointLinearLimit(PxTolerancesScale(), maxDist)); + j->setDistanceLimit(PxJointLinearLimit(maxDist)); return j; } else @@ -235,8 +197,8 @@ PxJoint* physx::PxD6JointCreate_GenericCone(float& apiroty, float& apirotz, PxPh apiroty = APIRotY; apirotz = APIRotZ; - const PxQuat RotY = getRotYQuat(APIRotY); - const PxQuat RotZ = getRotZQuat(APIRotZ); + const PxQuat RotY = PxGetRotYQuat(APIRotY); + const PxQuat RotZ = PxGetRotZQuat(APIRotZ); const PxQuat Rot = RotY * RotZ; const PxTransform localFrame0(localPos0, Rot); diff --git a/physx/source/physxextensions/src/ExtDefaultSimulationFilterShader.cpp b/physx/source/physxextensions/src/ExtDefaultSimulationFilterShader.cpp index 6297fb290..baa52cbd5 100644 --- a/physx/source/physxextensions/src/ExtDefaultSimulationFilterShader.cpp +++ b/physx/source/physxextensions/src/ExtDefaultSimulationFilterShader.cpp @@ -30,6 +30,7 @@ #include "extensions/PxDefaultSimulationFilterShader.h" #include "PxRigidActor.h" #include "PxShape.h" +#include "PxSoftBody.h" #include "foundation/PxIntrinsics.h" #include "foundation/PxAllocator.h" @@ -200,6 +201,22 @@ namespace } } break; + case PxActorType::eSOFTBODY: + { + PxSoftBody& sActor = static_cast(actor); + + PxShape* shape = sActor.getShape(); + + // retrieve current group mask + PxFilterData resultFd = shape->getSimulationFilterData(); + + adjustFilterData(TGroupsMask, fd, resultFd); + + // set new filter data + shape->setSimulationFilterData(resultFd); + } + break; + break; default: break; } diff --git a/physx/source/physxextensions/src/ExtDistanceJoint.cpp b/physx/source/physxextensions/src/ExtDistanceJoint.cpp index 5b311ce2f..bc2793ed9 100644 --- a/physx/source/physxextensions/src/ExtDistanceJoint.cpp +++ b/physx/source/physxextensions/src/ExtDistanceJoint.cpp @@ -37,13 +37,12 @@ DistanceJoint::DistanceJoint(const PxTolerancesScale& scale, PxRigidActor* actor { DistanceJointData* data = static_cast(mData); - data->stiffness = 0.0f; - data->damping = 0.0f; - data->contactDistance = 0.0f; - data->minDistance = 0.0f; - data->maxDistance = 0.0f; - data->tolerance = 0.025f * scale.length; - data->jointFlags = PxDistanceJointFlag::eMAX_DISTANCE_ENABLED; + data->stiffness = 0.0f; + data->damping = 0.0f; + data->minDistance = 0.0f; + data->maxDistance = 0.0f; + data->tolerance = 0.025f * scale.length; + data->jointFlags = PxDistanceJointFlag::eMAX_DISTANCE_ENABLED; } PxReal DistanceJoint::getDistance() const @@ -56,9 +55,8 @@ void DistanceJoint::setMinDistance(PxReal distance) PX_CHECK_AND_RETURN(PxIsFinite(distance) && distance>=0.0f, "PxDistanceJoint::setMinDistance: invalid parameter"); data().minDistance = distance; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceMinDistance, static_cast(*this), distance) -#endif + + OMNI_PVD_SET(PxDistanceJoint, minDistance, static_cast(*this), distance) } PxReal DistanceJoint::getMinDistance() const @@ -71,9 +69,8 @@ void DistanceJoint::setMaxDistance(PxReal distance) PX_CHECK_AND_RETURN(PxIsFinite(distance) && distance>=0.0f, "PxDistanceJoint::setMaxDistance: invalid parameter"); data().maxDistance = distance; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceMaxDistance, static_cast(*this), distance) -#endif + + OMNI_PVD_SET(PxDistanceJoint, maxDistance, static_cast(*this), distance) } PxReal DistanceJoint::getMaxDistance() const @@ -86,9 +83,8 @@ void DistanceJoint::setTolerance(PxReal tolerance) PX_CHECK_AND_RETURN(PxIsFinite(tolerance), "PxDistanceJoint::setTolerance: invalid parameter"); data().tolerance = tolerance; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceTolerance, static_cast(*this), tolerance) -#endif + + OMNI_PVD_SET(PxDistanceJoint, tolerance, static_cast(*this), tolerance) } PxReal DistanceJoint::getTolerance() const @@ -101,9 +97,8 @@ void DistanceJoint::setStiffness(PxReal stiffness) PX_CHECK_AND_RETURN(PxIsFinite(stiffness), "PxDistanceJoint::setStiffness: invalid parameter"); data().stiffness = stiffness; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceStiffness, static_cast(*this), stiffness) -#endif + + OMNI_PVD_SET(PxDistanceJoint, stiffness, static_cast(*this), stiffness) } PxReal DistanceJoint::getStiffness() const @@ -115,10 +110,9 @@ void DistanceJoint::setDamping(PxReal damping) { PX_CHECK_AND_RETURN(PxIsFinite(damping), "PxDistanceJoint::setDamping: invalid parameter"); data().damping = damping; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceDamping, static_cast(*this), damping) -#endif + markDirty(); + + OMNI_PVD_SET(PxDistanceJoint, damping, static_cast(*this), damping) } PxReal DistanceJoint::getDamping() const @@ -126,21 +120,6 @@ PxReal DistanceJoint::getDamping() const return data().damping; } -void DistanceJoint::setContactDistance(PxReal contactDistance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(contactDistance) && contactDistance>=0.0f, "PxDistanceJoint::setContactDistance: invalid parameter"); - data().contactDistance = contactDistance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceContactDistance, static_cast(*this), contactDistance) -#endif -} - -PxReal DistanceJoint::getContactDistance() const -{ - return data().contactDistance; -} - PxDistanceJointFlags DistanceJoint::getDistanceJointFlags(void) const { return data().jointFlags; @@ -149,10 +128,9 @@ PxDistanceJointFlags DistanceJoint::getDistanceJointFlags(void) const void DistanceJoint::setDistanceJointFlags(PxDistanceJointFlags flags) { data().jointFlags = flags; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceJointFlags, static_cast(*this), flags) -#endif + markDirty(); + + OMNI_PVD_SET(PxDistanceJoint, jointFlags, static_cast(*this), flags) } void DistanceJoint::setDistanceJointFlag(PxDistanceJointFlag::Enum flag, bool value) @@ -162,21 +140,15 @@ void DistanceJoint::setDistanceJointFlag(PxDistanceJointFlag::Enum flag, bool va else data().jointFlags &= ~flag; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, distanceJointFlags, static_cast(*this), getDistanceJointFlags()) -#endif -} -static void DistanceJointProject(const void* /*constantBlock*/, PxTransform& /*bodyAToWorld*/, PxTransform& /*bodyBToWorld*/, bool /*projectToA*/) -{ - // TODO + OMNI_PVD_SET(PxDistanceJoint, jointFlags, static_cast(*this), getDistanceJointFlags()) } static void DistanceJointVisualize(PxConstraintVisualizer& viz, const void* constantBlock, const PxTransform& body0Transform, const PxTransform& body1Transform, PxU32 flags) { const DistanceJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); if(flags & PxConstraintVisualizationFlag::eLOCAL_FRAMES) viz.visualizeJointFrames(cA2w, cB2w); @@ -202,7 +174,7 @@ static void DistanceJointVisualize(PxConstraintVisualizer& viz, const void* cons } } -static PX_FORCE_INLINE void setupContraint(Px1DConstraint& c, const PxVec3& direction, const PxVec3& angular0, const PxVec3& angular1, const DistanceJointData& data) +static PX_FORCE_INLINE void setupConstraint(Px1DConstraint& c, const PxVec3& direction, const PxVec3& angular0, const PxVec3& angular1, const DistanceJointData& data) { // constraint is breakable, so we need to output forces @@ -219,32 +191,24 @@ static PX_FORCE_INLINE void setupContraint(Px1DConstraint& c, const PxVec3& dire } } -static PX_FORCE_INLINE PxU32 setupMinConstraint(Px1DConstraint& c, const PxVec3& direction, const PxVec3& angular0, const PxVec3& angular1, const DistanceJointData& data, float distance, float contactDistance) +static PX_FORCE_INLINE PxU32 setupMinConstraint(Px1DConstraint& c, const PxVec3& direction, const PxVec3& angular0, const PxVec3& angular1, const DistanceJointData& data, float distance) { - if(distance < data.minDistance + contactDistance) - { - setupContraint(c, direction, angular0, angular1, data); - c.geometricError = distance - data.minDistance + data.tolerance; - c.minImpulse = 0.0f; - if(distance>=data.minDistance) - c.flags |= Px1DConstraintFlag::eKEEPBIAS; - return 1; - } - return 0; + setupConstraint(c, direction, angular0, angular1, data); + c.geometricError = distance - data.minDistance + data.tolerance; + c.minImpulse = 0.0f; + if(distance>=data.minDistance) + c.flags |= Px1DConstraintFlag::eKEEPBIAS; + return 1; } -static PX_FORCE_INLINE PxU32 setupMaxConstraint(Px1DConstraint& c, const PxVec3& direction, const PxVec3& angular0, const PxVec3& angular1, const DistanceJointData& data, float distance, float contactDistance) +static PX_FORCE_INLINE PxU32 setupMaxConstraint(Px1DConstraint& c, const PxVec3& direction, const PxVec3& angular0, const PxVec3& angular1, const DistanceJointData& data, float distance) { - if(distance > data.maxDistance - contactDistance) - { - setupContraint(c, direction, angular0, angular1, data); - c.geometricError = distance - data.maxDistance - data.tolerance; - c.maxImpulse = 0.0f; - if(distance<=data.maxDistance) - c.flags |= Px1DConstraintFlag::eKEEPBIAS; - return 1; - } - return 0; + setupConstraint(c, direction, angular0, angular1, data); + c.geometricError = distance - data.maxDistance - data.tolerance; + c.maxImpulse = 0.0f; + if(distance<=data.maxDistance) + c.flags |= Px1DConstraintFlag::eKEEPBIAS; + return 1; } //TAG:solverprepshader @@ -265,7 +229,7 @@ static PxU32 DistanceJointSolverPrep(Px1DConstraint* constraints, if(!enforceMax && !enforceMin) return 0; - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); cA2wOut = cB2w.p; @@ -285,14 +249,14 @@ static PxU32 DistanceJointSolverPrep(Px1DConstraint* constraints, const PxVec3 angular1 = ch.getRb().cross(direction); if(enforceMin && !enforceMax) - return setupMinConstraint(*c, direction, angular0, angular1, data, distance, data.contactDistance); + return setupMinConstraint(*c, direction, angular0, angular1, data, distance); else if(enforceMax && !enforceMin) - return setupMaxConstraint(*c, direction, angular0, angular1, data, distance, data.contactDistance); + return setupMaxConstraint(*c, direction, angular0, angular1, data, distance); else { if(data.minDistance == data.maxDistance) { - setupContraint(*c, direction, angular0, angular1, data); + setupConstraint(*c, direction, angular0, angular1, data); //add tolerance so we don't have contact-style jitter problem. const PxReal error = distance - data.maxDistance; @@ -302,17 +266,17 @@ static PxU32 DistanceJointSolverPrep(Px1DConstraint* constraints, } // since we dont know the current rigid velocity, we need to insert row for both limits - PxU32 nb = setupMinConstraint(*c, direction, angular0, angular1, data, distance, data.contactDistance); + PxU32 nb = setupMinConstraint(*c, direction, angular0, angular1, data, distance); if(nb) c++; - nb += setupMaxConstraint(*c, direction, angular0, angular1, data, distance, data.contactDistance); + nb += setupMaxConstraint(*c, direction, angular0, angular1, data, distance); return nb; } } /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gDistanceJointShaders = { DistanceJointSolverPrep, DistanceJointProject, DistanceJointVisualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable gDistanceJointShaders = { DistanceJointSolverPrep, DistanceJointVisualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep DistanceJoint::getPrep() const { return gDistanceJointShaders.solverPrep; } @@ -338,22 +302,23 @@ void DistanceJoint::resolveReferences(PxDeserializationContext& context) void DistanceJoint::updateOmniPvdProperties() const { const PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, distanceDistance, j, getDistance()) + OMNI_PVD_SET(PxDistanceJoint, distance, j, getDistance()) } template<> void physx::Ext::omniPvdInitJoint(DistanceJoint* joint) -{ - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eDISTANCE) - OMNI_PVD_SET(joint, distanceMinDistance, j, joint->getMinDistance()) - OMNI_PVD_SET(joint, distanceMaxDistance, j, joint->getMaxDistance()) - OMNI_PVD_SET(joint, distanceTolerance, j, joint->getTolerance()) - OMNI_PVD_SET(joint, distanceStiffness, j, joint->getStiffness()) - OMNI_PVD_SET(joint, distanceDamping, j, joint->getDamping()) - OMNI_PVD_SET(joint, distanceContactDistance, j, joint->getContactDistance()) - OMNI_PVD_SET(joint, distanceJointFlags, j, joint->getDistanceJointFlags()) - OMNI_PVD_SET(joint, distanceDistance, j, joint->getDistance()) +{ + PxDistanceJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxDistanceJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eDISTANCE); + + OMNI_PVD_SET(PxDistanceJoint, minDistance, j, joint->getMinDistance()) + OMNI_PVD_SET(PxDistanceJoint, maxDistance, j, joint->getMaxDistance()) + OMNI_PVD_SET(PxDistanceJoint, tolerance, j, joint->getTolerance()) + OMNI_PVD_SET(PxDistanceJoint, stiffness, j, joint->getStiffness()) + OMNI_PVD_SET(PxDistanceJoint, damping, j, joint->getDamping()) + OMNI_PVD_SET(PxDistanceJoint, jointFlags, j, joint->getDistanceJointFlags()) + OMNI_PVD_SET(PxDistanceJoint, distance, j, joint->getDistance()) } #endif diff --git a/physx/source/physxextensions/src/ExtDistanceJoint.h b/physx/source/physxextensions/src/ExtDistanceJoint.h index e7d1e8d40..2f77944b7 100644 --- a/physx/source/physxextensions/src/ExtDistanceJoint.h +++ b/physx/source/physxextensions/src/ExtDistanceJoint.h @@ -43,19 +43,11 @@ namespace Ext { struct DistanceJointData : public JointData { - //= 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. - //================================================================================================== - PxReal minDistance; PxReal maxDistance; PxReal tolerance; PxReal stiffness; PxReal damping; - PxReal contactDistance; PxDistanceJointFlags jointFlags; }; @@ -63,12 +55,6 @@ namespace Ext typedef JointT DistanceJointT; class DistanceJoint : public DistanceJointT { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION DistanceJoint(PxBaseFlags baseFlags) : DistanceJointT(baseFlags) {} @@ -89,8 +75,6 @@ namespace Ext virtual PxReal getStiffness() const PX_OVERRIDE; virtual void setDamping(PxReal damping) PX_OVERRIDE; virtual PxReal getDamping() const PX_OVERRIDE; - virtual void setContactDistance(PxReal contactDistance) PX_OVERRIDE; - virtual PxReal getContactDistance() const PX_OVERRIDE; virtual void setDistanceJointFlags(PxDistanceJointFlags flags) PX_OVERRIDE; virtual void setDistanceJointFlag(PxDistanceJointFlag::Enum flag, bool value) PX_OVERRIDE; virtual PxDistanceJointFlags getDistanceJointFlags() const PX_OVERRIDE; diff --git a/physx/source/physxextensions/src/ExtFixedJoint.cpp b/physx/source/physxextensions/src/ExtFixedJoint.cpp index 192376d72..e9326c6a8 100644 --- a/physx/source/physxextensions/src/ExtFixedJoint.cpp +++ b/physx/source/physxextensions/src/ExtFixedJoint.cpp @@ -35,55 +35,7 @@ using namespace Ext; FixedJoint::FixedJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1) : FixedJointT(PxJointConcreteType::eFIXED, actor0, localFrame0, actor1, localFrame1, "FixedJointData") { - FixedJointData* data = static_cast(mData); - - data->projectionLinearTolerance = 1e10f; - data->projectionAngularTolerance = PxPi; -} - -PxReal FixedJoint::getProjectionLinearTolerance() const -{ - return data().projectionLinearTolerance; -} - -void FixedJoint::setProjectionLinearTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0, "PxFixedJoint::setProjectionLinearTolerance: invalid parameter"); - data().projectionLinearTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, fixedProjectionLinearTolerance, static_cast(*this), tolerance) -#endif -} - -PxReal FixedJoint::getProjectionAngularTolerance() const -{ - return data().projectionAngularTolerance; -} - -void FixedJoint::setProjectionAngularTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0 && tolerance <= PxPi, "PxFixedJoint::setProjectionAngularTolerance: invalid parameter"); - data().projectionAngularTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, fixedProjectionAngularTolerance, static_cast(*this), tolerance) -#endif -} - -static void FixedJointProject(const void* constantBlock, PxTransform& bodyAToWorld, PxTransform& bodyBToWorld, bool projectToA) -{ - const FixedJointData &data = *reinterpret_cast(constantBlock); - - PxTransform cA2w, cB2w, cB2cA, projected; - joint::computeDerived(data, bodyAToWorld, bodyBToWorld, cA2w, cB2w, cB2cA); - - bool linearTrunc, angularTrunc; - projected.p = joint::truncateLinear(cB2cA.p, data.projectionLinearTolerance, linearTrunc); - projected.q = joint::truncateAngular(cB2cA.q, PxSin(data.projectionAngularTolerance/2), PxCos(data.projectionAngularTolerance/2), angularTrunc); - - if(linearTrunc || angularTrunc) - joint::projectTransforms(bodyAToWorld, bodyBToWorld, cA2w, cB2w, projected, data, projectToA); +// FixedJointData* data = static_cast(mData); } static void FixedJointVisualize(PxConstraintVisualizer& viz, const void* constantBlock, const PxTransform& body0Transform, const PxTransform& body1Transform, PxU32 flags) @@ -92,7 +44,7 @@ static void FixedJointVisualize(PxConstraintVisualizer& viz, const void* constan { const FixedJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); viz.visualizeJointFrames(cA2w, cB2w); } @@ -111,11 +63,10 @@ static PxU32 FixedJointSolverPrep(Px1DConstraint* constraints, { const FixedJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); - if (cA2w.q.dot(cB2w.q)<0.0f) // minimum dist quat (equiv to flipping cB2bB.q, which we don't use anywhere) - cB2w.q = -cB2w.q; + joint::applyNeighborhoodOperator(cA2w, cB2w); PxVec3 ra, rb; ch.prepareLockedAxes(cA2w.q, cB2w.q, cA2w.transformInv(cB2w.p), 7, 7, ra, rb); @@ -127,7 +78,7 @@ static PxU32 FixedJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gFixedJointShaders = { FixedJointSolverPrep, FixedJointProject, FixedJointVisualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable gFixedJointShaders = { FixedJointSolverPrep, FixedJointVisualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep FixedJoint::getPrep() const { return gFixedJointShaders.solverPrep; } @@ -153,10 +104,9 @@ void FixedJoint::resolveReferences(PxDeserializationContext& context) template<> void physx::Ext::omniPvdInitJoint(FixedJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eFIXED) - OMNI_PVD_SET(joint, fixedProjectionLinearTolerance, j, joint->getProjectionLinearTolerance()) - OMNI_PVD_SET(joint, fixedProjectionAngularTolerance, j, joint->getProjectionAngularTolerance()) + PxFixedJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxFixedJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eFIXED); } #endif diff --git a/physx/source/physxextensions/src/ExtFixedJoint.h b/physx/source/physxextensions/src/ExtFixedJoint.h index a070fff19..8b697f713 100644 --- a/physx/source/physxextensions/src/ExtFixedJoint.h +++ b/physx/source/physxextensions/src/ExtFixedJoint.h @@ -41,27 +41,12 @@ namespace Ext { struct FixedJointData : public JointData { - //= 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. - //================================================================================================== - - PxReal projectionLinearTolerance; - PxReal projectionAngularTolerance; }; typedef JointT FixedJointT; class FixedJoint : public FixedJointT { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION FixedJoint(PxBaseFlags baseFlags) : FixedJointT(baseFlags) {} @@ -71,10 +56,6 @@ namespace Ext //~PX_SERIALIZATION FixedJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); // PxFixedJoint - virtual void setProjectionLinearTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionLinearTolerance() const PX_OVERRIDE; - virtual void setProjectionAngularTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionAngularTolerance() const PX_OVERRIDE; //~PxFixedJoint // PxConstraintConnector diff --git a/physx/source/physxextensions/src/ExtGearJoint.cpp b/physx/source/physxextensions/src/ExtGearJoint.cpp index 12ea1d56f..60fe28d21 100644 --- a/physx/source/physxextensions/src/ExtGearJoint.cpp +++ b/physx/source/physxextensions/src/ExtGearJoint.cpp @@ -35,6 +35,8 @@ using namespace physx; using namespace Ext; +PX_IMPLEMENT_OUTPUT_ERROR + GearJoint::GearJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1) : GearJointT(PxJointConcreteType::eGEAR, actor0, localFrame0, actor1, localFrame1, "GearJointData") { @@ -52,10 +54,7 @@ bool GearJoint::setHinges(const PxBase* hinge0, const PxBase* hinge1) GearJointData* data = static_cast(mData); if(!hinge0 || !hinge1) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setHinges: cannot pass null pointers to this function."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setHinges: cannot pass null pointers to this function."); const PxType type0 = hinge0->getConcreteType(); if(type0 == PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE) @@ -63,18 +62,12 @@ bool GearJoint::setHinges(const PxBase* hinge0, const PxBase* hinge1) const PxArticulationJointReducedCoordinate* joint0 = static_cast(hinge0); const PxArticulationJointType::Enum artiJointType = joint0->getJointType(); if(artiJointType != PxArticulationJointType::eREVOLUTE && artiJointType != PxArticulationJointType::eREVOLUTE_UNWRAPPED) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint."); } else { if(type0 != PxJointConcreteType::eREVOLUTE && type0 != PxJointConcreteType::eD6) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint or a D6 joint."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint or a D6 joint."); } const PxType type1 = hinge1->getConcreteType(); @@ -83,18 +76,12 @@ bool GearJoint::setHinges(const PxBase* hinge0, const PxBase* hinge1) const PxArticulationJointReducedCoordinate* joint1 = static_cast(hinge1); const PxArticulationJointType::Enum artiJointType = joint1->getJointType(); if(artiJointType != PxArticulationJointType::eREVOLUTE && artiJointType != PxArticulationJointType::eREVOLUTE_UNWRAPPED) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint."); } else { if(type1 != PxJointConcreteType::eREVOLUTE && type1 != PxJointConcreteType::eD6) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint or a D6 joint."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setHinges: passed joint must be either a revolute joint or a D6 joint."); } data->hingeJoint0 = hinge0; @@ -105,21 +92,27 @@ bool GearJoint::setHinges(const PxBase* hinge0, const PxBase* hinge1) #if PX_SUPPORT_OMNI_PVD const PxBase* joints[] ={ hinge0, hinge1 }; PxU32 jointsLength = sizeof(joints); - OMNI_PVD_SETB(joint, gearHinges, static_cast(*this), joints, jointsLength) + OMNI_PVD_SETB(PxGearJoint, hinges, static_cast(*this), joints, jointsLength) #endif return true; } +void GearJoint::getHinges(const PxBase*& hinge0, const PxBase*& hinge1) const +{ + const GearJointData* data = static_cast(mData); + hinge0 = data->hingeJoint0; + hinge1 = data->hingeJoint1; +} + void GearJoint::setGearRatio(float ratio) { GearJointData* data = static_cast(mData); data->gearRatio = ratio; resetError(); markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, gearRatio, static_cast(*this), ratio) -#endif + + OMNI_PVD_SET(PxGearJoint, ratio, static_cast(*this), ratio) } float GearJoint::getGearRatio() const @@ -221,11 +214,6 @@ void GearJoint::resetError() mInitDone = false; } -static void GearJointProject(const void* /*constantBlock*/, PxTransform& /*bodyAToWorld*/, PxTransform& /*bodyBToWorld*/, bool /*projectToA*/) -{ -// const GearJointData& data = *reinterpret_cast(constantBlock); -} - static const bool gVizJointFrames = true; static const bool gVizGearAxes = false; @@ -236,7 +224,7 @@ static void GearJointVisualize(PxConstraintVisualizer& viz, const void* constant const GearJointData& data = *reinterpret_cast(constantBlock); // Visualize joint frames - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); if(gVizJointFrames) viz.visualizeJointFrames(cA2w, cB2w); @@ -264,7 +252,7 @@ static PxU32 GearJointSolverPrep(Px1DConstraint* constraints, { const GearJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); cA2wOut = cB2w.p; @@ -292,7 +280,7 @@ static PxU32 GearJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gGearJointShaders = { GearJointSolverPrep, GearJointProject, GearJointVisualize, PxConstraintFlag::eALWAYS_UPDATE }; +static PxConstraintShaderTable gGearJointShaders = { GearJointSolverPrep, GearJointVisualize, PxConstraintFlag::eALWAYS_UPDATE }; PxConstraintSolverPrep GearJoint::getPrep() const { return gGearJointShaders.solverPrep; } @@ -322,9 +310,10 @@ void GearJoint::resolveReferences(PxDeserializationContext& context) template<> void physx::Ext::omniPvdInitJoint(GearJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eGEAR) - OMNI_PVD_SET(joint, gearRatio, j, joint->getGearRatio()) + PxGearJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxGearJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eGEAR); + OMNI_PVD_SET(PxGearJoint, ratio, j , joint->getGearRatio()) } #endif diff --git a/physx/source/physxextensions/src/ExtGearJoint.h b/physx/source/physxextensions/src/ExtGearJoint.h index 1fd51e622..b79dbd345 100644 --- a/physx/source/physxextensions/src/ExtGearJoint.h +++ b/physx/source/physxextensions/src/ExtGearJoint.h @@ -60,6 +60,7 @@ namespace Ext GearJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); // PxGearJoint virtual bool setHinges(const PxBase* hinge0, const PxBase* hinge1) PX_OVERRIDE; + virtual void getHinges(const PxBase*& hinge0, const PxBase*& hinge1) const PX_OVERRIDE; virtual void setGearRatio(float ratio) PX_OVERRIDE; virtual float getGearRatio() const PX_OVERRIDE; //~PxGearJoint diff --git a/physx/source/physxextensions/src/ExtJoint.cpp b/physx/source/physxextensions/src/ExtJoint.cpp index 1d2daa382..66f97f7fe 100644 --- a/physx/source/physxextensions/src/ExtJoint.cpp +++ b/physx/source/physxextensions/src/ExtJoint.cpp @@ -124,31 +124,31 @@ void PxSetJointGlobalFrame(PxJoint& joint, const PxVec3* wsAnchor, const PxVec3* #if PX_SUPPORT_OMNI_PVD -void physx::Ext::omniPvdCreateJoint(PxJoint* joint) -{ - PxJoint& j = static_cast(*joint); - OMNI_PVD_CREATE(joint, j) +void physx::Ext::omniPvdSetBaseJointParams(PxJoint& joint, PxJointConcreteType::Enum cType) +{ + PxJoint& j = static_cast(joint); PxRigidActor* actors[2]; j.getActors(actors[0], actors[1]); - OMNI_PVD_SET(joint, actor0, j, actors[0]) - OMNI_PVD_SET(joint, actor1, j, actors[1]) + OMNI_PVD_SET(PxJoint, actor0, j, actors[0]) + OMNI_PVD_SET(PxJoint, actor1, j, actors[1]) PxTransform actor0LocalPose = j.getLocalPose(PxJointActorIndex::eACTOR0); - OMNI_PVD_SET(joint, actor0LocalPose, j, actor0LocalPose) + OMNI_PVD_SET(PxJoint, actor0LocalPose, j, actor0LocalPose) PxTransform actor1LocalPose = j.getLocalPose(PxJointActorIndex::eACTOR1); - OMNI_PVD_SET(joint, actor1LocalPose, j, actor1LocalPose) + OMNI_PVD_SET(PxJoint, actor1LocalPose, j, actor1LocalPose) PxReal breakForce, breakTorque; j.getBreakForce(breakForce, breakTorque); - OMNI_PVD_SET(joint, breakForce, j, breakForce) - OMNI_PVD_SET(joint, breakTorque, j, breakTorque) - OMNI_PVD_SET(joint, constraintFlags, j, j.getConstraintFlags()) - OMNI_PVD_SET(joint, invMassScale0, j, j.getInvMassScale0()) - OMNI_PVD_SET(joint, invInertiaScale0, j, j.getInvInertiaScale0()) - OMNI_PVD_SET(joint, invMassScale1, j, j.getInvMassScale1()) - OMNI_PVD_SET(joint, invInertiaScale1, j, j.getInvInertiaScale1()) + OMNI_PVD_SET(PxJoint, breakForce, j, breakForce) + OMNI_PVD_SET(PxJoint, breakTorque, j, breakTorque) + OMNI_PVD_SET(PxJoint, constraintFlags, j, j.getConstraintFlags()) + OMNI_PVD_SET(PxJoint, invMassScale0, j, j.getInvMassScale0()) + OMNI_PVD_SET(PxJoint, invInertiaScale0, j, j.getInvInertiaScale0()) + OMNI_PVD_SET(PxJoint, invMassScale1, j, j.getInvMassScale1()) + OMNI_PVD_SET(PxJoint, invInertiaScale1, j, j.getInvInertiaScale1()) const char* name = j.getName() ? j.getName() : ""; PxU32 nameLen = PxU32(strlen(name)) + 1; - OMNI_PVD_SETB(joint, name, j, name, nameLen) + OMNI_PVD_SETB(PxJoint, name, j, name, nameLen) const char* typeName = j.getConcreteTypeName(); PxU32 typeNameLen = PxU32(strlen(typeName)) + 1; - OMNI_PVD_SETB(joint, concreteTypeName, j, typeName, typeNameLen) + OMNI_PVD_SETB(PxJoint, concreteTypeName, j, typeName, typeNameLen) + OMNI_PVD_SET(PxJoint, type, j, cType) } #endif diff --git a/physx/source/physxextensions/src/ExtJoint.h b/physx/source/physxextensions/src/ExtJoint.h index 8130f433d..cb3345061 100644 --- a/physx/source/physxextensions/src/ExtJoint.h +++ b/physx/source/physxextensions/src/ExtJoint.h @@ -48,9 +48,7 @@ #include "PxPvdClient.h" #endif -#if PX_SUPPORT_OMNI_PVD -# include "omnipvd/OmniPvdPxExtensionsSampler.h" -#endif +#include "omnipvd/OmniPvdPxExtensionsSampler.h" namespace physx { @@ -80,7 +78,6 @@ namespace Ext #if PX_SUPPORT_OMNI_PVD if (j) { - omniPvdCreateJoint(j); omniPvdInitJoint(j); } #endif @@ -214,10 +211,8 @@ namespace Ext mData->c2b[1] = getCom(actor1).transformInv(mLocalPose[1]); mPxConstraint->markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, actor0, static_cast(*this), actor0) - OMNI_PVD_SET(joint, actor1, static_cast(*this), actor1) -#endif + OMNI_PVD_SET(PxJoint, actor0, static_cast(*this), actor0) + OMNI_PVD_SET(PxJoint, actor1, static_cast(*this), actor1) } // PxJoint @@ -244,10 +239,8 @@ namespace Ext mData->c2b[actor] = getCom(actor).transformInv(p); mPxConstraint->markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, actor0LocalPose, static_cast(*this), mLocalPose[0]) - OMNI_PVD_SET(joint, actor1LocalPose, static_cast(*this), mLocalPose[1]) -#endif + OMNI_PVD_SET(PxJoint, actor0LocalPose, static_cast(*this), mLocalPose[0]) + OMNI_PVD_SET(PxJoint, actor1LocalPose, static_cast(*this), mLocalPose[1]) } // PxJoint @@ -320,10 +313,9 @@ namespace Ext { PX_CHECK_AND_RETURN(PxIsFinite(force) && PxIsFinite(torque), "PxJoint::setBreakForce: invalid float"); mPxConstraint->setBreakForce(force,torque); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, breakForce, static_cast(*this), force) - OMNI_PVD_SET(joint, breakTorque, static_cast(*this), torque) -#endif + + OMNI_PVD_SET(PxJoint, breakForce, static_cast(*this), force) + OMNI_PVD_SET(PxJoint, breakTorque, static_cast(*this), torque) } // PxJoint @@ -336,18 +328,16 @@ namespace Ext virtual void setConstraintFlags(PxConstraintFlags flags) PX_OVERRIDE { mPxConstraint->setFlags(flags); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, constraintFlags, static_cast(*this), flags) -#endif + + OMNI_PVD_SET(PxJoint, constraintFlags, static_cast(*this), flags) } // PxJoint virtual void setConstraintFlag(PxConstraintFlag::Enum flag, bool value) PX_OVERRIDE { mPxConstraint->setFlag(flag, value); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, constraintFlags, static_cast(*this), getConstraintFlags()) -#endif + + OMNI_PVD_SET(PxJoint, constraintFlags, static_cast(*this), getConstraintFlags()) } // PxJoint @@ -362,9 +352,8 @@ namespace Ext PX_CHECK_AND_RETURN(PxIsFinite(invMassScale) && invMassScale>=0, "PxJoint::setInvMassScale0: scale must be non-negative"); mData->invMassScale.linear0 = invMassScale; mPxConstraint->markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, invMassScale0, static_cast(*this), invMassScale) -#endif + + OMNI_PVD_SET(PxJoint, invMassScale0, static_cast(*this), invMassScale) } // PxJoint @@ -379,9 +368,8 @@ namespace Ext PX_CHECK_AND_RETURN(PxIsFinite(invInertiaScale) && invInertiaScale>=0, "PxJoint::setInvInertiaScale0: scale must be non-negative"); mData->invMassScale.angular0 = invInertiaScale; mPxConstraint->markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, invInertiaScale0, static_cast(*this), invInertiaScale) -#endif + + OMNI_PVD_SET(PxJoint, invInertiaScale0, static_cast(*this), invInertiaScale) } // PxJoint @@ -396,9 +384,8 @@ namespace Ext PX_CHECK_AND_RETURN(PxIsFinite(invMassScale) && invMassScale>=0, "PxJoint::setInvMassScale1: scale must be non-negative"); mData->invMassScale.linear1 = invMassScale; mPxConstraint->markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, invMassScale1, static_cast(*this), invMassScale) -#endif + + OMNI_PVD_SET(PxJoint, invMassScale1, static_cast(*this), invMassScale) } // PxJoint @@ -413,9 +400,8 @@ namespace Ext PX_CHECK_AND_RETURN(PxIsFinite(invInertiaScale) && invInertiaScale>=0, "PxJoint::setInvInertiaScale: scale must be non-negative"); mData->invMassScale.angular1 = invInertiaScale; mPxConstraint->markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, invInertiaScale1, static_cast(*this), invInertiaScale) -#endif + + OMNI_PVD_SET(PxJoint, invInertiaScale1, static_cast(*this), invInertiaScale) } // PxJoint @@ -437,7 +423,7 @@ namespace Ext #if PX_SUPPORT_OMNI_PVD const char* n = name ? name : ""; PxU32 nLen = PxU32(strlen(n)) + 1; - OMNI_PVD_SETB(joint, name, static_cast(*this), n, nLen) + OMNI_PVD_SETB(PxJoint, name, static_cast(*this), n, nLen) #endif } @@ -575,9 +561,7 @@ namespace Ext if(Base::getBaseFlags() & PxBaseFlag::eOWNS_MEMORY) PX_FREE(mData); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_DESTROY(joint, static_cast(*this)) -#endif + OMNI_PVD_DESTROY(PxJoint, static_cast(*this)) } PX_FORCE_INLINE DataClass& data() const @@ -701,21 +685,8 @@ namespace Ext JointData* mData; }; - PX_FORCE_INLINE bool isLimitActive(const PxJointLimitParameters& limit, PxReal pad, PxReal angle, PxReal low, PxReal high) - { - PX_ASSERT(low high - pad) - active = true; - return active; - } - #if PX_SUPPORT_OMNI_PVD - void omniPvdCreateJoint(PxJoint* joint); + void omniPvdSetBaseJointParams(PxJoint& joint, PxJointConcreteType::Enum cType); template void omniPvdInitJoint(JointType* joint); #endif diff --git a/physx/source/physxextensions/src/ExtJointData.h b/physx/source/physxextensions/src/ExtJointData.h index db7f50afb..fbc1cc9f5 100644 --- a/physx/source/physxextensions/src/ExtJointData.h +++ b/physx/source/physxextensions/src/ExtJointData.h @@ -37,15 +37,8 @@ namespace Ext { struct JointData { - //= 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. - //================================================================================================== - PxConstraintInvMassScale invMassScale; //16 - PxTransform c2b[2]; //72 - PxU32 pading[2]; //80 + PxConstraintInvMassScale invMassScale; + PxTransform32 c2b[2]; protected: ~JointData() {} }; diff --git a/physx/source/physxextensions/src/ExtMetaData.cpp b/physx/source/physxextensions/src/ExtMetaData.cpp index be329a736..142d56b57 100644 --- a/physx/source/physxextensions/src/ExtMetaData.cpp +++ b/physx/source/physxextensions/src/ExtMetaData.cpp @@ -51,10 +51,7 @@ static void getBinaryMetaData_JointData(PxOutputStream& stream) { PX_DEF_BIN_METADATA_CLASS(stream, JointData) - PX_DEF_BIN_METADATA_ITEMS_AUTO(stream, JointData, PxTransform, c2b, 0) -#ifdef EXPLICIT_PADDING_METADATA - PX_DEF_BIN_METADATA_ITEM(stream, JointData, PxU32, paddingFromFlags, PxMetaDataFlag::ePADDING) -#endif + PX_DEF_BIN_METADATA_ITEMS_AUTO(stream, JointData, PxTransform32, c2b, 0) PX_DEF_BIN_METADATA_ITEM(stream, JointData, PxConstraintInvMassScale, invMassScale, 0) } @@ -77,7 +74,6 @@ static void getBinaryMetaData_PxJointLimitParameters(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, PxJointLimitParameters, PxReal, bounceThreshold, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxJointLimitParameters, PxReal, stiffness, 0) PX_DEF_BIN_METADATA_ITEM(stream, PxJointLimitParameters, PxReal, damping, 0) - PX_DEF_BIN_METADATA_ITEM(stream, PxJointLimitParameters, PxReal, contactDistance_deprecated, 0) } static void getBinaryMetaData_PxJointLinearLimit(PxOutputStream& stream) @@ -149,9 +145,6 @@ static void getBinaryMetaData_RevoluteJointData(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, RevoluteJointData, PxJointAngularLimitPair,limit, 0) - PX_DEF_BIN_METADATA_ITEM(stream, RevoluteJointData, PxReal, projectionLinearTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, RevoluteJointData, PxReal, projectionAngularTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, RevoluteJointData, PxRevoluteJointFlags, jointFlags, 0) #ifdef EXPLICIT_PADDING_METADATA PX_DEF_BIN_METADATA_ITEM(stream, RevoluteJointData, PxU16, paddingFromFlags, PxMetaDataFlag::ePADDING) @@ -188,8 +181,6 @@ static void getBinaryMetaData_SphericalJointData(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, SphericalJointData, PxJointLimitCone, limit, 0) - PX_DEF_BIN_METADATA_ITEM(stream, SphericalJointData, PxReal, projectionLinearTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, SphericalJointData, PxSphericalJointFlags, jointFlags, 0) #ifdef EXPLICIT_PADDING_METADATA PX_DEF_BIN_METADATA_ITEM(stream, SphericalJointData, PxU16, paddingFromFlags, PxMetaDataFlag::ePADDING) @@ -284,9 +275,6 @@ static void getBinaryMetaData_D6JointData(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, D6JointData, PxReal, distanceMinDist, 0) - PX_DEF_BIN_METADATA_ITEM(stream, D6JointData, PxReal, projectionLinearTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, D6JointData, PxReal, projectionAngularTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, D6JointData, bool, mUseDistanceLimit, 0) PX_DEF_BIN_METADATA_ITEM(stream, D6JointData, bool, mUseNewLinearLimits, 0) PX_DEF_BIN_METADATA_ITEM(stream, D6JointData, bool, mUseConeLimit, 0) @@ -325,8 +313,6 @@ static void getBinaryMetaData_PrismaticJointData(PxOutputStream& stream) PX_DEF_BIN_METADATA_BASE_CLASS(stream, PrismaticJointData, JointData) PX_DEF_BIN_METADATA_ITEM(stream, PrismaticJointData, PxJointLinearLimitPair, limit, 0) - PX_DEF_BIN_METADATA_ITEM(stream, PrismaticJointData, PxReal, projectionLinearTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, PrismaticJointData, PxReal, projectionAngularTolerance, 0) PX_DEF_BIN_METADATA_ITEM(stream, PrismaticJointData, PxPrismaticJointFlags, jointFlags, 0) #ifdef EXPLICIT_PADDING_METADATA PX_DEF_BIN_METADATA_ITEM(stream, PrismaticJointData, PxU16, paddingFromFlags, PxMetaDataFlag::ePADDING) @@ -358,9 +344,6 @@ static void getBinaryMetaData_FixedJointData(PxOutputStream& stream) { PX_DEF_BIN_METADATA_CLASS(stream, FixedJointData) PX_DEF_BIN_METADATA_BASE_CLASS(stream, FixedJointData, JointData) - - PX_DEF_BIN_METADATA_ITEM(stream, FixedJointData, PxReal, projectionLinearTolerance, 0) - PX_DEF_BIN_METADATA_ITEM(stream, FixedJointData, PxReal, projectionAngularTolerance, 0) } void FixedJoint::getBinaryMetaData(PxOutputStream& stream) diff --git a/physx/source/physxextensions/src/ExtParticleClothCooker.cpp b/physx/source/physxextensions/src/ExtParticleClothCooker.cpp index c69f86a9e..3ab1bf195 100644 --- a/physx/source/physxextensions/src/ExtParticleClothCooker.cpp +++ b/physx/source/physxextensions/src/ExtParticleClothCooker.cpp @@ -274,24 +274,26 @@ void PxParticleClothCookerImpl::cookConstraints(const PxParticleClothConstraint* //Add all edges to Edges for(PxU32 i = 0; i bestCosAngle) + float cosAngleAbs = PxAbs(dir1.dot(dir2)); + if(cosAngleAbs > bestCosAngle) { - bestCosAngle = cosAngle; + bestCosAngle = cosAngleAbs; bestAdjB = adjB; } } diff --git a/physx/source/physxextensions/src/ExtParticleExt.cpp b/physx/source/physxextensions/src/ExtParticleExt.cpp index 076c7b0a5..85634fc71 100644 --- a/physx/source/physxextensions/src/ExtParticleExt.cpp +++ b/physx/source/physxextensions/src/ExtParticleExt.cpp @@ -240,18 +240,27 @@ void PxParticleAttachmentBuffer::copyToDevice(CUstream stream) void PxParticleAttachmentBuffer::addRigidAttachment(PxRigidActor* rigidActor, const PxU32 particleID, const PxVec3& localPose, PxConeLimitedConstraint* coneLimit) { + PX_CHECK_AND_RETURN(coneLimit == NULL || coneLimit->isValid(), "PxParticleAttachmentBuffer::addRigidAttachment: PxConeLimitedConstraint needs to be valid if specified."); + PX_ASSERT(particleID < mParticleBuffer.getNbActiveParticles()); - PxParticleRigidAttachment attachment; + PxParticleRigidAttachment attachment(PxConeLimitedConstraint(), PxVec4(0.0f)); + if (rigidActor == NULL) + { + PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxParticleAttachmentBuffer::addRigidAttachment: rigidActor cannot be NULL."); + return; + } + if (coneLimit) { - attachment.mParams.axisAngle = PxVec4(coneLimit->mAxis, coneLimit->mAngle); - attachment.mParams.lowHighLimits = PxVec4(coneLimit->mLowLimit, coneLimit->mHighLimit, 0.f, 0.f); + attachment.mConeLimitParams.axisAngle = PxVec4(coneLimit->mAxis, coneLimit->mAngle); + attachment.mConeLimitParams.lowHighLimits = PxVec4(coneLimit->mLowLimit, coneLimit->mHighLimit, 0.f, 0.f); } else { - attachment.mParams.axisAngle = PxVec4(0.f); - attachment.mParams.lowHighLimits = PxVec4(0.f); + attachment.mConeLimitParams.axisAngle = PxVec4(0.f, 0.f, 0.f, -1.f); + attachment.mConeLimitParams.lowHighLimits = PxVec4(0.f); } if (rigidActor->getType() == PxActorType::eRIGID_STATIC) @@ -310,6 +319,13 @@ bool PxParticleAttachmentBuffer::removeRigidAttachment(PxRigidActor* rigidActor, { PX_ASSERT(particleID < mParticleBuffer.getNbActiveParticles()); + if (rigidActor == NULL) + { + PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxParticleAttachmentBuffer::removeRigidAttachment: rigidActor cannot be NULL."); + return false; + } + if (rigidActor) { PxU32& refCount = mReferencedBodies[rigidActor]; diff --git a/physx/source/physxextensions/src/ExtPrismaticJoint.cpp b/physx/source/physxextensions/src/ExtPrismaticJoint.cpp index 94db23614..b9cd5bb7a 100644 --- a/physx/source/physxextensions/src/ExtPrismaticJoint.cpp +++ b/physx/source/physxextensions/src/ExtPrismaticJoint.cpp @@ -37,40 +37,8 @@ PrismaticJoint::PrismaticJoint(const PxTolerancesScale& scale, PxRigidActor* act { PrismaticJointData* data = static_cast(mData); - data->limit = PxJointLinearLimitPair(scale); - data->projectionLinearTolerance = 1e10f; - data->projectionAngularTolerance = PxPi; - data->jointFlags = PxPrismaticJointFlags(); -} - -void PrismaticJoint::setProjectionAngularTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0 && tolerance <= PxPi, "PxPrismaticJoint::setProjectionAngularTolerance: invalid parameter"); - data().projectionAngularTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, prismaticProjectionAngularTolerance, static_cast(*this), tolerance) -#endif -} - -PxReal PrismaticJoint::getProjectionAngularTolerance() const -{ - return data().projectionAngularTolerance; -} - -void PrismaticJoint::setProjectionLinearTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0, "PxPrismaticJoint::setProjectionLinearTolerance: invalid parameter"); - data().projectionLinearTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, prismaticProjectionLinearTolerance, static_cast(*this), tolerance) -#endif -} - -PxReal PrismaticJoint::getProjectionLinearTolerance() const -{ - return data().projectionLinearTolerance; + data->limit = PxJointLinearLimitPair(scale); + data->jointFlags = PxPrismaticJointFlags(); } PxPrismaticJointFlags PrismaticJoint::getPrismaticJointFlags(void) const @@ -80,10 +48,9 @@ PxPrismaticJointFlags PrismaticJoint::getPrismaticJointFlags(void) const void PrismaticJoint::setPrismaticJointFlags(PxPrismaticJointFlags flags) { - data().jointFlags = flags; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, prismaticJointFlags, static_cast(*this), flags) -#endif + data().jointFlags = flags; markDirty(); + + OMNI_PVD_SET(PxPrismaticJoint, jointFlags, static_cast(*this), flags) } void PrismaticJoint::setPrismaticJointFlag(PxPrismaticJointFlag::Enum flag, bool value) @@ -93,9 +60,8 @@ void PrismaticJoint::setPrismaticJointFlag(PxPrismaticJointFlag::Enum flag, bool else data().jointFlags &= ~flag; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, prismaticJointFlags, static_cast(*this), getPrismaticJointFlags()) -#endif + + OMNI_PVD_SET(PxPrismaticJoint, jointFlags, static_cast(*this), getPrismaticJointFlags()) } PxJointLinearLimitPair PrismaticJoint::getLimit() const @@ -109,53 +75,29 @@ void PrismaticJoint::setLimit(const PxJointLinearLimitPair& limit) data().limit = limit; markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, prismaticLimitLower, j, limit.lower) - OMNI_PVD_SET(joint, prismaticLimitUpper, j, limit.upper) - OMNI_PVD_SET(joint, prismaticLimitRestitution, j, limit.restitution) - OMNI_PVD_SET(joint, prismaticLimitBounceThreshold, j, limit.bounceThreshold) - OMNI_PVD_SET(joint, prismaticLimitStiffness, j, limit.stiffness) - OMNI_PVD_SET(joint, prismaticLimitDamping, j, limit.damping) - OMNI_PVD_SET(joint, prismaticLimitContactDistance, j, limit.contactDistance_deprecated) + PxPrismaticJoint& j = static_cast(*this); + OMNI_PVD_SET(PxPrismaticJoint, limitLower, j, limit.lower) + OMNI_PVD_SET(PxPrismaticJoint, limitUpper, j, limit.upper) + OMNI_PVD_SET(PxPrismaticJoint, limitRestitution, j, limit.restitution) + OMNI_PVD_SET(PxPrismaticJoint, limitBounceThreshold, j, limit.bounceThreshold) + OMNI_PVD_SET(PxPrismaticJoint, limitStiffness, j, limit.stiffness) + OMNI_PVD_SET(PxPrismaticJoint, limitDamping, j, limit.damping) #endif } -static void PrismaticJointProject(const void* constantBlock, PxTransform& bodyAToWorld, PxTransform& bodyBToWorld, bool projectToA) -{ - const PrismaticJointData& data = *reinterpret_cast(constantBlock); - - PxTransform cA2w, cB2w, cB2cA, projected; - joint::computeDerived(data, bodyAToWorld, bodyBToWorld, cA2w, cB2w, cB2cA); - - const PxVec3 v(0.0f, cB2cA.p.y, cB2cA.p.z); - bool linearTrunc, angularTrunc; - projected.p = joint::truncateLinear(v, data.projectionLinearTolerance, linearTrunc); - projected.q = joint::truncateAngular(cB2cA.q, PxSin(data.projectionAngularTolerance/2), PxCos(data.projectionAngularTolerance/2), angularTrunc); - - if(linearTrunc || angularTrunc) - { - projected.p.x = cB2cA.p.x; - joint::projectTransforms(bodyAToWorld, bodyBToWorld, cA2w, cB2w, projected, data, projectToA); - } -} - static void PrismaticJointVisualize(PxConstraintVisualizer& viz, const void* constantBlock, const PxTransform& body0Transform, const PxTransform& body1Transform, PxU32 flags) { const PrismaticJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); if(flags & PxConstraintVisualizationFlag::eLOCAL_FRAMES) viz.visualizeJointFrames(cA2w, cB2w); if((flags & PxConstraintVisualizationFlag::eLIMITS) && (data.jointFlags & PxPrismaticJointFlag::eLIMIT_ENABLED)) { - const PxVec3 bOriginInA = cA2w.transformInv(cB2w.p); - const PxReal ordinate = bOriginInA.x; - - const PxReal pad = data.limit.isSoft() ? 0.0f : data.limit.contactDistance_deprecated; - viz.visualizeLinearLimit(cA2w, cB2w, data.limit.lower, ordinate < data.limit.lower + pad); - viz.visualizeLinearLimit(cA2w, cB2w, data.limit.upper, ordinate > data.limit.upper - pad); + viz.visualizeLinearLimit(cA2w, cB2w, data.limit.lower); + viz.visualizeLinearLimit(cA2w, cB2w, data.limit.upper); } } @@ -172,26 +114,24 @@ static PxU32 PrismaticJointSolverPrep(Px1DConstraint* constraints, { const PrismaticJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); - if (cA2w.q.dot(cB2w.q)<0.0f) // minimum dist quat (equiv to flipping cB2bB.q, which we don't use anywhere) - cB2w.q = -cB2w.q; + joint::applyNeighborhoodOperator(cA2w, cB2w); const bool limitEnabled = data.jointFlags & PxPrismaticJointFlag::eLIMIT_ENABLED; const PxJointLinearLimitPair& limit = data.limit; const bool limitIsLocked = limitEnabled && limit.lower >= limit.upper; const PxVec3 bOriginInA = cA2w.transformInv(cB2w.p); - PxVec3 ra, rb; - ch.prepareLockedAxes(cA2w.q, cB2w.q, bOriginInA, limitIsLocked ? 7ul : 6ul, 7ul, ra, rb); + + PxVec3 ra, rb, axis; + ch.prepareLockedAxes(cA2w.q, cB2w.q, bOriginInA, limitIsLocked ? 7ul : 6ul, 7ul, ra, rb, &axis); cA2wOut = ra + bA2w.p; cB2wOut = rb + bB2w.p; if(limitEnabled && !limitIsLocked) { - const PxVec3 axis = cA2w.q.getBasisVector0(); // PT: TODO: this has already been computed as part of the quat-to-matrix transform within prepareLockedAxes - const PxReal ordinate = bOriginInA.x; ch.linearLimit(axis, ordinate, limit.upper, limit); @@ -203,7 +143,7 @@ static PxU32 PrismaticJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gPrismaticJointShaders = { PrismaticJointSolverPrep, PrismaticJointProject, PrismaticJointVisualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable gPrismaticJointShaders = { PrismaticJointSolverPrep, PrismaticJointVisualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep PrismaticJoint::getPrep() const { return gPrismaticJointShaders.solverPrep; } @@ -228,30 +168,28 @@ void PrismaticJoint::resolveReferences(PxDeserializationContext& context) void PrismaticJoint::updateOmniPvdProperties() const { - const PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, prismaticPosition, j, getPosition()) - OMNI_PVD_SET(joint, prismaticVelocity, j, getVelocity()) + const PxPrismaticJoint& j = static_cast(*this); + OMNI_PVD_SET(PxPrismaticJoint, position, j, getPosition()) + OMNI_PVD_SET(PxPrismaticJoint, velocity, j, getVelocity()) } template<> void physx::Ext::omniPvdInitJoint(PrismaticJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::ePRISMATIC) - OMNI_PVD_SET(joint, prismaticProjectionLinearTolerance, j, joint->getProjectionLinearTolerance()) - OMNI_PVD_SET(joint, prismaticProjectionAngularTolerance, j, joint->getProjectionAngularTolerance()) + PxPrismaticJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxPrismaticJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::ePRISMATIC); PxJointLinearLimitPair limit = joint->getLimit(); - OMNI_PVD_SET(joint, prismaticLimitLower, j, limit.lower) - OMNI_PVD_SET(joint, prismaticLimitUpper, j, limit.upper) - OMNI_PVD_SET(joint, prismaticLimitRestitution, j, limit.restitution) - OMNI_PVD_SET(joint, prismaticLimitBounceThreshold, j, limit.bounceThreshold) - OMNI_PVD_SET(joint, prismaticLimitStiffness, j, limit.stiffness) - OMNI_PVD_SET(joint, prismaticLimitDamping, j, limit.damping) - OMNI_PVD_SET(joint, prismaticLimitContactDistance, j, limit.contactDistance_deprecated) - - OMNI_PVD_SET(joint, prismaticPosition, j, joint->getPosition()) - OMNI_PVD_SET(joint, prismaticVelocity, j, joint->getVelocity()) + OMNI_PVD_SET(PxPrismaticJoint, limitLower, j, limit.lower) + OMNI_PVD_SET(PxPrismaticJoint, limitUpper, j, limit.upper) + OMNI_PVD_SET(PxPrismaticJoint, limitRestitution, j, limit.restitution) + OMNI_PVD_SET(PxPrismaticJoint, limitBounceThreshold, j, limit.bounceThreshold) + OMNI_PVD_SET(PxPrismaticJoint, limitStiffness, j, limit.stiffness) + OMNI_PVD_SET(PxPrismaticJoint, limitDamping, j, limit.damping) + + OMNI_PVD_SET(PxPrismaticJoint, position, j, joint->getPosition()) + OMNI_PVD_SET(PxPrismaticJoint, velocity, j, joint->getVelocity()) } #endif diff --git a/physx/source/physxextensions/src/ExtPrismaticJoint.h b/physx/source/physxextensions/src/ExtPrismaticJoint.h index b42c713ab..f24ba794e 100644 --- a/physx/source/physxextensions/src/ExtPrismaticJoint.h +++ b/physx/source/physxextensions/src/ExtPrismaticJoint.h @@ -42,16 +42,7 @@ namespace Ext { struct PrismaticJointData : public JointData { - //= 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. - //================================================================================================== - PxJointLinearLimitPair limit; - PxReal projectionLinearTolerance; - PxReal projectionAngularTolerance; PxPrismaticJointFlags jointFlags; @@ -63,12 +54,6 @@ namespace Ext class PrismaticJoint : public PrismaticJointT { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION PrismaticJoint(PxBaseFlags baseFlags) : PrismaticJointT(baseFlags) {} @@ -85,10 +70,6 @@ namespace Ext virtual void setPrismaticJointFlags(PxPrismaticJointFlags flags) PX_OVERRIDE; virtual void setPrismaticJointFlag(PxPrismaticJointFlag::Enum flag, bool value) PX_OVERRIDE; virtual PxPrismaticJointFlags getPrismaticJointFlags() const PX_OVERRIDE; - virtual void setProjectionLinearTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionLinearTolerance() const PX_OVERRIDE; - virtual void setProjectionAngularTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionAngularTolerance() const PX_OVERRIDE; //~PxPrismaticJoint // PxConstraintConnector diff --git a/physx/source/physxextensions/src/ExtRackAndPinionJoint.cpp b/physx/source/physxextensions/src/ExtRackAndPinionJoint.cpp index 20b462914..d3695a50d 100644 --- a/physx/source/physxextensions/src/ExtRackAndPinionJoint.cpp +++ b/physx/source/physxextensions/src/ExtRackAndPinionJoint.cpp @@ -36,6 +36,8 @@ using namespace physx; using namespace Ext; +PX_IMPLEMENT_OUTPUT_ERROR + RackAndPinionJoint::RackAndPinionJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1) : RackAndPinionJointT(PxJointConcreteType::eRACK_AND_PINION, actor0, localFrame0, actor1, localFrame1, "RackAndPinionJointData") { @@ -55,9 +57,8 @@ void RackAndPinionJoint::setRatio(float ratio) data->ratio = ratio; resetError(); markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, rackAndPinionRatio, static_cast(*this), ratio) -#endif + + OMNI_PVD_SET(PxRackAndPinionJoint, ratio, static_cast(*this), ratio) } float RackAndPinionJoint::getRatio() const @@ -69,22 +70,13 @@ float RackAndPinionJoint::getRatio() const bool RackAndPinionJoint::setData(PxU32 nbRackTeeth, PxU32 nbPinionTeeth, float rackLength) { if(!nbRackTeeth) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRackAndPinionJoint::setData: nbRackTeeth cannot be zero."); - return false; - } + return outputError(__LINE__, "PxRackAndPinionJoint::setData: nbRackTeeth cannot be zero."); if(!nbPinionTeeth) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRackAndPinionJoint::setData: nbPinionTeeth cannot be zero."); - return false; - } + return outputError(__LINE__, "PxRackAndPinionJoint::setData: nbPinionTeeth cannot be zero."); if(rackLength<=0.0f) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRackAndPinionJoint::setData: rackLength must be positive."); - return false; - } + return outputError(__LINE__, "PxRackAndPinionJoint::setData: rackLength must be positive."); RackAndPinionJointData* data = reinterpret_cast(mData); data->ratio = (PxTwoPi*nbRackTeeth)/(rackLength*nbPinionTeeth); @@ -98,10 +90,7 @@ bool RackAndPinionJoint::setJoints(const PxBase* hinge, const PxBase* prismatic) RackAndPinionJointData* data = static_cast(mData); if(!hinge || !prismatic) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRackAndPinionJoint::setJoints: cannot pass null pointers to this function."); - return false; - } + return outputError(__LINE__, "PxRackAndPinionJoint::setJoints: cannot pass null pointers to this function."); const PxType type0 = hinge->getConcreteType(); if(type0 == PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE) @@ -109,18 +98,12 @@ bool RackAndPinionJoint::setJoints(const PxBase* hinge, const PxBase* prismatic) const PxArticulationJointReducedCoordinate* joint0 = static_cast(hinge); const PxArticulationJointType::Enum artiJointType0 = joint0->getJointType(); if(artiJointType0 != PxArticulationJointType::eREVOLUTE && artiJointType0 != PxArticulationJointType::eREVOLUTE_UNWRAPPED) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setJoints: passed joint must be a revolute joint."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setJoints: passed joint must be a revolute joint."); } else { if(type0 != PxJointConcreteType::eREVOLUTE && type0 != PxJointConcreteType::eD6) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRackAndPinionJoint::setJoints: passed hinge joint must be either a revolute joint or a D6 joint."); - return false; - } + return outputError(__LINE__, "PxRackAndPinionJoint::setJoints: passed hinge joint must be either a revolute joint or a D6 joint."); } const PxType type1 = prismatic->getConcreteType(); @@ -129,18 +112,12 @@ bool RackAndPinionJoint::setJoints(const PxBase* hinge, const PxBase* prismatic) const PxArticulationJointReducedCoordinate* joint1 = static_cast(prismatic); const PxArticulationJointType::Enum artiJointType1 = joint1->getJointType(); if(artiJointType1 != PxArticulationJointType::ePRISMATIC) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxGearJoint::setJoints: passed joint must be a prismatic joint."); - return false; - } + return outputError(__LINE__, "PxGearJoint::setJoints: passed joint must be a prismatic joint."); } else { if(type1 != PxJointConcreteType::ePRISMATIC && type1 != PxJointConcreteType::eD6) - { - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "PxRackAndPinionJoint::setJoints: passed prismatic joint must be either a prismatic joint or a D6 joint."); - return false; - } + return outputError(__LINE__, "PxRackAndPinionJoint::setJoints: passed prismatic joint must be either a prismatic joint or a D6 joint."); } data->hingeJoint = hinge; @@ -151,12 +128,19 @@ bool RackAndPinionJoint::setJoints(const PxBase* hinge, const PxBase* prismatic) #if PX_SUPPORT_OMNI_PVD const PxBase* joints[] ={ hinge, prismatic }; PxU32 jointsLength = sizeof(joints); - OMNI_PVD_SETB(joint, rackAndPinionJoints, static_cast(*this), joints, jointsLength) + OMNI_PVD_SETB(PxRackAndPinionJoint, joints, static_cast(*this), joints, jointsLength) #endif return true; } +void RackAndPinionJoint::getJoints(const PxBase*& hinge, const PxBase*& prismatic) const +{ + const RackAndPinionJointData* data = static_cast(mData); + hinge = data->hingeJoint; + prismatic = data->prismaticJoint; +} + static float angleDiff(float angle0, float angle1) { const float diff = fmodf( angle1 - angle0 + PxPi, PxTwoPi) - PxPi; @@ -271,11 +255,6 @@ void RackAndPinionJoint::resetError() mInitDone = false; } -static void RackAndPinionJointProject(const void* /*constantBlock*/, PxTransform& /*bodyAToWorld*/, PxTransform& /*bodyBToWorld*/, bool /*projectToA*/) -{ -// const RackAndPinionJointData& data = *reinterpret_cast(constantBlock); -} - static void RackAndPinionJointVisualize(PxConstraintVisualizer& viz, const void* constantBlock, const PxTransform& body0Transform, const PxTransform& body1Transform, PxU32 flags) { if(flags & PxConstraintVisualizationFlag::eLOCAL_FRAMES) @@ -283,7 +262,7 @@ static void RackAndPinionJointVisualize(PxConstraintVisualizer& viz, const void* const RackAndPinionJointData& data = *reinterpret_cast(constantBlock); // Visualize joint frames - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); viz.visualizeJointFrames(cA2w, cB2w); } @@ -294,7 +273,7 @@ static void RackAndPinionJointVisualize(PxConstraintVisualizer& viz, const void* if(0) { - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); const PxVec3 gearAxis0 = cA2w.q.getBasisVector0(); @@ -318,7 +297,7 @@ static PxU32 RackAndPinionJointSolverPrep(Px1DConstraint* constraints, { const RackAndPinionJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); cA2wOut = cB2w.p; @@ -366,7 +345,7 @@ static PxU32 RackAndPinionJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gRackAndPinionJointShaders = { RackAndPinionJointSolverPrep, RackAndPinionJointProject, RackAndPinionJointVisualize, PxConstraintFlag::eALWAYS_UPDATE }; +static PxConstraintShaderTable gRackAndPinionJointShaders = { RackAndPinionJointSolverPrep, RackAndPinionJointVisualize, PxConstraintFlag::eALWAYS_UPDATE }; PxConstraintSolverPrep RackAndPinionJoint::getPrep() const { return gRackAndPinionJointShaders.solverPrep; } @@ -396,9 +375,10 @@ void RackAndPinionJoint::resolveReferences(PxDeserializationContext& context) template<> void physx::Ext::omniPvdInitJoint(RackAndPinionJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eRACK_AND_PINION) - OMNI_PVD_SET(joint, rackAndPinionRatio, j, joint->getRatio()) + PxRackAndPinionJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxRackAndPinionJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eRACK_AND_PINION); + OMNI_PVD_SET(PxRackAndPinionJoint, ratio, j, joint->getRatio()) } #endif diff --git a/physx/source/physxextensions/src/ExtRackAndPinionJoint.h b/physx/source/physxextensions/src/ExtRackAndPinionJoint.h index 89e498a04..7dbf7e79f 100644 --- a/physx/source/physxextensions/src/ExtRackAndPinionJoint.h +++ b/physx/source/physxextensions/src/ExtRackAndPinionJoint.h @@ -61,6 +61,7 @@ namespace Ext RackAndPinionJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); // PxRackAndPinionJoint virtual bool setJoints(const PxBase* hinge, const PxBase* prismatic) PX_OVERRIDE; + virtual void getJoints(const PxBase*& hinge, const PxBase*& prismatic) const PX_OVERRIDE; virtual void setRatio(float ratio) PX_OVERRIDE; virtual float getRatio() const PX_OVERRIDE; virtual bool setData(PxU32 nbRackTeeth, PxU32 nbPinionTeeth, float rackLength) PX_OVERRIDE; diff --git a/physx/source/physxextensions/src/ExtRaycastCCD.cpp b/physx/source/physxextensions/src/ExtRaycastCCD.cpp index d2b47ff8b..c7b82d252 100644 --- a/physx/source/physxextensions/src/ExtRaycastCCD.cpp +++ b/physx/source/physxextensions/src/ExtRaycastCCD.cpp @@ -71,12 +71,10 @@ class RaycastCCDManagerInternal static PxVec3 getShapeCenter(PxShape* shape, const PxTransform& pose) { PxVec3 offset(0.0f); - if(shape->getGeometryType()==PxGeometryType::eCONVEXMESH) + const PxGeometry& geom = shape->getGeometry(); + if(geom.getType()==PxGeometryType::eCONVEXMESH) { - PxConvexMeshGeometry geometry; - bool status = shape->getConvexMeshGeometry(geometry); - PX_UNUSED(status); - PX_ASSERT(status); + const PxConvexMeshGeometry& geometry = static_cast(geom); PxReal mass; PxMat33 localInertia; @@ -105,15 +103,12 @@ static PxReal computeInternalRadius(PxRigidActor* actor, PxShape* shape, const P PxReal internalRadius = 0.0f; const PxReal length = offsetFromOrigin*2.0f; - switch(shape->getGeometryType()) + const PxGeometry& geom = shape->getGeometry(); + switch(geom.getType()) { case PxGeometryType::eSPHERE: { - PxSphereGeometry geometry; - bool status = shape->getSphereGeometry(geometry); - PX_UNUSED(status); - PX_ASSERT(status); - + const PxSphereGeometry& geometry = static_cast(geom); internalRadius = geometry.radius; } break; diff --git a/physx/source/physxextensions/src/ExtRevoluteJoint.cpp b/physx/source/physxextensions/src/ExtRevoluteJoint.cpp index 30a53c4b7..44ec7229a 100644 --- a/physx/source/physxextensions/src/ExtRevoluteJoint.cpp +++ b/physx/source/physxextensions/src/ExtRevoluteJoint.cpp @@ -37,13 +37,11 @@ RevoluteJoint::RevoluteJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* a { RevoluteJointData* data = static_cast(mData); - data->projectionLinearTolerance = 1e10f; - data->projectionAngularTolerance = PxPi; - data->driveForceLimit = PX_MAX_F32; - data->driveVelocity = 0.0f; - data->driveGearRatio = 1.0f; - data->limit = PxJointAngularLimitPair(-PxPi/2, PxPi/2); - data->jointFlags = PxRevoluteJointFlags(); + data->driveForceLimit = PX_MAX_F32; + data->driveVelocity = 0.0f; + data->driveGearRatio = 1.0f; + data->limit = PxJointAngularLimitPair(-PxPi/2, PxPi/2); + data->jointFlags = PxRevoluteJointFlags(); } PxReal RevoluteJoint::getAngle() const @@ -70,14 +68,13 @@ void RevoluteJoint::setLimit(const PxJointAngularLimitPair& limit) markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, revoluteLimitLower, j, limit.lower) - OMNI_PVD_SET(joint, revoluteLimitUpper, j, limit.upper) - OMNI_PVD_SET(joint, revoluteLimitRestitution, j, limit.restitution) - OMNI_PVD_SET(joint, revoluteLimitBounceThreshold, j, limit.bounceThreshold) - OMNI_PVD_SET(joint, revoluteLimitStiffness, j, limit.stiffness) - OMNI_PVD_SET(joint, revoluteLimitDamping, j, limit.damping) - OMNI_PVD_SET(joint, revoluteLimitContactDistance, j, limit.contactDistance_deprecated) + PxRevoluteJoint& j = static_cast(*this); + OMNI_PVD_SET(PxRevoluteJoint, limitLower, j, limit.lower) + OMNI_PVD_SET(PxRevoluteJoint, limitUpper, j, limit.upper) + OMNI_PVD_SET(PxRevoluteJoint, limitRestitution, j, limit.restitution) + OMNI_PVD_SET(PxRevoluteJoint, limitBounceThreshold, j, limit.bounceThreshold) + OMNI_PVD_SET(PxRevoluteJoint, limitStiffness, j, limit.stiffness) + OMNI_PVD_SET(PxRevoluteJoint, limitDamping, j, limit.damping) #endif } @@ -92,10 +89,9 @@ void RevoluteJoint::setDriveVelocity(PxReal velocity, bool autowake) data().driveVelocity = velocity; if(autowake) wakeUpActors(); - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteDriveVelocity, static_cast(*this), velocity) -#endif + markDirty(); + + OMNI_PVD_SET(PxRevoluteJoint, driveVelocity, static_cast(*this), velocity) } PxReal RevoluteJoint::getDriveForceLimit() const @@ -107,10 +103,9 @@ void RevoluteJoint::setDriveForceLimit(PxReal forceLimit) { PX_CHECK_AND_RETURN(PxIsFinite(forceLimit), "PxRevoluteJoint::setDriveForceLimit: invalid parameter"); data().driveForceLimit = forceLimit; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteDriveForceLimit, static_cast(*this), forceLimit) -#endif + markDirty(); + + OMNI_PVD_SET(PxRevoluteJoint, driveForceLimit, static_cast(*this), forceLimit) } PxReal RevoluteJoint::getDriveGearRatio() const @@ -122,40 +117,9 @@ void RevoluteJoint::setDriveGearRatio(PxReal gearRatio) { PX_CHECK_AND_RETURN(PxIsFinite(gearRatio) && gearRatio>0, "PxRevoluteJoint::setDriveGearRatio: invalid parameter"); data().driveGearRatio = gearRatio; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteDriveGearRatio, static_cast(*this), gearRatio) -#endif -} - -void RevoluteJoint::setProjectionAngularTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance>=0 && tolerance<=PxPi, "PxRevoluteJoint::setProjectionAngularTolerance: invalid parameter"); - data().projectionAngularTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteProjectionAngularTolerance, static_cast(*this), tolerance) -#endif -} - -PxReal RevoluteJoint::getProjectionAngularTolerance() const -{ - return data().projectionAngularTolerance; -} - -void RevoluteJoint::setProjectionLinearTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0, "PxRevoluteJoint::setProjectionLinearTolerance: invalid parameter"); - data().projectionLinearTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteProjectionLinearTolerance, static_cast(*this), tolerance) -#endif -} + markDirty(); -PxReal RevoluteJoint::getProjectionLinearTolerance() const -{ - return data().projectionLinearTolerance; + OMNI_PVD_SET(PxRevoluteJoint, driveGearRatio, static_cast(*this), gearRatio) } PxRevoluteJointFlags RevoluteJoint::getRevoluteJointFlags(void) const @@ -165,10 +129,9 @@ PxRevoluteJointFlags RevoluteJoint::getRevoluteJointFlags(void) const void RevoluteJoint::setRevoluteJointFlags(PxRevoluteJointFlags flags) { - data().jointFlags = flags; -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteJointFlags, static_cast(*this), flags) -#endif + data().jointFlags = flags; + + OMNI_PVD_SET(PxRevoluteJoint, jointFlags, static_cast(*this), flags) } void RevoluteJoint::setRevoluteJointFlag(PxRevoluteJointFlag::Enum flag, bool value) @@ -178,30 +141,8 @@ void RevoluteJoint::setRevoluteJointFlag(PxRevoluteJointFlag::Enum flag, bool va else data().jointFlags &= ~flag; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, revoluteJointFlags, static_cast(*this), getRevoluteJointFlags()) -#endif -} - -static void RevoluteJointProject(const void* constantBlock, PxTransform& bodyAToWorld, PxTransform& bodyBToWorld, bool projectToA) -{ - const RevoluteJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w, cB2cA, projected; - joint::computeDerived(data, bodyAToWorld, bodyBToWorld, cA2w, cB2w, cB2cA, false); - - bool linearTrunc, angularTrunc; - projected.p = joint::truncateLinear(cB2cA.p, data.projectionLinearTolerance, linearTrunc); - - PxQuat swing, twist, projSwing; - PxSeparateSwingTwist(cB2cA.q, swing, twist); - projSwing = joint::truncateAngular(swing, PxSin(data.projectionAngularTolerance/2), PxCos(data.projectionAngularTolerance/2), angularTrunc); - - if(linearTrunc || angularTrunc) - { - projected.q = projSwing * twist; - joint::projectTransforms(bodyAToWorld, bodyBToWorld, cA2w, cB2w, projected, data, projectToA); - } + OMNI_PVD_SET(PxRevoluteJoint, jointFlags, static_cast(*this), getRevoluteJointFlags()) } static PxQuat computeTwist(const PxTransform& cA2w, const PxTransform& cB2w) @@ -235,21 +176,13 @@ static void RevoluteJointVisualize(PxConstraintVisualizer& viz, const void* cons { const RevoluteJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); if(flags & PxConstraintVisualizationFlag::eLOCAL_FRAMES) viz.visualizeJointFrames(cA2w, cB2w); if((data.jointFlags & PxRevoluteJointFlag::eLIMIT_ENABLED) && (flags & PxConstraintVisualizationFlag::eLIMITS)) - { - const PxReal angle = computePhi(cA2w, cB2w); - const PxReal pad = data.limit.contactDistance_deprecated; - const PxReal low = data.limit.lower; - const PxReal high = data.limit.upper; - - const bool active = isLimitActive(data.limit, pad, angle, low, high); - viz.visualizeAngularLimit(cA2w, data.limit.lower, data.limit.upper, active); - } + viz.visualizeAngularLimit(cA2w, data.limit.lower, data.limit.upper); } //TAG:solverprepshader @@ -265,7 +198,7 @@ static PxU32 RevoluteJointSolverPrep(Px1DConstraint* constraints, { const RevoluteJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); const PxJointAngularLimitPair& limit = data.limit; @@ -275,19 +208,17 @@ static PxU32 RevoluteJointSolverPrep(Px1DConstraint* constraints, // PT: it is a mistake to use the neighborhood operator since it // prevents us from using the quat's double-cover feature. - if(!useExtendedLimits && cB2w.q.dot(cA2w.q)<0.0f) - cB2w.q = -cB2w.q; + if(!useExtendedLimits) + joint::applyNeighborhoodOperator(cA2w, cB2w); - PxVec3 ra, rb; - ch.prepareLockedAxes(cA2w.q, cB2w.q, cA2w.transformInv(cB2w.p), 7, PxU32(limitIsLocked ? 7 : 6), ra, rb); + PxVec3 ra, rb, axis; + ch.prepareLockedAxes(cA2w.q, cB2w.q, cA2w.transformInv(cB2w.p), 7, PxU32(limitIsLocked ? 7 : 6), ra, rb, &axis); cA2wOut = ra + bA2w.p; cB2wOut = rb + bB2w.p; if(limitIsLocked) return ch.getCount(); - const PxVec3 axis = cA2w.q.getBasisVector0(); - if(data.jointFlags & PxRevoluteJointFlag::eDRIVE_ENABLED) { Px1DConstraint* c = ch.getConstraintRow(); @@ -314,7 +245,7 @@ static PxU32 RevoluteJointSolverPrep(Px1DConstraint* constraints, if(limitEnabled) { const PxReal phi = computePhi(cA2w, cB2w); - ch.anglePair(phi, data.limit.lower, data.limit.upper, data.limit.contactDistance_deprecated, axis, limit); + ch.anglePair(phi, data.limit.lower, data.limit.upper, axis, limit); } return ch.getCount(); @@ -322,10 +253,13 @@ static PxU32 RevoluteJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gRevoluteJointShaders = { RevoluteJointSolverPrep, RevoluteJointProject, RevoluteJointVisualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable gRevoluteJointShaders = { RevoluteJointSolverPrep, RevoluteJointVisualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep RevoluteJoint::getPrep() const { return gRevoluteJointShaders.solverPrep; } +// PT: for tests / benchmarks +PxConstraintSolverPrep getRevoluteJointPrep() { return gRevoluteJointShaders.solverPrep; } + PxRevoluteJoint* physx::PxRevoluteJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1) { PX_CHECK_AND_RETURN_NULL(localFrame0.isSane(), "PxRevoluteJointCreate: local frame 0 is not a valid transform"); @@ -347,35 +281,33 @@ void RevoluteJoint::resolveReferences(PxDeserializationContext& context) void RevoluteJoint::updateOmniPvdProperties() const { - const PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, revoluteAngle, j, getAngle()) - OMNI_PVD_SET(joint, revoluteVelocity, j, getVelocity()) + const PxRevoluteJoint& j = static_cast(*this); + OMNI_PVD_SET(PxRevoluteJoint, angle, j, getAngle()) + OMNI_PVD_SET(PxRevoluteJoint, velocity, j, getVelocity()) } template<> void physx::Ext::omniPvdInitJoint(RevoluteJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eREVOLUTE) - OMNI_PVD_SET(joint, revoluteProjectionLinearTolerance, j, joint->getProjectionLinearTolerance()) - OMNI_PVD_SET(joint, revoluteProjectionAngularTolerance, j, joint->getProjectionAngularTolerance()) - + PxRevoluteJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxRevoluteJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eREVOLUTE); + PxJointAngularLimitPair limit = joint->getLimit(); - OMNI_PVD_SET(joint, revoluteLimitLower, j, limit.lower) - OMNI_PVD_SET(joint, revoluteLimitUpper, j, limit.upper) - OMNI_PVD_SET(joint, revoluteLimitRestitution, j, limit.restitution) - OMNI_PVD_SET(joint, revoluteLimitBounceThreshold, j, limit.bounceThreshold) - OMNI_PVD_SET(joint, revoluteLimitStiffness, j, limit.stiffness) - OMNI_PVD_SET(joint, revoluteLimitDamping, j, limit.damping) - OMNI_PVD_SET(joint, revoluteLimitContactDistance, j, limit.contactDistance_deprecated) - - OMNI_PVD_SET(joint, revoluteDriveVelocity, j, joint->getDriveVelocity()) - OMNI_PVD_SET(joint, revoluteDriveForceLimit, j, joint->getDriveForceLimit()) - OMNI_PVD_SET(joint, revoluteDriveGearRatio, j, joint->getDriveGearRatio()) - OMNI_PVD_SET(joint, revoluteJointFlags, j, joint->getRevoluteJointFlags()) - - OMNI_PVD_SET(joint, revoluteAngle, j, joint->getAngle()) - OMNI_PVD_SET(joint, revoluteVelocity, j, joint->getVelocity()) + OMNI_PVD_SET(PxRevoluteJoint, limitLower, j, limit.lower) + OMNI_PVD_SET(PxRevoluteJoint, limitUpper, j, limit.upper) + OMNI_PVD_SET(PxRevoluteJoint, limitRestitution, j, limit.restitution) + OMNI_PVD_SET(PxRevoluteJoint, limitBounceThreshold, j, limit.bounceThreshold) + OMNI_PVD_SET(PxRevoluteJoint, limitStiffness, j, limit.stiffness) + OMNI_PVD_SET(PxRevoluteJoint, limitDamping, j, limit.damping) + + OMNI_PVD_SET(PxRevoluteJoint, driveVelocity, j, joint->getDriveVelocity()) + OMNI_PVD_SET(PxRevoluteJoint, driveForceLimit, j, joint->getDriveForceLimit()) + OMNI_PVD_SET(PxRevoluteJoint, driveGearRatio, j, joint->getDriveGearRatio()) + OMNI_PVD_SET(PxRevoluteJoint, jointFlags, j, joint->getRevoluteJointFlags()) + + OMNI_PVD_SET(PxRevoluteJoint, angle, j, joint->getAngle()) + OMNI_PVD_SET(PxRevoluteJoint, velocity, j, joint->getVelocity()) } #endif diff --git a/physx/source/physxextensions/src/ExtRevoluteJoint.h b/physx/source/physxextensions/src/ExtRevoluteJoint.h index 1b46bf708..fb3d035ea 100644 --- a/physx/source/physxextensions/src/ExtRevoluteJoint.h +++ b/physx/source/physxextensions/src/ExtRevoluteJoint.h @@ -43,24 +43,14 @@ namespace Ext { struct RevoluteJointData : public JointData { - //= 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. - //================================================================================================== - PxReal driveVelocity; PxReal driveForceLimit; PxReal driveGearRatio; PxJointAngularLimitPair limit; - PxReal projectionLinearTolerance; - PxReal projectionAngularTolerance; - PxRevoluteJointFlags jointFlags; - private: +// private: // PT: must be public for a benchmark RevoluteJointData(const PxJointAngularLimitPair& pair) : limit(pair) {} }; @@ -68,12 +58,6 @@ namespace Ext class RevoluteJoint : public RevoluteJointT { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION RevoluteJoint(PxBaseFlags baseFlags) : RevoluteJointT(baseFlags) {} @@ -96,10 +80,6 @@ namespace Ext virtual void setRevoluteJointFlags(PxRevoluteJointFlags flags) PX_OVERRIDE; virtual void setRevoluteJointFlag(PxRevoluteJointFlag::Enum flag, bool value) PX_OVERRIDE; virtual PxRevoluteJointFlags getRevoluteJointFlags() const PX_OVERRIDE; - virtual void setProjectionLinearTolerance(PxReal distance) PX_OVERRIDE; - virtual PxReal getProjectionLinearTolerance() const PX_OVERRIDE; - virtual void setProjectionAngularTolerance(PxReal tolerance) PX_OVERRIDE; - virtual PxReal getProjectionAngularTolerance() const PX_OVERRIDE; //~PxRevoluteJoint // PxConstraintConnector diff --git a/physx/source/physxextensions/src/ExtRigidBodyExt.cpp b/physx/source/physxextensions/src/ExtRigidBodyExt.cpp index c37d383a8..6e8c9c824 100644 --- a/physx/source/physxextensions/src/ExtRigidBodyExt.cpp +++ b/physx/source/physxextensions/src/ExtRigidBodyExt.cpp @@ -142,14 +142,12 @@ static bool computeMassAndInertia(Ext::InertiaTensorComputer& inertiaComp, bool Ext::InertiaTensorComputer it(false); - switch(shapes[i]->getGeometryType()) + const PxGeometry& geom = shapes[i]->getGeometry(); + switch(geom.getType()) { case PxGeometryType::eSPHERE : { - PxSphereGeometry g; - bool ok = shapes[i]->getSphereGeometry(g); - PX_ASSERT(ok); - PX_UNUSED(ok); + const PxSphereGeometry& g = static_cast(geom); PxTransform temp(shapes[i]->getLocalPose()); it.setSphere(g.radius, &temp); @@ -158,10 +156,7 @@ static bool computeMassAndInertia(Ext::InertiaTensorComputer& inertiaComp, bool case PxGeometryType::eBOX : { - PxBoxGeometry g; - bool ok = shapes[i]->getBoxGeometry(g); - PX_ASSERT(ok); - PX_UNUSED(ok); + const PxBoxGeometry& g = static_cast(geom); PxTransform temp(shapes[i]->getLocalPose()); it.setBox(g.halfExtents, &temp); @@ -170,10 +165,7 @@ static bool computeMassAndInertia(Ext::InertiaTensorComputer& inertiaComp, bool case PxGeometryType::eCAPSULE : { - PxCapsuleGeometry g; - bool ok = shapes[i]->getCapsuleGeometry(g); - PX_ASSERT(ok); - PX_UNUSED(ok); + const PxCapsuleGeometry& g = static_cast(geom); PxTransform temp(shapes[i]->getLocalPose()); it.setCapsule(0, g.radius, g.halfHeight, &temp); @@ -182,10 +174,7 @@ static bool computeMassAndInertia(Ext::InertiaTensorComputer& inertiaComp, bool case PxGeometryType::eCONVEXMESH : { - PxConvexMeshGeometry g; - bool ok = shapes[i]->getConvexMeshGeometry(g); - PX_ASSERT(ok); - PX_UNUSED(ok); + const PxConvexMeshGeometry& g = static_cast(geom); PxConvexMesh& convMesh = *g.convexMesh; PxReal convMass; @@ -214,10 +203,7 @@ static bool computeMassAndInertia(Ext::InertiaTensorComputer& inertiaComp, bool break; case PxGeometryType::eTRIANGLEMESH: { - PxTriangleMeshGeometry g; - bool ok = shapes[i]->getTriangleMeshGeometry(g); - PX_ASSERT(ok); - PX_UNUSED(ok); + const PxTriangleMeshGeometry& g = static_cast(geom); PxReal mass; PxMat33 inertia; @@ -509,6 +495,7 @@ void PxRigidBodyExt::computeVelocityDeltaFromImpulse(const PxRigidBody& body, co { const PxTransform globalPose = body.getGlobalPose(); const PxTransform cmLocalPose = body.getCMassLocalPose(); + // PT:: tag: scalar transform*transform const PxTransform body2World = globalPose*cmLocalPose; const PxMat33Padded M(body2World.q); diff --git a/physx/source/physxextensions/src/ExtSimpleFactory.cpp b/physx/source/physxextensions/src/ExtSimpleFactory.cpp index 6743e66d5..c8748f780 100644 --- a/physx/source/physxextensions/src/ExtSimpleFactory.cpp +++ b/physx/source/physxextensions/src/ExtSimpleFactory.cpp @@ -104,7 +104,7 @@ PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, { PX_CHECK_AND_RETURN_NULL(transform.isValid(), "PxCreateKinematic: transform is not valid."); - bool isDynGeom = isDynamicGeometry(shape.getGeometryType()); + bool isDynGeom = isDynamicGeometry(shape.getGeometry().getType()); if(isDynGeom && density <= 0.0f) return NULL; diff --git a/physx/source/physxextensions/src/ExtSoftBodyExt.cpp b/physx/source/physxextensions/src/ExtSoftBodyExt.cpp index 713ee0d76..f8b96c0c0 100644 --- a/physx/source/physxextensions/src/ExtSoftBodyExt.cpp +++ b/physx/source/physxextensions/src/ExtSoftBodyExt.cpp @@ -30,16 +30,17 @@ #include "extensions/PxTetMakerExt.h" #include "GuTetrahedronMesh.h" -#include "PxBuffer.h" #include "cooking/PxCooking.h" #include "PxPhysics.h" #include "extensions/PxRemeshingExt.h" +#include "cudamanager/PxCudaContextManager.h" +#include "cudamanager/PxCudaContext.h" using namespace physx; using namespace Cm; //Computes the volume of the simulation mesh defined as the sum of the volumes of all tetrahedra -static PxReal computeSimulationMeshVolume(PxSoftBody& sb) +static PxReal computeSimulationMeshVolume(PxSoftBody& sb, PxVec4* simPositions) { const PxU32 numTetsGM = sb.getSimulationMesh()->getNbTetrahedrons(); @@ -47,15 +48,13 @@ static PxReal computeSimulationMeshVolume(PxSoftBody& sb) const PxU16* tetPtr16 = reinterpret_cast(sb.getSimulationMesh()->getTetrahedrons()); const bool sixteenBit = sb.getSimulationMesh()->getTetrahedronMeshFlags() & PxTetrahedronMeshFlag::e16_BIT_INDICES; - PxVec4* positionInvGM = reinterpret_cast(sb.getSimPositionInvMassCPU()->map()); - PxReal volume = 0; for (PxU32 i = 0; i < numTetsGM; ++i) { - PxVec4& x0 = positionInvGM[sixteenBit ? tetPtr16[4 * i] : tetPtr32[4 * i]]; - PxVec4& x1 = positionInvGM[sixteenBit ? tetPtr16[4 * i + 1] : tetPtr32[4 * i + 1]]; - PxVec4& x2 = positionInvGM[sixteenBit ? tetPtr16[4 * i + 2] : tetPtr32[4 * i + 2]]; - PxVec4& x3 = positionInvGM[sixteenBit ? tetPtr16[4 * i + 3] : tetPtr32[4 * i + 3]]; + PxVec4& x0 = simPositions[sixteenBit ? tetPtr16[4 * i] : tetPtr32[4 * i]]; + PxVec4& x1 = simPositions[sixteenBit ? tetPtr16[4 * i + 1] : tetPtr32[4 * i + 1]]; + PxVec4& x2 = simPositions[sixteenBit ? tetPtr16[4 * i + 2] : tetPtr32[4 * i + 2]]; + PxVec4& x3 = simPositions[sixteenBit ? tetPtr16[4 * i + 3] : tetPtr32[4 * i + 3]]; const PxVec3 u1 = x1.getXYZ() - x0.getXYZ(); const PxVec3 u2 = x2.getXYZ() - x0.getXYZ(); @@ -68,14 +67,12 @@ static PxReal computeSimulationMeshVolume(PxSoftBody& sb) } volume /= 6.0f; - sb.getSimPositionInvMassCPU()->unmap(); - return volume; } //Recomputes the volume associated with a vertex. Every tetrahedron distributes a quarter of its volume to //each vertex it is connected to. Finally the volume stored for every vertex is inverted. -static void updateNodeInverseVolumes(PxSoftBody& sb) +static void updateNodeInverseVolumes(PxSoftBody& sb, PxVec4* simPositions) { const PxU32 numVertsGM = sb.getSimulationMesh()->getNbVertices(); const PxU32 numTetsGM = sb.getSimulationMesh()->getNbTetrahedrons(); @@ -84,17 +81,15 @@ static void updateNodeInverseVolumes(PxSoftBody& sb) const PxU16* tetPtr16 = reinterpret_cast(sb.getSimulationMesh()->getTetrahedrons()); const bool sixteenBit = sb.getSimulationMesh()->getTetrahedronMeshFlags() & PxTetrahedronMeshFlag::e16_BIT_INDICES; - PxVec4* positionInvGM = reinterpret_cast(sb.getSimPositionInvMassCPU()->map()); - for (PxU32 i = 0; i < numVertsGM; ++i) - positionInvGM[i].w = 0.0f; + simPositions[i].w = 0.0f; for (PxU32 i = 0; i < numTetsGM; ++i) { - PxVec4& x0 = positionInvGM[sixteenBit ? tetPtr16[4 * i] : tetPtr32[4 * i]]; - PxVec4& x1 = positionInvGM[sixteenBit ? tetPtr16[4 * i + 1] : tetPtr32[4 * i + 1]]; - PxVec4& x2 = positionInvGM[sixteenBit ? tetPtr16[4 * i + 2] : tetPtr32[4 * i + 2]]; - PxVec4& x3 = positionInvGM[sixteenBit ? tetPtr16[4 * i + 3] : tetPtr32[4 * i + 3]]; + PxVec4& x0 = simPositions[sixteenBit ? tetPtr16[4 * i] : tetPtr32[4 * i]]; + PxVec4& x1 = simPositions[sixteenBit ? tetPtr16[4 * i + 1] : tetPtr32[4 * i + 1]]; + PxVec4& x2 = simPositions[sixteenBit ? tetPtr16[4 * i + 2] : tetPtr32[4 * i + 2]]; + PxVec4& x3 = simPositions[sixteenBit ? tetPtr16[4 * i + 3] : tetPtr32[4 * i + 3]]; const PxVec3 u1 = x1.getXYZ() - x0.getXYZ(); const PxVec3 u2 = x2.getXYZ() - x0.getXYZ(); @@ -105,9 +100,9 @@ static void updateNodeInverseVolumes(PxSoftBody& sb) //det should be positive const PxReal det = Q.getDeterminant(); - if (det <= 1.e-9f) - PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "updateNodeInverseVolumes(): tretrahedron is degenerate or inverted"); - + if (det <= 1.e-9f) + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "updateNodeInverseVolumes(): tetrahedron is degenerate or inverted"); + //Distribute one quarter of the volume to each vertex the tetrahedron is connected to const PxReal volume = det / 6.0f; x0.w += 0.25f * volume; @@ -117,42 +112,31 @@ static void updateNodeInverseVolumes(PxSoftBody& sb) } //Invert the volumes stored per vertex and copy it to the velocity buffer - PxVec4* velocityInvGM = reinterpret_cast(sb.getSimVelocityInvMassCPU()->map()); for (PxU32 i = 0; i < numVertsGM; ++i) { - if (positionInvGM[i].w > 0) + if (simPositions[i].w > 0) { - positionInvGM[i].w = 1.0f / positionInvGM[i].w; + simPositions[i].w = 1.0f / simPositions[i].w; } - velocityInvGM[i].w = positionInvGM[i].w; } - - sb.getSimPositionInvMassCPU()->unmap(); - sb.getSimVelocityInvMassCPU()->unmap(); } -void PxSoftBodyExt::updateMass(PxSoftBody& sb, const PxReal density, const PxReal maxInvMassRatio) +void PxSoftBodyExt::updateMass(PxSoftBody& sb, const PxReal density, const PxReal maxInvMassRatio, PxVec4* simPositionsPinned) { //Inverse volumes are recomputed to ensure that multiple subsequent calls of this method lead to correct results - updateNodeInverseVolumes(sb); + updateNodeInverseVolumes(sb, simPositionsPinned); const PxU32 numVertsGM = sb.getSimulationMesh()->getNbVertices(); - PxVec4* positionInvGM = reinterpret_cast(sb.getSimPositionInvMassCPU()->map()); - PxVec4* velocityInvGM = reinterpret_cast(sb.getSimVelocityInvMassCPU()->map()); - PxReal minInvMass = PX_MAX_F32, maxInvMass = 0.f; for (PxU32 i = 0; i < numVertsGM; ++i) { - const PxVec4& vert = positionInvGM[i]; + const PxVec4& vert = simPositionsPinned[i]; PxReal invMass = vert.w; invMass = invMass / (density); minInvMass = invMass > 0.f ? PxMin(invMass, minInvMass) : minInvMass; maxInvMass = PxMax(invMass, maxInvMass); - positionInvGM[i] = PxVec4(vert.x, vert.y, vert.z, invMass); - - const PxVec4& vel = velocityInvGM[i]; - velocityInvGM[i] = PxVec4(vel.x, vel.y, vel.z, invMass); + simPositionsPinned[i] = PxVec4(vert.x, vert.y, vert.z, invMass); } if (minInvMass != PX_MAX_F32) { @@ -163,66 +147,51 @@ void PxSoftBodyExt::updateMass(PxSoftBody& sb, const PxReal density, const PxRea maxInvMass = minInvMass * maxInvMassRatio; for (PxU32 i = 0; i < numVertsGM; ++i) { - PxVec4& posInvMass = positionInvGM[i]; - PxVec4& velInvMass = velocityInvGM[i]; + PxVec4& posInvMass = simPositionsPinned[i]; posInvMass.w = PxMin(posInvMass.w, maxInvMass); - velInvMass.w = PxMin(velInvMass.w, maxInvMass); } } } - - sb.getSimPositionInvMassCPU()->unmap(); - sb.getSimVelocityInvMassCPU()->unmap(); } -void PxSoftBodyExt::setMass(PxSoftBody& sb, const PxReal mass, const PxReal maxInvMassRatio) +void PxSoftBodyExt::setMass(PxSoftBody& sb, const PxReal mass, const PxReal maxInvMassRatio, PxVec4* simPositionsPinned) { //Compute the density such that density times volume is equal to the desired mass - updateMass(sb, mass / computeSimulationMeshVolume(sb), maxInvMassRatio); + updateMass(sb, mass / computeSimulationMeshVolume(sb, simPositionsPinned), maxInvMassRatio, simPositionsPinned); } -void PxSoftBodyExt::transform(PxSoftBody& sb, const PxTransform& transform, const PxReal scale) +void PxSoftBodyExt::transform(PxSoftBody& sb, const PxTransform& transform, const PxReal scale, PxVec4* simPositionsPinned, PxVec4* simVelocitiesPinned, PxVec4* collPositionsPinned, PxVec4* restPositionsPinned) { const PxU32 numVertsGM = sb.getSimulationMesh()->getNbVertices(); const PxU32 numVerts = sb.getCollisionMesh()->getNbVertices(); - PxVec4* collPositionInvGM = reinterpret_cast(sb.getPositionInvMassCPU()->map()); - PxVec4* positionInvGM = reinterpret_cast(sb.getSimPositionInvMassCPU()->map()); - PxVec4* velocityInvGM = reinterpret_cast(sb.getSimVelocityInvMassCPU()->map()); - PxVec4* restPositions = reinterpret_cast(sb.getRestPositionInvMassCPU()->map()); - for (PxU32 i = 0; i < numVertsGM; ++i) { - const PxVec4 tpInvMass = positionInvGM[i]; + const PxVec4 tpInvMass = simPositionsPinned[i]; const PxReal invMass = tpInvMass.w; PxVec3 vert = PxVec3(tpInvMass.x * scale, tpInvMass.y * scale, tpInvMass.z * scale); //Transform the vertex position and keep the inverse mass vert = transform.transform(vert); - positionInvGM[i] = PxVec4(vert.x, vert.y, vert.z, invMass); + simPositionsPinned[i] = PxVec4(vert.x, vert.y, vert.z, invMass); - PxVec4 vel = velocityInvGM[i]; + PxVec4 vel = simVelocitiesPinned[i]; PxVec3 v = PxVec3(vel.x * scale, vel.y * scale, vel.z * scale); //Velocities are translation invariant, therefore only the direction needs to get adjusted. //The inverse mass is stored as well to optimize memory access on the GPU v = transform.rotate(v); - velocityInvGM[i] = PxVec4(v.x, v.y, v.z, invMass); + simVelocitiesPinned[i] = PxVec4(v.x, v.y, v.z, invMass); } for (PxU32 i = 0; i < numVerts; ++i) { - restPositions[i] = PxVec4(restPositions[i].x*scale, restPositions[i].y*scale, restPositions[i].z*scale, 1.f); + restPositionsPinned[i] = PxVec4(restPositionsPinned[i].x*scale, restPositionsPinned[i].y*scale, restPositionsPinned[i].z*scale, 1.f); - const PxVec4 tpInvMass = collPositionInvGM[i]; + const PxVec4 tpInvMass = collPositionsPinned[i]; PxVec3 vert = PxVec3(tpInvMass.x * scale, tpInvMass.y * scale, tpInvMass.z * scale); vert = transform.transform(vert); - collPositionInvGM[i] = PxVec4(vert.x, vert.y, vert.z, tpInvMass.w); + collPositionsPinned[i] = PxVec4(vert.x, vert.y, vert.z, tpInvMass.w); } - sb.getSimPositionInvMassCPU()->unmap(); - sb.getSimVelocityInvMassCPU()->unmap(); - sb.getRestPositionInvMassCPU()->unmap(); - sb.getPositionInvMassCPU()->unmap(); - PxMat33* tetraRestPosesGM = static_cast(sb.getSoftBodyAuxData())->getGridModelRestPosesFast(); // reinterpret_cast(simMeshData->softBodyAuxData.getGridModelRestPosesFast()); const PxU32 nbTetraGM = sb.getSimulationMesh()->getNbTetrahedrons(); @@ -269,7 +238,7 @@ void PxSoftBodyExt::transform(PxSoftBody& sb, const PxTransform& transform, cons } -void PxSoftBodyExt::updateEmbeddedCollisionMesh(PxSoftBody& sb) +void PxSoftBodyExt::updateEmbeddedCollisionMesh(PxSoftBody& sb, PxVec4* simPositionsPinned, PxVec4* collPositionsPinned) { Gu::SoftBodyAuxData* softBodyAuxData = static_cast(sb.getSoftBodyAuxData()); const PxU32* remapTable = softBodyAuxData->mVertsRemapInGridModel; @@ -282,47 +251,61 @@ void PxSoftBodyExt::updateEmbeddedCollisionMesh(PxSoftBody& sb) bool sixteenBit = simMesh->getTetrahedronMeshFlags() & PxTetrahedronMeshFlag::e16_BIT_INDICES; - PxVec4* positionInvGM = reinterpret_cast(sb.getSimPositionInvMassCPU()->map()); - PxVec4* positionInv = reinterpret_cast(sb.getPositionInvMassCPU()->map()); - const PxU32 numVerts = sb.getCollisionMesh()->getNbVertices(); for (PxU32 i = 0; i < numVerts; ++i) { //The tetrahedra are ordered differently on the GPU, therefore the index must be taken from the remap table const PxU32 tetrahedronIdx = remapTable[i]; - const PxVec4 p0 = positionInvGM[sixteenBit ? tets16[4 * tetrahedronIdx] : tets32[4 * tetrahedronIdx]]; - const PxVec4 p1 = positionInvGM[sixteenBit ? tets16[4 * tetrahedronIdx + 1] : tets32[4 * tetrahedronIdx + 1]]; - const PxVec4 p2 = positionInvGM[sixteenBit ? tets16[4 * tetrahedronIdx + 2] : tets32[4 * tetrahedronIdx + 2]]; - const PxVec4 p3 = positionInvGM[sixteenBit ? tets16[4 * tetrahedronIdx + 3] : tets32[4 * tetrahedronIdx + 3]]; + const PxVec4 p0 = simPositionsPinned[sixteenBit ? tets16[4 * tetrahedronIdx] : tets32[4 * tetrahedronIdx]]; + const PxVec4 p1 = simPositionsPinned[sixteenBit ? tets16[4 * tetrahedronIdx + 1] : tets32[4 * tetrahedronIdx + 1]]; + const PxVec4 p2 = simPositionsPinned[sixteenBit ? tets16[4 * tetrahedronIdx + 2] : tets32[4 * tetrahedronIdx + 2]]; + const PxVec4 p3 = simPositionsPinned[sixteenBit ? tets16[4 * tetrahedronIdx + 3] : tets32[4 * tetrahedronIdx + 3]]; const PxReal* barycentric = &barycentricCoordinates[4*i]; //Compute the embedded position as a weigted sum of vertices from the simulation mesh //This ensures that all tranformations and scale changes applied to the simulation mesh get transferred //to the collision mesh - positionInv[i] = p0 * barycentric[0] + p1 * barycentric[1] + p2 * barycentric[2] + p3 * barycentric[3]; - positionInv[i].w = 1.0f; + collPositionsPinned[i] = p0 * barycentric[0] + p1 * barycentric[1] + p2 * barycentric[2] + p3 * barycentric[3]; + collPositionsPinned[i].w = 1.0f; } +} - sb.getSimPositionInvMassCPU()->unmap(); - sb.getPositionInvMassCPU()->unmap(); +void PxSoftBodyExt::commit(PxSoftBody& sb, PxSoftBodyDataFlags flags, PxVec4* simPositionsPinned, PxVec4* simVelocitiesPinned, PxVec4* collPositionsPinned, PxVec4* restPositionsPinned, CUstream stream) +{ + copyToDevice(sb, flags, simPositionsPinned, simVelocitiesPinned, collPositionsPinned, restPositionsPinned, stream); } -void PxSoftBodyExt::commit(PxSoftBody& sb, PxSoftBodyDataFlags flags, bool flush) +void PxSoftBodyExt::copyToDevice(PxSoftBody& sb, PxSoftBodyDataFlags flags, PxVec4* simPositionsPinned, PxVec4* simVelocitiesPinned, PxVec4* collPositionsPinned, PxVec4* restPositionsPinned, CUstream stream) { //Updating the collision mesh's vertices ensures that simulation mesh and collision mesh are //represented in the same coordinate system and the same scale - updateEmbeddedCollisionMesh(sb); + updateEmbeddedCollisionMesh(sb, simPositionsPinned, collPositionsPinned); + +#if PX_SUPPORT_GPU_PHYSX + PxScopedCudaLock _lock(*sb.getCudaContextManager()); + PxCudaContext* ctx = sb.getCudaContextManager()->getCudaContext(); - //Schedule data uploads for all buffers specified - if (flags & PxSoftBodyData::eSIM_POSITION_INVMASS) - sb.writeData(PxSoftBodyData::eSIM_POSITION_INVMASS, *sb.getSimPositionInvMassCPU(), flush); + if (flags & PxSoftBodyDataFlag::ePOSITION_INVMASS && collPositionsPinned) + ctx->memcpyHtoDAsync(reinterpret_cast(sb.getPositionInvMassBufferD()), collPositionsPinned, sb.getCollisionMesh()->getNbVertices() * sizeof(PxVec4), stream); - if (flags & PxSoftBodyData::eSIM_VELOCITY) - sb.writeData(PxSoftBodyData::eSIM_VELOCITY, *sb.getSimVelocityInvMassCPU(), flush); + if (flags & PxSoftBodyDataFlag::eREST_POSITION_INVMASS && restPositionsPinned) + ctx->memcpyHtoDAsync(reinterpret_cast(sb.getRestPositionBufferD()), restPositionsPinned, sb.getCollisionMesh()->getNbVertices() * sizeof(PxVec4), stream); - if (flags & PxSoftBodyData::eSIM_KINEMATIC_TARGET) - sb.writeData(PxSoftBodyData::eSIM_KINEMATIC_TARGET, *sb.getKinematicTargetCPU(), flush); + if (flags & PxSoftBodyDataFlag::eSIM_POSITION_INVMASS && simPositionsPinned) + ctx->memcpyHtoDAsync(reinterpret_cast(sb.getSimPositionInvMassBufferD()), simPositionsPinned, sb.getSimulationMesh()->getNbVertices() * sizeof(PxVec4), stream); + + if (flags & PxSoftBodyDataFlag::eSIM_VELOCITY && simVelocitiesPinned) + ctx->memcpyHtoDAsync(reinterpret_cast(sb.getSimVelocityBufferD()), simVelocitiesPinned, sb.getSimulationMesh()->getNbVertices() * sizeof(PxVec4), stream); + + sb.markDirty(flags); + + // we need to synchronize if the stream is the default argument. + if (stream == 0) + { + ctx->streamSynchronize(stream); + } +#endif } PxSoftBodyMesh* PxSoftBodyExt::createSoftBodyMesh(const PxCookingParams& params, const PxSimpleTriangleMesh& surfaceMesh, PxU32 numVoxelsAlongLongestAABBAxis, PxInsertionCallback& insertionCallback, const bool validate) @@ -373,6 +356,7 @@ PxSoftBody* PxSoftBodyExt::createSoftBodyFromMesh(PxSoftBodyMesh* softBodyMesh, { PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE; + PxTetrahedronMeshGeometry geometry(softBodyMesh->getCollisionMesh()); PxFEMSoftBodyMaterial* materialPointer = const_cast(&material); PxShape* shape = PxGetPhysics().createShape(geometry, &materialPointer, 1, true, shapeFlags); @@ -380,17 +364,31 @@ PxSoftBody* PxSoftBodyExt::createSoftBodyFromMesh(PxSoftBodyMesh* softBodyMesh, { softBody->attachShape(*shape); } - softBody->attachSimulationMesh(*softBodyMesh->getSimulationMesh(), *softBodyMesh->getSoftBodyAuxData()); + softBody->attachSimulationMesh(*softBodyMesh->getSimulationMesh(), *softBodyMesh->getSoftBodyAuxData()); + + PxVec4* simPositionInvMassPinned; + PxVec4* simVelocityPinned; + PxVec4* collPositionInvMassPinned; + PxVec4* restPositionPinned; + PxSoftBodyExt::allocateAndInitializeHostMirror(*softBody, &cudaContextManager, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); const PxReal maxInvMassRatio = 50.f; softBody->setParameter(femParams); softBody->setSolverIterationCounts(solverIterationCount); - PxSoftBodyExt::transform(*softBody, transform, scale); - PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio); - PxSoftBodyExt::commit(*softBody, PxSoftBodyData::eALL); + PxSoftBodyExt::transform(*softBody, transform, scale, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + PxSoftBodyExt::updateMass(*softBody, density, maxInvMassRatio, simPositionInvMassPinned); + PxSoftBodyExt::copyToDevice(*softBody, PxSoftBodyDataFlag::eALL, simPositionInvMassPinned, simVelocityPinned, collPositionInvMassPinned, restPositionPinned); + + PxCudaContextManager* mgr = &cudaContextManager; +#if PX_SUPPORT_GPU_PHYSX + PX_PINNED_HOST_FREE(mgr, simPositionInvMassPinned); + PX_PINNED_HOST_FREE(mgr, simVelocityPinned); + PX_PINNED_HOST_FREE(mgr, collPositionInvMassPinned); + PX_PINNED_HOST_FREE(mgr, restPositionPinned) +#endif } return softBody; } @@ -447,3 +445,179 @@ PxSoftBody* PxSoftBodyExt::createSoftBodyBox(const PxTransform& transform, const return createSoftBodyFromMesh(softBodyMesh, transform, material, cudaContextManager, density, solverIterationCount, femParams, scale); } + +void PxSoftBodyExt::allocateAndInitializeHostMirror(PxSoftBody& softBody, PxCudaContextManager* cudaContextManager, PxVec4*& simPositionInvMassPinned, PxVec4*& simVelocityPinned, PxVec4*& collPositionInvMassPinned, PxVec4*& restPositionPinned) +{ + PX_ASSERT(softBody.getCollisionMesh() != NULL); + PX_ASSERT(softBody.getSimulationMesh() != NULL); + + PxU32 nbCollVerts = softBody.getCollisionMesh()->getNbVertices(); + PxU32 nbSimVerts = softBody.getSimulationMesh()->getNbVertices(); + +#if PX_SUPPORT_GPU_PHYSX + simPositionInvMassPinned = PX_PINNED_HOST_ALLOC_T(PxVec4, cudaContextManager, nbSimVerts); + simVelocityPinned = PX_PINNED_HOST_ALLOC_T(PxVec4, cudaContextManager, nbSimVerts); + collPositionInvMassPinned = PX_PINNED_HOST_ALLOC_T(PxVec4, cudaContextManager, nbCollVerts); + restPositionPinned = PX_PINNED_HOST_ALLOC_T(PxVec4, cudaContextManager, nbCollVerts); +#endif + + // write positionInvMass into CPU part. + const PxVec3* positions = softBody.getCollisionMesh()->getVertices(); + + for (PxU32 i = 0; i < nbCollVerts; ++i) + { + PxVec3 vert = positions[i]; + collPositionInvMassPinned[i] = PxVec4(vert, 1.f); + restPositionPinned[i] = PxVec4(vert, 1.f); + } + + // write sim mesh part. + PxSoftBodyAuxData* s = softBody.getSoftBodyAuxData(); + PxReal* invMassGM = s->getGridModelInvMass(); + + const PxVec3* simPositions = softBody.getSimulationMesh()->getVertices(); + for (PxU32 i = 0; i < nbSimVerts; ++i) + { + PxReal invMass = invMassGM ? invMassGM[i] : 1.f; + simPositionInvMassPinned[i] = PxVec4(simPositions[i], invMass); + simVelocityPinned[i] = PxVec4(0.f, 0.f, 0.f, invMass); + } +} + +struct InternalSoftBodyState +{ + PxVec4* mVertices; + PxArray mInvMasses; + const PxU32* mTetrahedra; + PxArray mInvRestPose; + PxArray mPrevPos; + + InternalSoftBodyState(const PxVec4* verticesOriginal, PxVec4* verticesDeformed, PxU32 nbVertices, const PxU32* tetrahedra, PxU32 nbTetraheda, const bool* vertexIsFixed) : + mVertices(verticesDeformed), mTetrahedra(tetrahedra) + { + PxReal density = 1.0f; + + mInvMasses.resize(nbVertices, 0.0f); + mInvRestPose.resize(nbTetraheda, PxMat33(PxZero)); + for (PxU32 i = 0; i < nbTetraheda; i++) + { + const PxU32* t = &mTetrahedra[4 * i]; + const PxVec3 a = verticesOriginal[t[0]].getXYZ(); + PxMat33 ir(verticesOriginal[t[1]].getXYZ() - a, verticesOriginal[t[2]].getXYZ() - a, verticesOriginal[t[3]].getXYZ() - a); + PxReal volume = ir.getDeterminant() / 6.0f; + if (volume > 1e-8f) + mInvRestPose[i] = ir.getInverse(); + + PxReal m = 0.25f * volume * density; + mInvMasses[t[0]] += m; + mInvMasses[t[1]] += m; + mInvMasses[t[2]] += m; + mInvMasses[t[3]] += m; + } + + for (PxU32 i = 0; i < nbVertices; i++) + { + bool fixed = vertexIsFixed ? vertexIsFixed[i] : verticesOriginal[i].w == 0.0f; + if (mInvMasses[i] != 0.0f && !fixed) + mInvMasses[i] = 1.0f / mInvMasses[i]; + else + mInvMasses[i] = 0.0f; + } + + mPrevPos.resize(nbVertices); + for (PxU32 i = 0; i < mPrevPos.size(); ++i) + mPrevPos[i] = mVertices[i].getXYZ(); + } + + void applyDelta() + { + for (PxU32 i = 0; i < mPrevPos.size(); ++i) + { + PxVec3 delta = mVertices[i].getXYZ() - mPrevPos[i]; + mPrevPos[i] = mVertices[i].getXYZ(); + mVertices[i] += PxVec4(0.99f * delta, 0.0f); + } + } + + PX_FORCE_INLINE void applyToElem(PxU32 elemNr, PxReal C, PxReal compliance, const PxVec3& g1, const PxVec3& g2, const PxVec3& g3, const PxVec4& invMasses) + { + if (C == 0.0f) + return; + const PxVec3 g0 = -g1 - g2 - g3; + + const PxU32* t = &mTetrahedra[4 * elemNr]; + const PxReal w = g0.magnitudeSquared() * invMasses.x + g1.magnitudeSquared() * invMasses.y + g2.magnitudeSquared() * invMasses.z + g3.magnitudeSquared() * invMasses.w; + + if (w == 0.0f) + return; + + const PxReal alpha = compliance; + const PxReal dlambda = -C / (w + alpha); + + if (invMasses.x != 0.0f) + mVertices[t[0]] += PxVec4(g0 * dlambda * invMasses.x, 0.0f); + if (invMasses.y != 0.0f) + mVertices[t[1]] += PxVec4(g1 * dlambda * invMasses.y, 0.0f); + if (invMasses.z != 0.0f) + mVertices[t[2]] += PxVec4(g2 * dlambda * invMasses.z, 0.0f); + if (invMasses.w != 0.0f) + mVertices[t[3]] += PxVec4(g3 * dlambda * invMasses.w, 0.0f); + } + + void solveElem(PxU32 elemNr) + { + const PxMat33& ir = mInvRestPose[elemNr]; + if (ir == PxMat33(PxZero)) + return; + + const PxU32* tet = &mTetrahedra[4 * elemNr]; + + PxVec4 invMasses(mInvMasses[tet[0]], mInvMasses[tet[1]], mInvMasses[tet[2]], mInvMasses[tet[3]]); + + PxMat33 P; + P.column0 = mVertices[tet[1]].getXYZ() - mVertices[tet[0]].getXYZ(); + P.column1 = mVertices[tet[2]].getXYZ() - mVertices[tet[0]].getXYZ(); + P.column2 = mVertices[tet[3]].getXYZ() - mVertices[tet[0]].getXYZ(); + + PxMat33 F = P * ir; + + PxVec3 g1 = F.column0 * 2.0f * ir.column0.x + F.column1 * 2.0f * ir.column1.x + F.column2 * 2.0f * ir.column2.x; + PxVec3 g2 = F.column0 * 2.0f * ir.column0.y + F.column1 * 2.0f * ir.column1.y + F.column2 * 2.0f * ir.column2.y; + PxVec3 g3 = F.column0 * 2.0f * ir.column0.z + F.column1 * 2.0f * ir.column1.z + F.column2 * 2.0f * ir.column2.z; + + PxReal C = F.column0.magnitudeSquared() + F.column1.magnitudeSquared() + F.column2.magnitudeSquared() - 3.0f; + + applyToElem(elemNr, C, 0.0f, g1, g2, g3, invMasses); + + P.column0 = mVertices[tet[1]].getXYZ() - mVertices[tet[0]].getXYZ(); + P.column1 = mVertices[tet[2]].getXYZ() - mVertices[tet[0]].getXYZ(); + P.column2 = mVertices[tet[3]].getXYZ() - mVertices[tet[0]].getXYZ(); + + F = P * ir; + + PxMat33& dF = P; //Re-use memory, possible since P is not used anymore afterwards + dF.column0 = F.column1.cross(F.column2); + dF.column1 = F.column2.cross(F.column0); + dF.column2 = F.column0.cross(F.column1); + + g1 = dF.column0 * ir.column0.x + dF.column1 * ir.column1.x + dF.column2 * ir.column2.x; + g2 = dF.column0 * ir.column0.y + dF.column1 * ir.column1.y + dF.column2 * ir.column2.y; + g3 = dF.column0 * ir.column0.z + dF.column1 * ir.column1.z + dF.column2 * ir.column2.z; + + C = F.getDeterminant() - 1.0f; + + applyToElem(elemNr, C, 0.0f, g1, g2, g3, invMasses); + } +}; + +void PxSoftBodyExt::relaxSoftBodyMesh(const PxVec4* verticesOriginal, PxVec4* verticesDeformed, PxU32 nbVertices, const PxU32* tetrahedra, PxU32 nbTetraheda, const bool* vertexIsFixed, PxU32 numIterations) +{ + InternalSoftBodyState state(verticesOriginal, verticesDeformed, nbVertices, tetrahedra, nbTetraheda, vertexIsFixed); + for (PxU32 iter = 0; iter < numIterations; ++iter) + { + state.applyDelta(); + for (PxU32 i = 0; i < nbTetraheda; ++i) + state.solveElem(i); + } + return; +} diff --git a/physx/source/physxextensions/src/ExtSphericalJoint.cpp b/physx/source/physxextensions/src/ExtSphericalJoint.cpp index 13b603223..af8da4c4b 100644 --- a/physx/source/physxextensions/src/ExtSphericalJoint.cpp +++ b/physx/source/physxextensions/src/ExtSphericalJoint.cpp @@ -38,24 +38,8 @@ SphericalJoint::SphericalJoint(const PxTolerancesScale& /*scale*/, PxRigidActor* { SphericalJointData* data = static_cast(mData); - data->projectionLinearTolerance = 1e10f; - data->limit = PxJointLimitCone(PxPi/2, PxPi/2); - data->jointFlags = PxSphericalJointFlags(); -} - -void SphericalJoint::setProjectionLinearTolerance(PxReal tolerance) -{ - PX_CHECK_AND_RETURN(PxIsFinite(tolerance) && tolerance >=0, "PxSphericalJoint::setProjectionLinearTolerance: invalid parameter"); - data().projectionLinearTolerance = tolerance; - markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, sphericalProjectionLinearTolerance, static_cast(*this), tolerance) -#endif -} - -PxReal SphericalJoint::getProjectionLinearTolerance() const -{ - return data().projectionLinearTolerance; + data->limit = PxJointLimitCone(PxPi/2, PxPi/2); + data->jointFlags = PxSphericalJointFlags(); } void SphericalJoint::setLimitCone(const PxJointLimitCone &limit) @@ -64,14 +48,13 @@ void SphericalJoint::setLimitCone(const PxJointLimitCone &limit) data().limit = limit; markDirty(); #if PX_SUPPORT_OMNI_PVD - PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, sphericalLimitYAngle, j, limit.yAngle) - OMNI_PVD_SET(joint, sphericalLimitZAngle, j, limit.zAngle) - OMNI_PVD_SET(joint, sphericalLimitRestitution, j, limit.restitution) - OMNI_PVD_SET(joint, sphericalLimitBounceThreshold, j, limit.bounceThreshold) - OMNI_PVD_SET(joint, sphericalLimitStiffness, j, limit.stiffness) - OMNI_PVD_SET(joint, sphericalLimitDamping, j, limit.damping) - OMNI_PVD_SET(joint, sphericalLimitContactDistance, j, limit.contactDistance_deprecated) + PxSphericalJoint& j = static_cast(*this); + OMNI_PVD_SET(PxSphericalJoint, limitYAngle, j, limit.yAngle) + OMNI_PVD_SET(PxSphericalJoint, limitZAngle, j, limit.zAngle) + OMNI_PVD_SET(PxSphericalJoint, limitRestitution, j, limit.restitution) + OMNI_PVD_SET(PxSphericalJoint, limitBounceThreshold, j, limit.bounceThreshold) + OMNI_PVD_SET(PxSphericalJoint, limitStiffness, j, limit.stiffness) + OMNI_PVD_SET(PxSphericalJoint, limitDamping, j, limit.damping) #endif } @@ -87,10 +70,9 @@ PxSphericalJointFlags SphericalJoint::getSphericalJointFlags(void) const void SphericalJoint::setSphericalJointFlags(PxSphericalJointFlags flags) { - data().jointFlags = flags; -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, sphericalJointFlags, static_cast(*this), flags) -#endif + data().jointFlags = flags; + + OMNI_PVD_SET(PxSphericalJoint, jointFlags, static_cast(*this), flags) } void SphericalJoint::setSphericalJointFlag(PxSphericalJointFlag::Enum flag, bool value) @@ -100,9 +82,8 @@ void SphericalJoint::setSphericalJointFlag(PxSphericalJointFlag::Enum flag, bool else data().jointFlags &= ~flag; markDirty(); -#if PX_SUPPORT_OMNI_PVD - OMNI_PVD_SET(joint, sphericalJointFlags, static_cast(*this), getSphericalJointFlags()) -#endif + + OMNI_PVD_SET(PxSphericalJoint, jointFlags, static_cast(*this), getSphericalJointFlags()) } PxReal SphericalJoint::getSwingYAngle() const @@ -115,46 +96,24 @@ PxReal SphericalJoint::getSwingZAngle() const return getSwingZAngle_Internal(); } -static void SphericalJointProject(const void* constantBlock, PxTransform& bodyAToWorld, PxTransform& bodyBToWorld, bool projectToA) -{ - const SphericalJointData& data = *reinterpret_cast(constantBlock); - - PxTransform cA2w, cB2w, cB2cA, projected; - joint::computeDerived(data, bodyAToWorld, bodyBToWorld, cA2w, cB2w, cB2cA); - - bool linearTrunc; - projected.p = joint::truncateLinear(cB2cA.p, data.projectionLinearTolerance, linearTrunc); - - if(linearTrunc) - { - projected.q = cB2cA.q; - joint::projectTransforms(bodyAToWorld, bodyBToWorld, cA2w, cB2w, projected, data, projectToA); - } -} - static void SphericalJointVisualize(PxConstraintVisualizer& viz, const void* constantBlock, const PxTransform& body0Transform, const PxTransform& body1Transform, PxU32 flags) { const SphericalJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::computeJointFrames(cA2w, cB2w, data, body0Transform, body1Transform); if(flags & PxConstraintVisualizationFlag::eLOCAL_FRAMES) viz.visualizeJointFrames(cA2w, cB2w); if((flags & PxConstraintVisualizationFlag::eLIMITS) && (data.jointFlags & PxSphericalJointFlag::eLIMIT_ENABLED)) { - if(cA2w.q.dot(cB2w.q)<0.0f) - cB2w.q = -cB2w.q; + joint::applyNeighborhoodOperator(cA2w, cB2w); - const PxTransform cB2cA = cA2w.transformInv(cB2w); + const PxTransform cB2cA = cA2w.transformInv(cB2w); PxQuat swing, twist; - PxSeparateSwingTwist(cB2cA.q,swing,twist); + PxSeparateSwingTwist(cB2cA.q, swing, twist); - // PT: TODO: refactor with D6 joint code - const PxReal pad = data.limit.isSoft() ? 0.0f : data.limit.contactDistance_deprecated; - const PxVec3 swingAngle(0.0f, computeSwingAngle(swing.y, swing.w), computeSwingAngle(swing.z, swing.w)); - Cm::ConeLimitHelperTanLess coneHelper(data.limit.yAngle, data.limit.zAngle, pad); - viz.visualizeLimitCone(cA2w, PxTan(data.limit.zAngle/4), PxTan(data.limit.yAngle/4), !coneHelper.contains(swingAngle)); + viz.visualizeLimitCone(cA2w, PxTan(data.limit.zAngle/4), PxTan(data.limit.yAngle/4)); } } @@ -171,11 +130,10 @@ static PxU32 SphericalJointSolverPrep(Px1DConstraint* constraints, { const SphericalJointData& data = *reinterpret_cast(constantBlock); - PxTransform cA2w, cB2w; + PxTransform32 cA2w, cB2w; joint::ConstraintHelper ch(constraints, invMassScale, cA2w, cB2w, body0WorldOffset, data, bA2w, bB2w); - if(cB2w.q.dot(cA2w.q)<0.0f) - cB2w.q = -cB2w.q; + joint::applyNeighborhoodOperator(cA2w, cB2w); if(data.jointFlags & PxSphericalJointFlag::eLIMIT_ENABLED) { @@ -183,14 +141,11 @@ static PxU32 SphericalJointSolverPrep(Px1DConstraint* constraints, PxSeparateSwingTwist(cA2w.q.getConjugate() * cB2w.q, swing, twist); PX_ASSERT(PxAbs(swing.x)<1e-6f); - // PT: TODO: refactor with D6 joint code PxVec3 axis; PxReal error; - const PxReal pad = data.limit.isSoft() ? 0.0f : data.limit.contactDistance_deprecated; - const Cm::ConeLimitHelperTanLess coneHelper(data.limit.yAngle, data.limit.zAngle, pad); - const bool active = coneHelper.getLimit(swing, axis, error); - if(active) - ch.angularLimit(cA2w.rotate(axis), error, data.limit); + const Cm::ConeLimitHelperTanLess coneHelper(data.limit.yAngle, data.limit.zAngle); + coneHelper.getLimit(swing, axis, error); + ch.angularLimit(cA2w.rotate(axis), error, data.limit); } PxVec3 ra, rb; @@ -203,7 +158,7 @@ static PxU32 SphericalJointSolverPrep(Px1DConstraint* constraints, /////////////////////////////////////////////////////////////////////////////// -static PxConstraintShaderTable gSphericalJointShaders = { SphericalJointSolverPrep, SphericalJointProject, SphericalJointVisualize, PxConstraintFlag::Enum(0) }; +static PxConstraintShaderTable gSphericalJointShaders = { SphericalJointSolverPrep, SphericalJointVisualize, PxConstraintFlag::Enum(0) }; PxConstraintSolverPrep SphericalJoint::getPrep() const { return gSphericalJointShaders.solverPrep; } @@ -228,31 +183,30 @@ void SphericalJoint::resolveReferences(PxDeserializationContext& context) void SphericalJoint::updateOmniPvdProperties() const { - const PxJoint& j = static_cast(*this); - OMNI_PVD_SET(joint, sphericalSwingYAngle, j, getSwingYAngle()) - OMNI_PVD_SET(joint, sphericalSwingZAngle, j, getSwingZAngle()) + const PxSphericalJoint& j = static_cast(*this); + OMNI_PVD_SET(PxSphericalJoint, swingYAngle, j, getSwingYAngle()) + OMNI_PVD_SET(PxSphericalJoint, swingZAngle, j, getSwingZAngle()) } template<> void physx::Ext::omniPvdInitJoint(SphericalJoint* joint) { - PxJoint& j = static_cast(*joint); - OMNI_PVD_SET(joint, type, j, PxJointConcreteType::eSPHERICAL) - OMNI_PVD_SET(joint, sphericalProjectionLinearTolerance, j, joint->getProjectionLinearTolerance()) + PxSphericalJoint& j = static_cast(*joint); + OMNI_PVD_CREATE(PxSphericalJoint, j); + omniPvdSetBaseJointParams(static_cast(*joint), PxJointConcreteType::eSPHERICAL); PxJointLimitCone limit = joint->getLimitCone(); - OMNI_PVD_SET(joint, sphericalLimitYAngle, j, limit.yAngle) - OMNI_PVD_SET(joint, sphericalLimitZAngle, j, limit.zAngle) - OMNI_PVD_SET(joint, sphericalLimitRestitution, j, limit.restitution) - OMNI_PVD_SET(joint, sphericalLimitBounceThreshold, j, limit.bounceThreshold) - OMNI_PVD_SET(joint, sphericalLimitStiffness, j, limit.stiffness) - OMNI_PVD_SET(joint, sphericalLimitDamping, j, limit.damping) - OMNI_PVD_SET(joint, sphericalLimitContactDistance, j, limit.contactDistance_deprecated) - - OMNI_PVD_SET(joint, sphericalJointFlags, j, joint->getSphericalJointFlags()) - - OMNI_PVD_SET(joint, sphericalSwingYAngle, j, joint->getSwingYAngle()) - OMNI_PVD_SET(joint, sphericalSwingZAngle, j, joint->getSwingZAngle()) + OMNI_PVD_SET(PxSphericalJoint, limitYAngle, j, limit.yAngle) + OMNI_PVD_SET(PxSphericalJoint, limitZAngle, j, limit.zAngle) + OMNI_PVD_SET(PxSphericalJoint, limitRestitution, j, limit.restitution) + OMNI_PVD_SET(PxSphericalJoint, limitBounceThreshold, j, limit.bounceThreshold) + OMNI_PVD_SET(PxSphericalJoint, limitStiffness, j, limit.stiffness) + OMNI_PVD_SET(PxSphericalJoint, limitDamping, j, limit.damping) + + OMNI_PVD_SET(PxSphericalJoint, jointFlags, j, joint->getSphericalJointFlags()) + + OMNI_PVD_SET(PxSphericalJoint, swingYAngle, j, joint->getSwingYAngle()) + OMNI_PVD_SET(PxSphericalJoint, swingZAngle, j, joint->getSwingZAngle()) } #endif diff --git a/physx/source/physxextensions/src/ExtSphericalJoint.h b/physx/source/physxextensions/src/ExtSphericalJoint.h index 389cd41c8..55bc66ec6 100644 --- a/physx/source/physxextensions/src/ExtSphericalJoint.h +++ b/physx/source/physxextensions/src/ExtSphericalJoint.h @@ -41,16 +41,8 @@ namespace Ext { struct SphericalJointData: public JointData { - //= 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. - //================================================================================================== PxJointLimitCone limit; - PxReal projectionLinearTolerance; - PxSphericalJointFlags jointFlags; private: SphericalJointData(const PxJointLimitCone& cone) : limit(cone) {} @@ -60,12 +52,6 @@ namespace Ext class SphericalJoint : public SphericalJointT { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION SphericalJoint(PxBaseFlags baseFlags) : SphericalJointT(baseFlags) {} @@ -80,8 +66,6 @@ namespace Ext virtual void setSphericalJointFlags(PxSphericalJointFlags flags) PX_OVERRIDE; virtual void setSphericalJointFlag(PxSphericalJointFlag::Enum flag, bool value) PX_OVERRIDE; virtual PxSphericalJointFlags getSphericalJointFlags(void) const PX_OVERRIDE; - virtual void setProjectionLinearTolerance(PxReal distance) PX_OVERRIDE; - virtual PxReal getProjectionLinearTolerance() const PX_OVERRIDE; virtual PxReal getSwingYAngle() const PX_OVERRIDE; virtual PxReal getSwingZAngle() const PX_OVERRIDE; //~PxSphericalJoint diff --git a/physx/source/physxextensions/src/ExtSqQuery.cpp b/physx/source/physxextensions/src/ExtSqQuery.cpp index b383fbf8b..a2e8038fd 100644 --- a/physx/source/physxextensions/src/ExtSqQuery.cpp +++ b/physx/source/physxextensions/src/ExtSqQuery.cpp @@ -187,7 +187,7 @@ template struct ExtGeomQueryAny { static PX_FORCE_INLINE PxU32 geomHit( - const CachedFuncs& funcs, const ExtMultiQueryInput& input, const Gu::ShapeData& sd, + const CachedFuncs& funcs, const ExtMultiQueryInput& input, const Gu::ShapeData* sd, const PxGeometry& sceneGeom, const PxTransform& pose, PxHitFlags hitFlags, PxU32 maxHits, HitType* hits, const PxReal shrunkMaxDistance, const PxBounds3* precomputedBounds, PxQueryThreadContext* context) @@ -221,6 +221,7 @@ struct ExtGeomQueryAny else if(HitTypeSupport::IsSweep) { PX_ASSERT(precomputedBounds != NULL); + PX_ASSERT(sd != NULL); // b0 = query shape bounds // b1 = scene shape bounds // AP: Here we clip the sweep to bounds with sum of extents. This is needed for GJK stability. @@ -278,7 +279,7 @@ struct ExtGeomQueryAny { const bool precise = hitFlags & PxHitFlag::ePRECISE_SWEEP; const SweepCapsuleFunc func = precise ? sf.preciseCapsuleMap[geom1.getType()] : sf.capsuleMap[geom1.getType()]; - retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd.getGuCapsule(), unitDir, distance, sweepHit, hitFlags, inflation, context)); + retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd->getGuCapsule(), unitDir, distance, sweepHit, hitFlags, inflation, context)); } break; @@ -286,7 +287,7 @@ struct ExtGeomQueryAny { const bool precise = hitFlags & PxHitFlag::ePRECISE_SWEEP; const SweepBoxFunc func = precise ? sf.preciseBoxMap[geom1.getType()] : sf.boxMap[geom1.getType()]; - retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd.getGuBox(), unitDir, distance, sweepHit, hitFlags, inflation, context)); + retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd->getGuBox(), unitDir, distance, sweepHit, hitFlags, inflation, context)); } break; @@ -388,6 +389,7 @@ static PX_FORCE_INLINE bool applyAllPreFiltersSQ( static PX_NOINLINE void computeCompoundShapeTransform(PxTransform* PX_RESTRICT transform, const PxTransform* PX_RESTRICT compoundPose, const PxTransform* PX_RESTRICT transforms, PxU32 primIndex) { + // PT:: tag: scalar transform*transform *transform = (*compoundPose) * transforms[primIndex]; } @@ -570,7 +572,7 @@ struct ExtMultiQueryCallback : public PrunerRaycastCallback, public PrunerOverla // call the geometry specific intersection template const PxU32 nbSubHits = ExtGeomQueryAny::geomHit( - mScene.mCachedFuncs, mInput, *mShapeData, shapeGeom, + mScene.mCachedFuncs, mInput, mShapeData, shapeGeom, *shapeTransform, filteredHitFlags | mMeshAnyHitFlags, maxSubHits1, subHits1, mShrunkDistance, mQueryShapeBounds, &mHitCall); @@ -607,7 +609,7 @@ struct ExtMultiQueryCallback : public PrunerRaycastCallback, public PrunerOverla return false; // found a hit for ANY qType, can early exit now } - if(mNoBlock) + if(mNoBlock && hitType==PxQueryHitType::eBLOCK) hitType = PxQueryHitType::eTOUCH; PX_WARN_ONCE_IF(HitTypeSupport::IsOverlap && hitType == PxQueryHitType::eBLOCK, @@ -1211,6 +1213,7 @@ static bool doQueryVsCached(const PrunerHandle handle, PxU32 prunerIndex, const pcb.mShapeData = &sd; // againAfterCache = pcb.invoke(dummyDist, 0); againAfterCache = pcb.template _invoke(dummyDist, 0, payloads, transform, compoundPosePtr); + pcb.mQueryShapeBounds = NULL; pcb.mShapeData = NULL; } else // againAfterCache = pcb.invoke(dummyDist, 0); diff --git a/physx/source/physxextensions/src/ExtTetMakerExt.cpp b/physx/source/physxextensions/src/ExtTetMakerExt.cpp index a2ca89401..574eb3cc4 100644 --- a/physx/source/physxextensions/src/ExtTetMakerExt.cpp +++ b/physx/source/physxextensions/src/ExtTetMakerExt.cpp @@ -125,6 +125,116 @@ void removeUnusedVertices(PxArray<::physx::PxVec3>& vertices, PxArray& te vertices.removeRange(indexer, vertices.size() - indexer); } + +PX_FORCE_INLINE PxU64 buildKey(PxI32 a, PxI32 b) +{ + if (a < b) + return ((PxU64(a)) << 32) | (PxU64(b)); + else + return ((PxU64(b)) << 32) | (PxU64(a)); +} + +static const PxI32 neighborEdgeList[3][2] = { { 0, 1 }, { 0, 2 }, { 1, 2 } }; + +static void buildTriangleNeighborhood(const PxI32* tris, PxU32 numTris, PxArray& result) +{ + PxU32 l = 4 * numTris; //Waste one element in neighborhood info but allow bit shift access instead + result.clear(); + result.resize(l, -1); + + PxHashMap faces; + for (PxU32 i = 0; i < numTris; ++i) + { + const PxI32* tri = &tris[3 * i]; + if (tris[0] < 0) + continue; + + for (PxI32 j = 0; j < 3; ++j) + { + PxU64 key = buildKey(tri[neighborEdgeList[j][0]], tri[neighborEdgeList[j][1]]); + if (const PxPair* ptr = faces.find(key)) + { + if (ptr->second < 0) + { + //PX_ASSERT(false); //Invalid tetmesh since a face is shared by more than 2 tetrahedra + continue; + } + + result[4 * i + j] = ptr->second; + result[ptr->second] = 4 * i + j; + + faces[key] = -1; + } + else + faces.insert(key, 4 * i + j); + } + } +} +void PxTetMaker::detectTriangleIslands(const PxI32* triangles, PxU32 numTriangles, PxArray& islandIndexPerTriangle) +{ + //Detect islands + PxArray neighborhood; + buildTriangleNeighborhood(triangles, numTriangles, neighborhood); + const PxU32 noIslandAssignedMarker = 0xFFFFFFFF; + islandIndexPerTriangle.resize(numTriangles, noIslandAssignedMarker); + PxU32 start = 0; + PxI32 color = -1; + PxArray stack; + while (true) + { + stack.clear(); + while (start < islandIndexPerTriangle.size()) + { + if (islandIndexPerTriangle[start] == noIslandAssignedMarker) + { + stack.pushBack(start); + ++color; + islandIndexPerTriangle[start] = color; + break; + } + ++start; + } + + if (start == islandIndexPerTriangle.size()) + break; + + while (stack.size() > 0) + { + PxI32 id = stack.popBack(); + for (PxI32 i = 0; i < 3; ++i) + { + PxI32 a = neighborhood[4 * id + i]; + PxI32 tetId = a >> 2; + if (tetId >= 0 && islandIndexPerTriangle[tetId] == noIslandAssignedMarker) + { + stack.pushBack(tetId); + islandIndexPerTriangle[tetId] = color; + } + } + } + } +} + +PxU32 PxTetMaker::findLargestIslandId(const PxU32* islandIndexPerTriangle, PxU32 numTriangles) +{ + PxU32 numIslands = 0; + for (PxU32 i = 0; i < numTriangles; ++i) + numIslands = PxMax(numIslands, islandIndexPerTriangle[i]); + ++numIslands; + + PxArray numEntriesPerColor; + numEntriesPerColor.resize(numIslands, 0); + for (PxU32 i = 0; i < numTriangles; ++i) + numEntriesPerColor[islandIndexPerTriangle[i]] += 1; + + PxU32 colorWithHighestTetCount = 0; + for (PxU32 i = 1; i < numEntriesPerColor.size(); ++i) + if (numEntriesPerColor[i] > numEntriesPerColor[colorWithHighestTetCount]) + colorWithHighestTetCount = i; + + return colorWithHighestTetCount; +} + bool PxTetMaker::createConformingTetrahedronMesh(const PxSimpleTriangleMesh& triangleMesh, physx::PxArray& outVertices, physx::PxArray& outTetIndices, const bool validate, PxReal volumeThreshold) { @@ -178,15 +288,50 @@ PxTetrahedronMeshAnalysisResults PxTetMaker::validateTetrahedronMesh(const PxBou void PxTetMaker::simplifyTriangleMesh(const PxArray& inputVertices, const PxArray&inputIndices, int targetTriangleCount, PxF32 maximalEdgeLength, PxArray& outputVertices, PxArray& outputIndices, - PxArray *vertexMap, PxReal edgeLengthCostWeight, PxReal flatnessDetectionThreshold) + PxArray *vertexMap, PxReal edgeLengthCostWeight, PxReal flatnessDetectionThreshold, + bool projectSimplifiedPointsOnInputMeshSurface, PxArray* outputVertexToInputTriangle, bool removeDisconnectedPatches) { Ext::MeshSimplificator ms; - ms.init(inputVertices, inputIndices, edgeLengthCostWeight, flatnessDetectionThreshold); - ms.decimateBySize(targetTriangleCount, maximalEdgeLength); - ms.readBack(outputVertices, outputIndices, vertexMap); + + PxArray indexMapToFullTriangleSet; + if (removeDisconnectedPatches) + { + PxU32 numTriangles = inputIndices.size() / 3; + PxArray islandIndexPerTriangle; + PxTetMaker::detectTriangleIslands(reinterpret_cast(inputIndices.begin()), numTriangles, islandIndexPerTriangle); + + PxU32 biggestIslandIndex = PxTetMaker::findLargestIslandId(islandIndexPerTriangle.begin(), islandIndexPerTriangle.size()); + + PxArray connectedTriangleSet; + for (PxU32 i = 0; i < numTriangles; ++i) + { + if (islandIndexPerTriangle[i] == biggestIslandIndex) + { + for (PxU32 j = 0; j < 3; ++j) + connectedTriangleSet.pushBack(inputIndices[3 * i + j]); + indexMapToFullTriangleSet.pushBack(i); + } + } + + ms.init(inputVertices, connectedTriangleSet, edgeLengthCostWeight, flatnessDetectionThreshold, projectSimplifiedPointsOnInputMeshSurface); + ms.decimateBySize(targetTriangleCount, maximalEdgeLength); + ms.readBack(outputVertices, outputIndices, vertexMap, outputVertexToInputTriangle); + } + else + { + ms.init(inputVertices, inputIndices, edgeLengthCostWeight, flatnessDetectionThreshold, projectSimplifiedPointsOnInputMeshSurface); + ms.decimateBySize(targetTriangleCount, maximalEdgeLength); + ms.readBack(outputVertices, outputIndices, vertexMap, outputVertexToInputTriangle); + } + + if (removeDisconnectedPatches && projectSimplifiedPointsOnInputMeshSurface && outputVertexToInputTriangle) + { + for (PxU32 i = 0; i < outputVertexToInputTriangle->size(); ++i) + (*outputVertexToInputTriangle)[i] = indexMapToFullTriangleSet[(*outputVertexToInputTriangle)[i]]; + } } -void PxTetMaker::remeshTriangleMesh(const PxArray& inputVertices, const PxArray&inputIndices, int gridResolution, +void PxTetMaker::remeshTriangleMesh(const PxArray& inputVertices, const PxArray&inputIndices, PxU32 gridResolution, PxArray& outputVertices, PxArray& outputIndices, PxArray *vertexMap) { Ext::Remesher rm; @@ -194,6 +339,13 @@ void PxTetMaker::remeshTriangleMesh(const PxArray& inputVertices, const rm.readBack(outputVertices, outputIndices); } +void PxTetMaker::remeshTriangleMesh(const PxVec3* inputVertices, PxU32 nbVertices, const PxU32* inputIndices, PxU32 nbIndices, PxU32 gridResolution, + PxArray& outputVertices, PxArray& outputIndices, PxArray *vertexMap) +{ + Ext::Remesher rm; + rm.remesh(inputVertices, nbVertices, inputIndices, nbIndices, gridResolution, vertexMap); + rm.readBack(outputVertices, outputIndices); +} void PxTetMaker::createTreeBasedTetrahedralMesh(const PxArray& inputVertices, const PxArray&inputIndices, bool useTreeNodes, PxArray& outputVertices, PxArray& outputIndices, PxReal volumeThreshold) diff --git a/physx/source/physxextensions/src/ExtTetrahedronMeshExt.cpp b/physx/source/physxextensions/src/ExtTetrahedronMeshExt.cpp index 70ae14560..fe65a6b65 100644 --- a/physx/source/physxextensions/src/ExtTetrahedronMeshExt.cpp +++ b/physx/source/physxextensions/src/ExtTetrahedronMeshExt.cpp @@ -35,6 +35,11 @@ #include "GuBV4_Common.h" #include "GuDistancePointTetrahedron.h" +#include "GuAABBTreeNode.h" +#include "GuAABBTree.h" +#include "GuAABBTreeBounds.h" +#include "GuAABBTreeQuery.h" + namespace physx { struct TetrahedronFinderCallback @@ -195,6 +200,167 @@ namespace physx return callback.mTetId; } + + + class ClosestDistanceToTetmeshTraversalController + { + private: + PxReal mClosestDistanceSquared; + const PxU32* mTetrahedra; + const PxVec3* mPoints; + const Gu::BVHNode* mNodes; + PxVec3 mQueryPoint; + PxVec3 mClosestPoint; + PxI32 mClosestTetId; + + public: + PX_FORCE_INLINE ClosestDistanceToTetmeshTraversalController() {} + + PX_FORCE_INLINE ClosestDistanceToTetmeshTraversalController(const PxU32* tetrahedra, const PxVec3* points, Gu::BVHNode* nodes) : + mTetrahedra(tetrahedra), mPoints(points), mNodes(nodes), mQueryPoint(0.0f), mClosestPoint(0.0f), mClosestTetId(-1) + { + initialize(tetrahedra, points, nodes); + } + + void initialize(const PxU32* tetrahedra, const PxVec3* points, Gu::BVHNode* nodes) + { + mTetrahedra = tetrahedra; + mPoints = points; + mNodes = nodes; + mQueryPoint = PxVec3(0.0f); + mClosestPoint = PxVec3(0.0f); + mClosestTetId = -1; + mClosestDistanceSquared = PX_MAX_F32; + } + + PX_FORCE_INLINE void setQueryPoint(const PxVec3& queryPoint) + { + this->mQueryPoint = queryPoint; + mClosestDistanceSquared = FLT_MAX; + mClosestPoint = PxVec3(0.0f); + mClosestTetId = -1; + } + + PX_FORCE_INLINE const PxVec3& getClosestPoint() const + { + return mClosestPoint; + } + + PX_FORCE_INLINE PxReal distancePointBoxSquared(const PxBounds3& box, const PxVec3& point) + { + PxVec3 closestPt = box.minimum.maximum(box.maximum.minimum(point)); + return (closestPt - point).magnitudeSquared(); + } + + PX_FORCE_INLINE Gu::TraversalControl::Enum analyze(const Gu::BVHNode& node, PxI32) + { + if (distancePointBoxSquared(node.mBV, mQueryPoint) >= mClosestDistanceSquared) + return Gu::TraversalControl::eDontGoDeeper; + + if (node.isLeaf()) + { + const PxI32 j = node.getPrimitiveIndex(); + const PxU32* tet = &mTetrahedra[4 * j]; + + PxVec4 bary; + computeBarycentric(mPoints[tet[0]], mPoints[tet[1]], mPoints[tet[2]], mPoints[tet[3]], mQueryPoint, bary); + + const PxReal tolerance = 0.0f; + if (bary.x >= -tolerance && bary.x <= 1 + tolerance && bary.y >= -tolerance && bary.y <= 1 + tolerance && + bary.z >= -tolerance && bary.z <= 1 + tolerance && bary.w >= -tolerance && bary.w <= 1 + tolerance) + { + mClosestDistanceSquared = 0; + mClosestTetId = j; + mClosestPoint = mQueryPoint; + return Gu::TraversalControl::eAbort; + } + + PxVec3 closest = Gu::closestPtPointTetrahedron(mQueryPoint, mPoints[tet[0]], mPoints[tet[1]], mPoints[tet[2]], mPoints[tet[3]]); + PxReal d2 = (closest - mQueryPoint).magnitudeSquared(); + if (d2 < mClosestDistanceSquared) + { + mClosestDistanceSquared = d2; + mClosestTetId = j; + mClosestPoint = closest; + } + return Gu::TraversalControl::eDontGoDeeper; + } + + const Gu::BVHNode& nodePos = mNodes[node.getPosIndex()]; + const PxReal distSquaredPos = distancePointBoxSquared(nodePos.mBV, mQueryPoint); + const Gu::BVHNode& nodeNeg = mNodes[node.getNegIndex()]; + const PxReal distSquaredNeg = distancePointBoxSquared(nodeNeg.mBV, mQueryPoint); + + if (distSquaredPos < distSquaredNeg) + { + if (distSquaredPos < mClosestDistanceSquared) + return Gu::TraversalControl::eGoDeeper; + } + else + { + if (distSquaredNeg < mClosestDistanceSquared) + return Gu::TraversalControl::eGoDeeperNegFirst; + } + return Gu::TraversalControl::eDontGoDeeper; + } + + PxI32 getClosestTetId() const { return mClosestTetId; } + + void setClosestStart(const PxReal closestDistanceSquared, PxI32 closestTetrahedron, const PxVec3& closestPoint) + { + mClosestDistanceSquared = closestDistanceSquared; + mClosestTetId = closestTetrahedron; + mClosestPoint = closestPoint; + } + + private: + PX_NOCOPY(ClosestDistanceToTetmeshTraversalController) + }; + + static void buildTree(const PxU32* tetrahedra, const PxU32 numTetrahedra, const PxVec3* points, PxArray& tree, PxF32 enlargement = 1e-4f) + { + //Computes a bounding box for every triangle in triangles + Gu::AABBTreeBounds boxes; + boxes.init(numTetrahedra); + for (PxU32 i = 0; i < numTetrahedra; ++i) + { + const PxU32* tri = &tetrahedra[4 * i]; + PxBounds3 box = PxBounds3::empty(); + box.include(points[tri[0]]); + box.include(points[tri[1]]); + box.include(points[tri[2]]); + box.include(points[tri[3]]); + box.fattenFast(enlargement); + boxes.getBounds()[i] = box; + } + + Gu::buildAABBTree(numTetrahedra, boxes, tree); + } + + void PxTetrahedronMeshExt::createPointsToTetrahedronMap(const PxArray& tetMeshVertices, const PxArray& tetMeshIndices, + const PxArray& pointsToEmbed, PxArray& barycentricCoordinates, PxArray& tetLinks) + { + PxArray tree; + buildTree(tetMeshIndices.begin(), tetMeshIndices.size() / 4, tetMeshVertices.begin(), tree); + + ClosestDistanceToTetmeshTraversalController cd(tetMeshIndices.begin(), tetMeshVertices.begin(), tree.begin()); + + barycentricCoordinates.resize(pointsToEmbed.size()); + tetLinks.resize(pointsToEmbed.size()); + for (PxU32 i = 0; i < pointsToEmbed.size(); ++i) + { + cd.setQueryPoint(pointsToEmbed[i]); + Gu::traverseBVH(tree.begin(), cd); + + const PxU32* tet = &tetMeshIndices[4 * cd.getClosestTetId()]; + PxVec4 bary; + computeBarycentric(tetMeshVertices[tet[0]], tetMeshVertices[tet[1]], tetMeshVertices[tet[2]], tetMeshVertices[tet[3]], cd.getClosestPoint(), bary); + + barycentricCoordinates[i] = bary; + tetLinks[i] = cd.getClosestTetId(); + } + } + struct SortedTriangle { public: diff --git a/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.cpp b/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.cpp index 16593f632..f83704470 100644 --- a/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.cpp +++ b/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.cpp @@ -42,25 +42,23 @@ using namespace physx; static uint32_t sizeOfOmniPvdTypes[32]; //create a class for each SDK type and attribute -- the primary thing is to allocate handle storage, the rest is just fluff. -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) OmniPvdClassHandle OmniPvdPxExtensionsSampler::classHandle_##c; -#define OMNI_PVD_CLASS(c, classT) OmniPvdClassHandle OmniPvdPxExtensionsSampler::classHandle_##c; -#define OMNI_PVD_ENUM(c, classT) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) OmniPvdAttributeHandle OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a; +#define OMNI_PVD_CLASS(classT) OmniPvdClassHandle OmniPvdPxExtensionsSampler::classHandle_##classT; +#define OMNI_PVD_ENUM(classT) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) OmniPvdAttributeHandle OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a; //enum values don't need to save their handle, since they are const/immutable: -#define OMNI_PVD_ENUM_VALUE(c, a, v) -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) OmniPvdAttributeHandle OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a; -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) OmniPvdAttributeHandle OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a; +#define OMNI_PVD_ENUM_VALUE(classT, a) +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) OmniPvdAttributeHandle OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a; +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) OmniPvdAttributeHandle OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a; #include "OmniPvdPxExtensionsTypes.h" #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST #undef OMNI_PVD_ATTRIBUTE_FLAG void OmniPvdPxExtensionsSampler::registerClasses() @@ -68,81 +66,74 @@ void OmniPvdPxExtensionsSampler::registerClasses() if (mWriter) { //register all SDK classes and attributes: -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) OmniPvdPxExtensionsSampler::classHandle_##c = mWriter->registerClass(#classStr); -#define OMNI_PVD_CLASS(c, classT) OmniPvdPxExtensionsSampler::classHandle_##c = mWriter->registerClass(#classT); -#define OMNI_PVD_ENUM(c, classT) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OmniPvdPxExtensionsSampler::classHandle_##c = mWriter->registerClass(#classT, OmniPvdPxExtensionsSampler::classHandle_##baseClass); -#define OMNI_PVD_ENUM_VALUE(c, a, v) mWriter->registerEnumValue(OmniPvdPxExtensionsSampler::classHandle_##c, #a, v); -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a = mWriter->registerSetAttribute(OmniPvdPxExtensionsSampler::classHandle_##c, #a, OmniPvdDataTypeEnum::eOBJECT_HANDLE); -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) PX_ASSERT((n == 0) || (sizeof(attrT) == sizeOfOmniPvdTypes[t] * n)); OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a = mWriter->registerAttribute(OmniPvdPxExtensionsSampler::classHandle_##c, #a, t, n); -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a = mWriter->registerFlagsAttribute(OmniPvdPxExtensionsSampler::classHandle_##c, OmniPvdPxExtensionsSampler::classHandle_##enumClass, #a); +#define OMNI_PVD_CLASS(classT) OmniPvdPxExtensionsSampler::classHandle_##classT = mWriter->registerClass(#classT); +#define OMNI_PVD_ENUM(classT) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OmniPvdPxExtensionsSampler::classHandle_##classT = mWriter->registerClass(#classT, OmniPvdPxExtensionsSampler::classHandle_##baseClass); +#define OMNI_PVD_ENUM_VALUE(classT, a) mWriter->registerEnumValue(OmniPvdPxExtensionsSampler::classHandle_##classT, #a, classT::a); +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a = mWriter->registerUniqueListAttribute(OmniPvdPxExtensionsSampler::classHandle_##classT, #a, OmniPvdDataType::eOBJECT_HANDLE); +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) PX_ASSERT((n == 0) || (sizeof(attrT) == sizeOfOmniPvdTypes[t] * n)); OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a = mWriter->registerAttribute(OmniPvdPxExtensionsSampler::classHandle_##classT, #a, t, n); +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a = mWriter->registerFlagsAttribute(OmniPvdPxExtensionsSampler::classHandle_##classT, #a, OmniPvdPxExtensionsSampler::classHandle_##enumClassT); #include "OmniPvdPxExtensionsTypes.h" #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST #undef OMNI_PVD_ATTRIBUTE_FLAG } } //instance any templates that are not used in this compilation unit so that code gets generated anyways -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) \ +#define OMNI_PVD_CLASS(classT) \ template void OmniPvdPxExtensionsSampler::createObject (OmniPvdClassHandle, classT const &);\ template void OmniPvdPxExtensionsSampler::destroyObject(classT const &); -#define OMNI_PVD_CLASS(c, classT) \ -template void OmniPvdPxExtensionsSampler::createObject (OmniPvdClassHandle, classT const &);\ -template void OmniPvdPxExtensionsSampler::destroyObject(classT const &); - -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OMNI_PVD_CLASS(c, classT) +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OMNI_PVD_CLASS(classT) -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) \ -template void OmniPvdPxExtensionsSampler::addToSet(OmniPvdAttributeHandle, classT const & , attrT const & );\ -template void OmniPvdPxExtensionsSampler::removeFromSet(OmniPvdAttributeHandle, classT const & , attrT const & ); +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) \ +template void OmniPvdPxExtensionsSampler::addToUniqueList(OmniPvdAttributeHandle, classT const & , attrT const & );\ +template void OmniPvdPxExtensionsSampler::removeFromUniqueList(OmniPvdAttributeHandle, classT const & , attrT const & ); -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) \ +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) \ template void OmniPvdPxExtensionsSampler::setAttribute(OmniPvdAttributeHandle, const classT&, attrT const &); \ template void OmniPvdPxExtensionsSampler::setAttributeBytes(OmniPvdAttributeHandle, const classT&, attrT const *, unsigned); -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) \ +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClass) \ template void OmniPvdPxExtensionsSampler::setAttribute(OmniPvdAttributeHandle, classT const &, attrT const &); -#define OMNI_PVD_ENUM(c, enumT) -#define OMNI_PVD_ENUM_VALUE(c, a, v) +#define OMNI_PVD_ENUM(classT) +#define OMNI_PVD_ENUM_VALUE(classT, a) #include "OmniPvdPxExtensionsTypes.h" #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST //end instance templates OmniPvdPxExtensionsSampler::OmniPvdPxExtensionsSampler() : mWriter(NULL) { //TODO: this could be done better - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT8] = 1; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT16] = 2; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT32] = 4; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eINT64] = 8; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT8] = 1; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT16] = 2; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT32] = 4; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eUINT64] = 8; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eFLOAT32] = 4; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eFLOAT64] = 8; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eSTRING] = 1; - sizeOfOmniPvdTypes[OmniPvdDataTypeEnum::eOBJECT_HANDLE] = sizeof(uint64_t); + sizeOfOmniPvdTypes[OmniPvdDataType::eINT8] = 1; + sizeOfOmniPvdTypes[OmniPvdDataType::eINT16] = 2; + sizeOfOmniPvdTypes[OmniPvdDataType::eINT32] = 4; + sizeOfOmniPvdTypes[OmniPvdDataType::eINT64] = 8; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT8] = 1; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT16] = 2; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT32] = 4; + sizeOfOmniPvdTypes[OmniPvdDataType::eUINT64] = 8; + sizeOfOmniPvdTypes[OmniPvdDataType::eFLOAT32] = 4; + sizeOfOmniPvdTypes[OmniPvdDataType::eFLOAT64] = 8; + sizeOfOmniPvdTypes[OmniPvdDataType::eSTRING] = 1; + sizeOfOmniPvdTypes[OmniPvdDataType::eOBJECT_HANDLE] = sizeof(uint64_t); } OmniPvdPxExtensionsSampler::~OmniPvdPxExtensionsSampler() @@ -171,27 +162,27 @@ template void OmniPvdPxExtensionsSampler::destroyObject(Cla template void OmniPvdPxExtensionsSampler::setAttribute(OmniPvdAttributeHandle ah, const ClassType & objectId, const AttributeType & value) { PX_ASSERT(mWriter); - mWriter->setAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&value, sizeof(AttributeType)); + mWriter->setAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&value, sizeof(AttributeType)); } template void OmniPvdPxExtensionsSampler::setAttributeBytes(OmniPvdAttributeHandle ah, ClassType const & objectId, const AttributeType * value, unsigned nBytes) { PX_ASSERT(mWriter); - mWriter->setAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)value, nBytes); + mWriter->setAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)value, nBytes); } -template void OmniPvdPxExtensionsSampler::addToSet(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) +template void OmniPvdPxExtensionsSampler::addToUniqueList(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) { PX_ASSERT(mWriter); const AttributeType * atp = &value; - mWriter->addToSetAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp)); + mWriter->addToUniqueListAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp)); } -template void OmniPvdPxExtensionsSampler::removeFromSet(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) +template void OmniPvdPxExtensionsSampler::removeFromUniqueList(OmniPvdAttributeHandle ah, ClassType const & objectId, AttributeType const & value) { PX_ASSERT(mWriter); const AttributeType * atp = &value; - mWriter->removeFromSetAttributeShallow(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp) ); + mWriter->removeFromUniqueListAttribute(UNNECESSARY_SCENE_HANDLE, OmniPvdObjectHandle(&objectId), ah, (const unsigned char*)&atp, sizeof(atp) ); } /////////////////////////////////////////////////////////////////////////////// diff --git a/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.h b/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.h index d3ae58fbf..6f62cf98e 100644 --- a/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.h +++ b/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsSampler.h @@ -42,27 +42,88 @@ The below helper macros are to be used in Extensions code to send information to #if PX_SUPPORT_OMNI_PVD // You can use this in conditional statements to check for a connection #define OMNI_PVD_ACTIVE (::OmniPvdPxExtensionsSampler::getInstance() != NULL) - // Create object reference o of PVD type c. Example: OMNI_PVD_CREATE(scene, static_cast(*npScene)); - #define OMNI_PVD_CREATE(c, o) if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->createObject(OmniPvdPxExtensionsSampler::classHandle_##c, o); } - // Destroy object reference o of PVD type c. Example: OMNI_PVD_DESTROY(scene, static_cast(*npScene)); - #define OMNI_PVD_DESTROY(c, o) if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->destroyObject(o); } - // Set PVD attribute a of object reference o of PVD type c to value v. v is passed as reference to value; PVD object handles are passed as reference to POINTER here! - // Example: OMNI_PVD_SET(actor, isdynamic, a, false) - #define OMNI_PVD_SET(c, a, o, v) if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->setAttribute(OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a, o, v); } - // Same as set, but for variable length attributes like vertex buffers. pv is the address of the data, and n is the size in bytes. - #define OMNI_PVD_SETB(c, a, o, pv, n)if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->setAttributeBytes(OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a, o, pv, n); } - // Same as set, but for attribute sets of unique things like an array of references. v is passed as a REFERENCE. - #define OMNI_PVD_ADD(c, a, o, v) if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->addToSet(OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a, o, v); } - // TO remove a member handle from the set. - #define OMNI_PVD_REMOVE(c, a, o, v) if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->removeFromSet(OmniPvdPxExtensionsSampler::attributeHandle_##c##_##a, o, v); } + +// Create object reference o of PVD type classT. Example: OMNI_PVD_CREATE(scene, static_cast(*npScene)); +#if PX_GCC_FAMILY + #define OMNI_PVD_CREATE(classT, o) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->createObject(OmniPvdPxExtensionsSampler::classHandle_##classT, o); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_CREATE(classT, o) \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->createObject(OmniPvdPxExtensionsSampler::classHandle_##classT, o); } +#endif + +// Destroy object reference o of PVD type classT. Example: OMNI_PVD_DESTROY(scene, static_cast(*npScene)); +#if PX_GCC_FAMILY + #define OMNI_PVD_DESTROY(classT, o) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->destroyObject(o); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_DESTROY(classT, o) \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->destroyObject(o); } +#endif + +// Set PVD attribute a of object reference o of PVD type classT to value v. v is passed as reference to value; PVD object handles are passed as reference to POINTER here! +// Example: OMNI_PVD_SET(PxActor, isdynamic, a, false) +#if PX_GCC_FAMILY + #define OMNI_PVD_SET(classT, a, o, v) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->setAttribute(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, v); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_SET(classT, a, o, v) \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->setAttribute(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, v); } +#endif + +// Same as set, but for variable length attributes like vertex buffers. pv is the address of the data, and n is the size in bytes. +#if PX_GCC_FAMILY + #define OMNI_PVD_SETB(classT, a, o, pv, n) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->setAttributeBytes(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, pv, n); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_SETB(classT, a, o, pv, n) \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->setAttributeBytes(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, pv, n); } +#endif + +// Same as set, but for attribute sets of unique things like an array of references. v is passed as a REFERENCE. +#if PX_GCC_FAMILY + #define OMNI_PVD_ADD(classT, a, o, v) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->addToUniqueList(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, v); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_ADD(classT, a, o, v) \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->addToUniqueList(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, v); } +#endif + +// TO remove a member handle from the set. +#if PX_GCC_FAMILY + #define OMNI_PVD_REMOVE(classT, a, o, v) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wundefined-func-template\"") \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->removeFromUniqueList(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, v); } \ + _Pragma("GCC diagnostic pop") +#else + #define OMNI_PVD_REMOVE(classT, a, o, v) \ + if (::OmniPvdPxExtensionsSampler::getInstance() != NULL) {::OmniPvdPxExtensionsSampler::getInstance()->removeFromUniqueList(OmniPvdPxExtensionsSampler::attributeHandle_##classT##_##a, o, v); } +#endif + #else #define OMNI_PVD_ACTIVE (false) - #define OMNI_PVD_CREATE(c, p) - #define OMNI_PVD_DESTROY(c, p) - #define OMNI_PVD_SET(c, a, p, v) - #define OMNI_PVD_SETB(c, a, p, v, n) - #define OMNI_PVD_ADD(c, a, p, v) - #define OMNI_PVD_REMOVE(c, a, p, v) + #define OMNI_PVD_CREATE(classT, p) + #define OMNI_PVD_DESTROY(classT, p) + #define OMNI_PVD_SET(classT, a, p, v) + #define OMNI_PVD_SETB(classT, a, p, v, n) + #define OMNI_PVD_ADD(classT, a, p, v) + #define OMNI_PVD_REMOVE(classT, a, p, v) #endif @@ -86,29 +147,27 @@ class OmniPvdPxExtensionsSampler : public physx::PxUserAllocated template void destroyObject(ClassType const & objectId); template void setAttribute(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); template void setAttributeBytes(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const * value, unsigned nBytes); - template void addToSet(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); - template void removeFromSet(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); + template void addToUniqueList(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); + template void removeFromUniqueList(OmniPvdAttributeHandle, ClassType const & objectId, AttributeType const & value); //handles for all Extensions classes and attributes -#define OMNI_PVD_FAKE_CLASS(c, classT, classStr) static OmniPvdClassHandle classHandle_##c; -#define OMNI_PVD_CLASS(c, classT) static OmniPvdClassHandle classHandle_##c; -#define OMNI_PVD_CLASS_DERIVED(c, classT, baseClass) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_ENUM(c, classT) OMNI_PVD_CLASS(c, classT) -#define OMNI_PVD_ENUM_VALUE(c, a, v) -#define OMNI_PVD_ATTRIBUTE(c, a, classT, attrT, t, n) static OmniPvdAttributeHandle attributeHandle_##c##_##a; -#define OMNI_PVD_ATTRIBUTE_SET(c, a, classT, attrT) static OmniPvdAttributeHandle attributeHandle_##c##_##a; -#define OMNI_PVD_ATTRIBUTE_FLAG(c, a, classT, attrT, enumClass) static OmniPvdAttributeHandle attributeHandle_##c##_##a; +#define OMNI_PVD_CLASS(classT) static OmniPvdClassHandle classHandle_##classT; +#define OMNI_PVD_CLASS_DERIVED(classT, baseClass) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_ENUM(classT) OMNI_PVD_CLASS(classT) +#define OMNI_PVD_ENUM_VALUE(classT, a) +#define OMNI_PVD_ATTRIBUTE(classT, a, attrT, t, n) static OmniPvdAttributeHandle attributeHandle_##classT##_##a; +#define OMNI_PVD_ATTRIBUTE_UNIQUE_LIST(classT, a, attrT) static OmniPvdAttributeHandle attributeHandle_##classT##_##a; +#define OMNI_PVD_ATTRIBUTE_FLAG(classT, a, attrT, enumClassT) static OmniPvdAttributeHandle attributeHandle_##classT##_##a; #include "OmniPvdPxExtensionsTypes.h" //Extensions classes and attributes declared here #undef OMNI_PVD_ENUM #undef OMNI_PVD_ENUM_VALUE -#undef OMNI_PVD_FAKE_CLASS #undef OMNI_PVD_CLASS #undef OMNI_PVD_CLASS_DERIVED #undef OMNI_PVD_ATTRIBUTE -#undef OMNI_PVD_ATTRIBUTE_SET +#undef OMNI_PVD_ATTRIBUTE_UNIQUE_LIST #undef OMNI_PVD_ATTRIBUTE_FLAG // OmniPvdPxExtensionsSampler singleton diff --git a/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsTypes.h b/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsTypes.h index bae41126d..5ec5c8242 100644 --- a/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsTypes.h +++ b/physx/source/physxextensions/src/omnipvd/OmniPvdPxExtensionsTypes.h @@ -30,193 +30,210 @@ // The last two attribute parameters could now be derived from the other data, so could be removed in a refactor, // though explicit control may be better. // Note that HANDLE attributes have to use (Type const *) style, otherwise it won't compile! -// Note also that if we update the PVD USD reader code to not need different names than we use in the source code we don't need to pass both e.g. "scene" and "PxScene" and we can simplify - -OMNI_PVD_ENUM (constraintflag, PxConstraintFlag) -OMNI_PVD_ENUM_VALUE (constraintflag, eBROKEN, PxConstraintFlag::eBROKEN) -OMNI_PVD_ENUM_VALUE (constraintflag, ePROJECT_TO_ACTOR0, PxConstraintFlag::ePROJECT_TO_ACTOR0) -OMNI_PVD_ENUM_VALUE (constraintflag, ePROJECT_TO_ACTOR1, PxConstraintFlag::ePROJECT_TO_ACTOR1) -OMNI_PVD_ENUM_VALUE (constraintflag, ePROJECTION, PxConstraintFlag::ePROJECTION) -OMNI_PVD_ENUM_VALUE (constraintflag, eCOLLISION_ENABLED, PxConstraintFlag::eCOLLISION_ENABLED) -OMNI_PVD_ENUM_VALUE (constraintflag, eVISUALIZATION, PxConstraintFlag::eVISUALIZATION) -OMNI_PVD_ENUM_VALUE (constraintflag, eDRIVE_LIMITS_ARE_FORCES, PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES) -OMNI_PVD_ENUM_VALUE (constraintflag, eIMPROVED_SLERP, PxConstraintFlag::eIMPROVED_SLERP) -OMNI_PVD_ENUM_VALUE (constraintflag, eDISABLE_PREPROCESSING, PxConstraintFlag::eDISABLE_PREPROCESSING) -OMNI_PVD_ENUM_VALUE (constraintflag, eENABLE_EXTENDED_LIMITS, PxConstraintFlag::eENABLE_EXTENDED_LIMITS) -OMNI_PVD_ENUM_VALUE (constraintflag, eGPU_COMPATIBLE, PxConstraintFlag::eGPU_COMPATIBLE) -OMNI_PVD_ENUM_VALUE (constraintflag, eALWAYS_UPDATE, PxConstraintFlag::eALWAYS_UPDATE) -OMNI_PVD_ENUM_VALUE (constraintflag, eDISABLE_CONSTRAINT, PxConstraintFlag::eDISABLE_CONSTRAINT) - -OMNI_PVD_ENUM (revolutejointflag, PxRevoluteJointFlag) -OMNI_PVD_ENUM_VALUE (revolutejointflag, eLIMIT_ENABLED, PxRevoluteJointFlag::eLIMIT_ENABLED) -OMNI_PVD_ENUM_VALUE (revolutejointflag, eDRIVE_ENABLED, PxRevoluteJointFlag::eDRIVE_ENABLED) -OMNI_PVD_ENUM_VALUE (revolutejointflag, eDRIVE_FREESPIN, PxRevoluteJointFlag::eDRIVE_FREESPIN) - -OMNI_PVD_ENUM (prismaticjointflag, PxPrismaticJointFlag) -OMNI_PVD_ENUM_VALUE (prismaticjointflag, eLIMIT_ENABLED, PxPrismaticJointFlag::eLIMIT_ENABLED) - -OMNI_PVD_ENUM (distancejointflag, PxDistanceJointFlag) -OMNI_PVD_ENUM_VALUE (distancejointflag, eMAX_DISTANCE_ENABLED, PxDistanceJointFlag::eMAX_DISTANCE_ENABLED) -OMNI_PVD_ENUM_VALUE (distancejointflag, eMIN_DISTANCE_ENABLED, PxDistanceJointFlag::eMIN_DISTANCE_ENABLED) -OMNI_PVD_ENUM_VALUE (distancejointflag, eSPRING_ENABLED, PxDistanceJointFlag::eSPRING_ENABLED) - -OMNI_PVD_ENUM (sphericaljointflag, PxSphericalJointFlag) -OMNI_PVD_ENUM_VALUE (sphericaljointflag, eLIMIT_ENABLED, PxSphericalJointFlag::eLIMIT_ENABLED) - -OMNI_PVD_ENUM (d6jointdriveflag, PxD6JointDriveFlag) -OMNI_PVD_ENUM_VALUE (d6jointdriveflag, eACCELERATION, PxD6JointDriveFlag::eACCELERATION) - -OMNI_PVD_ENUM (jointconcretetype, PxJointConcreteType) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eSPHERICAL, PxJointConcreteType::eSPHERICAL) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eREVOLUTE, PxJointConcreteType::eREVOLUTE) -OMNI_PVD_ENUM_VALUE (jointconcretetype, ePRISMATIC, PxJointConcreteType::ePRISMATIC) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eFIXED, PxJointConcreteType::eFIXED) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eDISTANCE, PxJointConcreteType::eDISTANCE) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eD6, PxJointConcreteType::eD6) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eCONTACT, PxJointConcreteType::eCONTACT) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eGEAR, PxJointConcreteType::eGEAR) -OMNI_PVD_ENUM_VALUE (jointconcretetype, eRACK_AND_PINION, PxJointConcreteType::eRACK_AND_PINION) - -OMNI_PVD_ENUM (d6motion, PxD6Motion) -OMNI_PVD_ENUM_VALUE (d6motion, eLOCKED, PxD6Motion::eLOCKED) -OMNI_PVD_ENUM_VALUE (d6motion, eLIMITED, PxD6Motion::eLIMITED) -OMNI_PVD_ENUM_VALUE (d6motion, eFREE, PxD6Motion::eFREE) + +//////////////////////////////////////////////////////////////////////////////// +// Enums +//////////////////////////////////////////////////////////////////////////////// + +OMNI_PVD_ENUM (PxConstraintFlag) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eBROKEN) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eCOLLISION_ENABLED) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eVISUALIZATION) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eDRIVE_LIMITS_ARE_FORCES) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eIMPROVED_SLERP) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eDISABLE_PREPROCESSING) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eENABLE_EXTENDED_LIMITS) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eGPU_COMPATIBLE) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eALWAYS_UPDATE) +OMNI_PVD_ENUM_VALUE (PxConstraintFlag, eDISABLE_CONSTRAINT) + +OMNI_PVD_ENUM (PxRevoluteJointFlag) +OMNI_PVD_ENUM_VALUE (PxRevoluteJointFlag, eLIMIT_ENABLED) +OMNI_PVD_ENUM_VALUE (PxRevoluteJointFlag, eDRIVE_ENABLED) +OMNI_PVD_ENUM_VALUE (PxRevoluteJointFlag, eDRIVE_FREESPIN) + +OMNI_PVD_ENUM (PxPrismaticJointFlag) +OMNI_PVD_ENUM_VALUE (PxPrismaticJointFlag, eLIMIT_ENABLED) + +OMNI_PVD_ENUM (PxDistanceJointFlag) +OMNI_PVD_ENUM_VALUE (PxDistanceJointFlag, eMAX_DISTANCE_ENABLED) +OMNI_PVD_ENUM_VALUE (PxDistanceJointFlag, eMIN_DISTANCE_ENABLED) +OMNI_PVD_ENUM_VALUE (PxDistanceJointFlag, eSPRING_ENABLED) + +OMNI_PVD_ENUM (PxSphericalJointFlag) +OMNI_PVD_ENUM_VALUE (PxSphericalJointFlag, eLIMIT_ENABLED) + +OMNI_PVD_ENUM (PxD6JointDriveFlag) +OMNI_PVD_ENUM_VALUE (PxD6JointDriveFlag, eACCELERATION) + +OMNI_PVD_ENUM (PxJointConcreteType) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eSPHERICAL) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eREVOLUTE) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, ePRISMATIC) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eFIXED) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eDISTANCE) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eD6) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eCONTACT) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eGEAR) +OMNI_PVD_ENUM_VALUE (PxJointConcreteType, eRACK_AND_PINION) + +OMNI_PVD_ENUM (PxD6Motion) +OMNI_PVD_ENUM_VALUE (PxD6Motion, eLOCKED) +OMNI_PVD_ENUM_VALUE (PxD6Motion, eLIMITED) +OMNI_PVD_ENUM_VALUE (PxD6Motion, eFREE) //////////////////////////////////////////////////////////////////////////////// // Classes //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// -// Joint -//////////////////////////////////////////////////////////////////////////////// -OMNI_PVD_CLASS (joint, PxJoint) -// Common -OMNI_PVD_ATTRIBUTE_FLAG (joint, type, PxJoint, PxJointConcreteType::Enum, jointconcretetype) -OMNI_PVD_ATTRIBUTE (joint, actor0, PxJoint, PxRigidActor*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (joint, actor1, PxJoint, PxRigidActor*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1) -OMNI_PVD_ATTRIBUTE (joint, actor0LocalPose, PxJoint, PxTransform, OmniPvdDataTypeEnum::eFLOAT32, 7) -OMNI_PVD_ATTRIBUTE (joint, actor1LocalPose, PxJoint, PxTransform, OmniPvdDataTypeEnum::eFLOAT32, 7) -OMNI_PVD_ATTRIBUTE (joint, breakForce, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, breakTorque, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (joint, constraintFlags, PxJoint, PxConstraintFlags, constraintflag) -OMNI_PVD_ATTRIBUTE (joint, invMassScale0, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, invInertiaScale0, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, invMassScale1, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, invInertiaScale1, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, name, PxJoint, char, OmniPvdDataTypeEnum::eSTRING, 1) -OMNI_PVD_ATTRIBUTE (joint, concreteTypeName, PxJoint, char, OmniPvdDataTypeEnum::eSTRING, 1) -// Fixed -OMNI_PVD_ATTRIBUTE (joint, fixedProjectionLinearTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, fixedProjectionAngularTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -// Prismatic -OMNI_PVD_ATTRIBUTE (joint, prismaticPosition, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticVelocity, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticProjectionLinearTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticProjectionAngularTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitLower, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitUpper, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, prismaticLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (joint, prismaticJointFlags, PxJoint, PxPrismaticJointFlags, prismaticjointflag) -// Revolute -OMNI_PVD_ATTRIBUTE (joint, revoluteAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteVelocity, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteProjectionLinearTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteProjectionAngularTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitLower, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitUpper, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteDriveVelocity, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteDriveForceLimit, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, revoluteDriveGearRatio, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (joint, revoluteJointFlags, PxJoint, PxRevoluteJointFlags, revolutejointflag) -// Spherical -OMNI_PVD_ATTRIBUTE (joint, sphericalSwingYAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalSwingZAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalProjectionLinearTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitYAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitZAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, sphericalLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (joint, sphericalJointFlags, PxJoint, PxSphericalJointFlags, sphericaljointflag) -// Distance -OMNI_PVD_ATTRIBUTE (joint, distanceDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, distanceMinDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, distanceMaxDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, distanceTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, distanceStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, distanceDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, distanceContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE_FLAG (joint, distanceJointFlags, PxJoint, PxDistanceJointFlags, distancejointflag) -// Contact -OMNI_PVD_ATTRIBUTE (joint, contactPoint, PxJoint, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (joint, contactNormal, PxJoint, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (joint, contactPenetration, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, contactRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, contactBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -// Gear -OMNI_PVD_ATTRIBUTE (joint, gearRatio, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, gearHinges, PxJoint, const PxBase*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 0) -// RackAndPinion -OMNI_PVD_ATTRIBUTE (joint, rackAndPinionRatio, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, rackAndPinionJoints, PxJoint, const PxBase*, OmniPvdDataTypeEnum::eOBJECT_HANDLE, 0) -// D6 -OMNI_PVD_ATTRIBUTE (joint, d6TwistAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingYAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingZAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6ProjectionLinearTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6ProjectionAngularTolerance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6Motions, PxJoint, PxD6Motion::Enum, OmniPvdDataTypeEnum::eUINT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6DistanceLimitValue, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6DistanceLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6DistanceLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6DistanceLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6DistanceLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6DistanceLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitLower, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitUpper, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6LinearLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitLower, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitUpper, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6TwistLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitYAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitZAngle, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6SwingLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitYAngleMin, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitYAngleMax, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitZAngleMin, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitZAngleMax, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitRestitution, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitBounceThreshold, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6PyramidSwingLimitContactDistance, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 1) -OMNI_PVD_ATTRIBUTE (joint, d6DriveForceLimit, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6DriveFlags, PxJoint, PxD6JointDriveFlags, OmniPvdDataTypeEnum::eUINT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6DriveStiffness, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6DriveDamping, PxJoint, PxReal, OmniPvdDataTypeEnum::eFLOAT32, 0) -OMNI_PVD_ATTRIBUTE (joint, d6DrivePosition, PxJoint, PxTransform, OmniPvdDataTypeEnum::eFLOAT32, 7) -OMNI_PVD_ATTRIBUTE (joint, d6DriveLinVelocity, PxJoint, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) -OMNI_PVD_ATTRIBUTE (joint, d6DriveAngVelocity, PxJoint, PxVec3, OmniPvdDataTypeEnum::eFLOAT32, 3) +// PxJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS (PxJoint) +OMNI_PVD_ATTRIBUTE_FLAG (PxJoint, type, PxJointConcreteType::Enum, PxJointConcreteType) +OMNI_PVD_ATTRIBUTE (PxJoint, actor0, PxRigidActor*, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, actor1, PxRigidActor*, OmniPvdDataType::eOBJECT_HANDLE, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, actor0LocalPose, PxTransform, OmniPvdDataType::eFLOAT32, 7) +OMNI_PVD_ATTRIBUTE (PxJoint, actor1LocalPose, PxTransform, OmniPvdDataType::eFLOAT32, 7) +OMNI_PVD_ATTRIBUTE (PxJoint, breakForce, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, breakTorque, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxJoint, constraintFlags, PxConstraintFlags, PxConstraintFlag) +OMNI_PVD_ATTRIBUTE (PxJoint, invMassScale0, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, invInertiaScale0, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, invMassScale1, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, invInertiaScale1, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, name, char, OmniPvdDataType::eSTRING, 1) +OMNI_PVD_ATTRIBUTE (PxJoint, concreteTypeName, char, OmniPvdDataType::eSTRING, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxFixedJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxFixedJoint, PxJoint) + +//////////////////////////////////////////////////////////////////////////////// +// PxPrismaticJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxPrismaticJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, position, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, velocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, limitLower, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, limitUpper, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, limitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, limitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, limitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxPrismaticJoint, limitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxPrismaticJoint, jointFlags, PxPrismaticJointFlags, PxPrismaticJointFlag) + +//////////////////////////////////////////////////////////////////////////////// +// PxRevoluteJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxRevoluteJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, angle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, velocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, limitLower, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, limitUpper, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, limitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, limitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, limitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, limitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, driveVelocity, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, driveForceLimit, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRevoluteJoint, driveGearRatio, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxRevoluteJoint, jointFlags, PxRevoluteJointFlags, PxRevoluteJointFlag) + +//////////////////////////////////////////////////////////////////////////////// +// PxSphericalJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxSphericalJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, swingYAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, swingZAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, limitYAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, limitZAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, limitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, limitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, limitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxSphericalJoint, limitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxSphericalJoint, jointFlags, PxSphericalJointFlags, PxSphericalJointFlag) + +//////////////////////////////////////////////////////////////////////////////// +// PxDistanceJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxDistanceJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxDistanceJoint, distance, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxDistanceJoint, minDistance, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxDistanceJoint, maxDistance, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxDistanceJoint, tolerance, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxDistanceJoint, stiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxDistanceJoint, damping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE_FLAG (PxDistanceJoint, jointFlags, PxDistanceJointFlags, PxDistanceJointFlag) + +//////////////////////////////////////////////////////////////////////////////// +// PxContactJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxContactJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxContactJoint, point, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxContactJoint, normal, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxContactJoint, penetration, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxContactJoint, restitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxContactJoint, bounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) + +//////////////////////////////////////////////////////////////////////////////// +// PxGearJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxGearJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxGearJoint, ratio, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxGearJoint, hinges, const PxBase*, OmniPvdDataType::eOBJECT_HANDLE, 0) + +//////////////////////////////////////////////////////////////////////////////// +// PxRackAndPinionJoint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxRackAndPinionJoint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxRackAndPinionJoint, ratio, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxRackAndPinionJoint, joints, const PxBase*, OmniPvdDataType::eOBJECT_HANDLE, 0) + +//////////////////////////////////////////////////////////////////////////////// +// PxD6Joint +//////////////////////////////////////////////////////////////////////////////// +OMNI_PVD_CLASS_DERIVED (PxD6Joint, PxJoint) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingYAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingZAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, motions, PxD6Motion::Enum, OmniPvdDataType::eUINT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, distanceLimitValue, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, distanceLimitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, distanceLimitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, distanceLimitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, distanceLimitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, linearLimitLower, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, linearLimitUpper, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, linearLimitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, linearLimitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, linearLimitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, linearLimitDamping, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistLimitLower, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistLimitUpper, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistLimitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistLimitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistLimitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, twistLimitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingLimitYAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingLimitZAngle, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingLimitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingLimitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingLimitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, swingLimitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitYAngleMin, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitYAngleMax, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitZAngleMin, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitZAngleMax, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitRestitution, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitBounceThreshold, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitStiffness, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, pyramidSwingLimitDamping, PxReal, OmniPvdDataType::eFLOAT32, 1) +OMNI_PVD_ATTRIBUTE (PxD6Joint, driveForceLimit, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, driveFlags, PxD6JointDriveFlags, OmniPvdDataType::eUINT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, driveStiffness, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, driveDamping, PxReal, OmniPvdDataType::eFLOAT32, 0) +OMNI_PVD_ATTRIBUTE (PxD6Joint, drivePosition, PxTransform, OmniPvdDataType::eFLOAT32, 7) +OMNI_PVD_ATTRIBUTE (PxD6Joint, driveLinVelocity, PxVec3, OmniPvdDataType::eFLOAT32, 3) +OMNI_PVD_ATTRIBUTE (PxD6Joint, driveAngVelocity, PxVec3, OmniPvdDataType::eFLOAT32, 3) diff --git a/physx/source/physxextensions/src/serialization/Binary/SnBinaryDeserialization.cpp b/physx/source/physxextensions/src/serialization/Binary/SnBinaryDeserialization.cpp index cc078a814..dc4386682 100644 --- a/physx/source/physxextensions/src/serialization/Binary/SnBinaryDeserialization.cpp +++ b/physx/source/physxextensions/src/serialization/Binary/SnBinaryDeserialization.cpp @@ -83,7 +83,6 @@ namespace const PxU32 markedPadding = read32(address); PX_UNUSED(markedPadding); -#if PX_CHECKED if (header != PX_MAKE_FOURCC('S','E','B','D')) { PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, @@ -107,7 +106,7 @@ namespace getBinaryPlatformName(platformTag)); return false; } -#endif + return true; } @@ -148,13 +147,12 @@ namespace PxCollection* PxSerialization::createCollectionFromBinary(void* memBlock, PxSerializationRegistry& sr, const PxCollection* pxExternalRefs) { -#if PX_CHECKED if(size_t(memBlock) & (PX_SERIAL_FILE_ALIGN-1)) { PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, "Buffer must be 128-bytes aligned."); return NULL; } -#endif + PxU8* address = reinterpret_cast(memBlock); const Cm::Collection* externalRefs = static_cast(pxExternalRefs); diff --git a/physx/source/physxextensions/src/serialization/Binary/SnSerializationContext.h b/physx/source/physxextensions/src/serialization/Binary/SnSerializationContext.h index 472beaf35..ef354f695 100644 --- a/physx/source/physxextensions/src/serialization/Binary/SnSerializationContext.h +++ b/physx/source/physxextensions/src/serialization/Binary/SnSerializationContext.h @@ -44,16 +44,8 @@ namespace physx { namespace Sn { - struct ManifestEntry { - //= 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_FORCE_INLINE ManifestEntry(PxU32 _offset, PxType _type) { PxMarkSerializedMemory(this, sizeof(ManifestEntry)); @@ -72,13 +64,6 @@ namespace physx struct ImportReference { - //= 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_FORCE_INLINE ImportReference(PxSerialObjectId _id, PxType _type) { PxMarkSerializedMemory(this, sizeof(ImportReference)); @@ -97,13 +82,6 @@ namespace physx #define SERIAL_OBJECT_INDEX_TYPE_BIT (1u<<31) struct SerialObjectIndex { - //= 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_FORCE_INLINE SerialObjectIndex(PxU32 index, bool external) { setIndex(index, external); } PX_FORCE_INLINE SerialObjectIndex(const SerialObjectIndex& objIndex) : mObjIndex(objIndex.mObjIndex) {} PX_FORCE_INLINE SerialObjectIndex() : mObjIndex(PX_INVALID_U32) {} @@ -132,13 +110,6 @@ namespace physx struct ExportReference { - //= 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_FORCE_INLINE ExportReference(PxSerialObjectId _id, SerialObjectIndex _objIndex) { PxMarkSerializedMemory(this, sizeof(ExportReference)); @@ -156,13 +127,6 @@ namespace physx struct InternalReferencePtr { - //= 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_FORCE_INLINE InternalReferencePtr() {} PX_FORCE_INLINE InternalReferencePtr(size_t _reference, SerialObjectIndex _objIndex) : @@ -183,13 +147,6 @@ namespace physx struct InternalReferenceHandle16 { - //= 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_FORCE_INLINE InternalReferenceHandle16() {} PX_FORCE_INLINE InternalReferenceHandle16(PxU16 _reference, SerialObjectIndex _objIndex) : diff --git a/physx/source/physxextensions/src/serialization/Xml/SnJointRepXSerializer.h b/physx/source/physxextensions/src/serialization/Xml/SnJointRepXSerializer.h index 5531ca08c..27cf5d37d 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnJointRepXSerializer.h +++ b/physx/source/physxextensions/src/serialization/Xml/SnJointRepXSerializer.h @@ -45,7 +45,7 @@ namespace physx class MemoryBuffer; template - struct PxJointRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxJointRepXSerializer : public RepXSerializerImpl { PxJointRepXSerializer(PxAllocatorCallback& inAllocator) : RepXSerializerImpl(inAllocator) {} virtual PxRepXObject fileToObject(XmlReader& inReader, XmlMemoryAllocator& inAllocator, PxRepXInstantiationArgs& inArgs, PxCollection* inCollection); @@ -55,13 +55,13 @@ namespace physx #if PX_SUPPORT_EXTERN_TEMPLATE // explicit template instantiations declarations - extern template struct PxJointRepXSerializer; - extern template struct PxJointRepXSerializer; - extern template struct PxJointRepXSerializer; - extern template struct PxJointRepXSerializer; - extern template struct PxJointRepXSerializer; - extern template struct PxJointRepXSerializer; - extern template struct PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; + extern template struct PX_DEPRECATED PxJointRepXSerializer; #endif #if !PX_DOXYGEN diff --git a/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.cpp b/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.cpp index b4a451afa..fc5554af5 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.cpp +++ b/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.cpp @@ -176,7 +176,7 @@ namespace physx { TMemoryPoolManager theManager(mAllocator); MemoryBuffer theTempBuf( &theManager ); theTempBuf.clear(); - inArgs.cooker->cookTriangleMesh( meshDesc, theTempBuf ); + PxCookTriangleMesh( *inArgs.cooker, meshDesc, theTempBuf ); writeBuffer( inWriter, inTempBuffer, 16, theTempBuf.mBuffer, theTempBuf.mWriteOffset, "CookedData", writeDatatype ); } @@ -215,13 +215,10 @@ namespace physx { PX_ASSERT(inArgs.cooker); theTempBuf.clear(); - { - PxCookingParams params = inArgs.cooker->getParams(); - params.midphaseDesc = PxMeshMidPhase::eBVH33; - inArgs.cooker->setParams(params); - } + PxCookingParams params = *inArgs.cooker; + params.midphaseDesc = PxMeshMidPhase::eBVH33; - inArgs.cooker->cookTriangleMesh( theDesc, theTempBuf ); + PxCookTriangleMesh( params, theDesc, theTempBuf ); // theMesh = inArgs.physics.createTriangleMesh( theTempBuf ); theMesh = static_cast(inArgs.physics.createTriangleMesh( theTempBuf )); } @@ -280,7 +277,7 @@ namespace physx { TMemoryPoolManager theManager(mAllocator); MemoryBuffer theTempBuf( &theManager ); theTempBuf.clear(); - inArgs.cooker->cookTriangleMesh( meshDesc, theTempBuf ); + PxCookTriangleMesh( *inArgs.cooker, meshDesc, theTempBuf ); writeBuffer( inWriter, inTempBuffer, 16, theTempBuf.mBuffer, theTempBuf.mWriteOffset, "CookedData", writeDatatype ); } @@ -319,13 +316,10 @@ namespace physx { PX_ASSERT(inArgs.cooker); theTempBuf.clear(); - { - PxCookingParams params = inArgs.cooker->getParams(); - params.midphaseDesc = PxMeshMidPhase::eBVH34; - inArgs.cooker->setParams(params); - } + PxCookingParams params = *inArgs.cooker; + params.midphaseDesc = PxMeshMidPhase::eBVH34; - inArgs.cooker->cookTriangleMesh( theDesc, theTempBuf ); + PxCookTriangleMesh( params, theDesc, theTempBuf ); // theMesh = inArgs.physics.createTriangleMesh( theTempBuf ); theMesh = static_cast(inArgs.physics.createTriangleMesh( theTempBuf )); } @@ -368,7 +362,7 @@ namespace physx { //Now read the data... PxU32 count = 0; //ignored becaues numRows and numColumns tells the story readStridedBufferProperty( inReader, "samples", theDesc.samples, count, inAllocator); - PxHeightField* retval = inArgs.cooker->createHeightField( theDesc, inArgs.physics.getPhysicsInsertionCallback() ); + PxHeightField* retval = PxCreateHeightField( theDesc, inArgs.physics.getPhysicsInsertionCallback() ); return PxCreateRepXObject(retval); } @@ -390,7 +384,7 @@ namespace physx { theDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX; TMemoryPoolManager theManager(mAllocator); MemoryBuffer theTempBuf( &theManager ); - inArgs.cooker->cookConvexMesh( theDesc, theTempBuf ); + PxCookConvexMesh( *inArgs.cooker, theDesc, theTempBuf ); writeBuffer( inWriter, inTempBuffer, 16, theTempBuf.mBuffer, theTempBuf.mWriteOffset, "CookedData", writeDatatype ); } @@ -425,7 +419,7 @@ namespace physx { PX_ASSERT(inArgs.cooker); theTempBuf.clear(); - inArgs.cooker->cookConvexMesh( theDesc, theTempBuf ); + PxCookConvexMesh( *inArgs.cooker, theDesc, theTempBuf ); theMesh = inArgs.physics.createConvexMesh( theTempBuf ); } diff --git a/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.h b/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.h index e28217afa..6a80bf136 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.h +++ b/physx/source/physxextensions/src/serialization/Xml/SnRepXCoreSerializer.h @@ -43,27 +43,27 @@ namespace physx class XmlWriter; class MemoryBuffer; - struct PxMaterialRepXSerializer : RepXSerializerImpl + struct PX_DEPRECATED PxMaterialRepXSerializer : RepXSerializerImpl { PxMaterialRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual PxMaterial* allocateObject( PxRepXInstantiationArgs& ); }; - struct PxShapeRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxShapeRepXSerializer : public RepXSerializerImpl { PxShapeRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); virtual PxShape* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } }; - struct PxBVH33TriangleMeshRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxBVH33TriangleMeshRepXSerializer : public RepXSerializerImpl { PxBVH33TriangleMeshRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual void objectToFileImpl( const PxBVH33TriangleMesh*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); virtual PxRepXObject fileToObject( XmlReader&, XmlMemoryAllocator&, PxRepXInstantiationArgs&, PxCollection* ); virtual PxBVH33TriangleMesh* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } }; - struct PxBVH34TriangleMeshRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxBVH34TriangleMeshRepXSerializer : public RepXSerializerImpl { PxBVH34TriangleMeshRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual void objectToFileImpl( const PxBVH34TriangleMesh*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); @@ -71,7 +71,7 @@ namespace physx virtual PxBVH34TriangleMesh* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } }; - struct PxHeightFieldRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxHeightFieldRepXSerializer : public RepXSerializerImpl { PxHeightFieldRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual void objectToFileImpl( const PxHeightField*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); @@ -79,7 +79,7 @@ namespace physx virtual PxHeightField* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } }; - struct PxConvexMeshRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxConvexMeshRepXSerializer : public RepXSerializerImpl { PxConvexMeshRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual void objectToFileImpl( const PxConvexMesh*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs& ); @@ -87,27 +87,27 @@ namespace physx virtual PxConvexMesh* allocateObject( PxRepXInstantiationArgs& ) { return NULL; } }; - struct PxRigidStaticRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxRigidStaticRepXSerializer : public RepXSerializerImpl { PxRigidStaticRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual PxRigidStatic* allocateObject( PxRepXInstantiationArgs& ); }; - struct PxRigidDynamicRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxRigidDynamicRepXSerializer : public RepXSerializerImpl { PxRigidDynamicRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual PxRigidDynamic* allocateObject( PxRepXInstantiationArgs& ); }; - struct PxArticulationReducedCoordinateRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxArticulationReducedCoordinateRepXSerializer : public RepXSerializerImpl { PxArticulationReducedCoordinateRepXSerializer(PxAllocatorCallback& inCallback) : RepXSerializerImpl(inCallback) {} virtual void objectToFileImpl(const PxArticulationReducedCoordinate*, PxCollection*, XmlWriter&, MemoryBuffer&, PxRepXInstantiationArgs&); virtual PxArticulationReducedCoordinate* allocateObject(PxRepXInstantiationArgs&); }; - struct PxAggregateRepXSerializer : public RepXSerializerImpl + struct PX_DEPRECATED PxAggregateRepXSerializer : public RepXSerializerImpl { PxAggregateRepXSerializer( PxAllocatorCallback& inCallback ) : RepXSerializerImpl( inCallback ) {} virtual void objectToFileImpl( const PxAggregate*, PxCollection*, XmlWriter& , MemoryBuffer&, PxRepXInstantiationArgs& ); diff --git a/physx/source/physxextensions/src/serialization/Xml/SnXmlMemoryAllocator.h b/physx/source/physxextensions/src/serialization/Xml/SnXmlMemoryAllocator.h index a05db28cf..e7885ca43 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnXmlMemoryAllocator.h +++ b/physx/source/physxextensions/src/serialization/Xml/SnXmlMemoryAllocator.h @@ -33,7 +33,7 @@ namespace physx { - class XmlMemoryAllocator + class PX_DEPRECATED XmlMemoryAllocator { protected: virtual ~XmlMemoryAllocator(){} @@ -98,7 +98,7 @@ namespace physx { } }; - struct XmlMemoryAllocatorImpl : public XmlMemoryAllocator + struct PX_DEPRECATED XmlMemoryAllocatorImpl : public XmlMemoryAllocator { Sn::TMemoryPoolManager mManager; diff --git a/physx/source/physxextensions/src/serialization/Xml/SnXmlSerialization.cpp b/physx/source/physxextensions/src/serialization/Xml/SnXmlSerialization.cpp index a5344a13b..8814df1df 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnXmlSerialization.cpp +++ b/physx/source/physxextensions/src/serialization/Xml/SnXmlSerialization.cpp @@ -728,7 +728,7 @@ namespace physx { namespace Sn { } } - bool PxSerialization::serializeCollectionToXml( PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, PxCooking* cooking, const PxCollection* externalRefs, PxXmlMiscParameter* inArgs ) + bool PxSerialization::serializeCollectionToXml( PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, const PxCookingParams* params, const PxCollection* externalRefs, PxXmlMiscParameter* inArgs ) { if( !PxSerialization::isSerializable(collection, sr, const_cast(externalRefs)) ) return false; @@ -736,7 +736,7 @@ namespace physx { namespace Sn { bool bRet = true; SerializationRegistry& sn = static_cast(sr); - PxRepXInstantiationArgs args( sn.getPhysics(), cooking ); + PxRepXInstantiationArgs args( sn.getPhysics(), params ); PxCollection* tmpCollection = PxCreateCollection(); PX_ASSERT(tmpCollection); @@ -794,7 +794,7 @@ namespace physx { namespace Sn { return bRet; } - PxCollection* PxSerialization::createCollectionFromXml(PxInputData& inputData, PxCooking& cooking, PxSerializationRegistry& sr, const PxCollection* externalRefs, PxStringTable* stringTable, PxXmlMiscParameter* outArgs) + PxCollection* PxSerialization::createCollectionFromXml(PxInputData& inputData, const PxCookingParams& params, PxSerializationRegistry& sr, const PxCollection* externalRefs, PxStringTable* stringTable, PxXmlMiscParameter* outArgs) { SerializationRegistry& sn = static_cast(sr); PxCollection* collection = PxCreateCollection(); @@ -807,7 +807,7 @@ namespace physx { namespace Sn { Sn::RepXCollection* theRepXCollection = Sn::create(sn, inputData, allocator, *collection); theRepXCollection = &Sn::RepXUpgrader::upgradeCollection( *theRepXCollection ); - PxRepXInstantiationArgs args( sn.getPhysics(), &cooking, stringTable ); + PxRepXInstantiationArgs args( sn.getPhysics(), ¶ms, stringTable ); if( !theRepXCollection->instantiateCollection(args, *collection) ) { collection->release(); diff --git a/physx/source/physxextensions/src/serialization/Xml/SnXmlVisitorWriter.h b/physx/source/physxextensions/src/serialization/Xml/SnXmlVisitorWriter.h index 643f1ad87..2489b2953 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnXmlVisitorWriter.h +++ b/physx/source/physxextensions/src/serialization/Xml/SnXmlVisitorWriter.h @@ -748,7 +748,7 @@ namespace physx { namespace Sn { void handleGeomProperty( const PxShapeGeomProperty& inProp ) { - switch( mObj->getGeometryType() ) + switch( mObj->getGeometry().getType() ) { case PxGeometryType::eSPHERE: writeGeomProperty( inProp, "PxSphereGeometry" ); break; case PxGeometryType::ePLANE: writeGeomProperty( inProp, "PxPlaneGeometry" ); break; diff --git a/physx/source/physxextensions/src/serialization/Xml/SnXmlWriter.h b/physx/source/physxextensions/src/serialization/Xml/SnXmlWriter.h index b6a0cf15c..0a5cce26b 100644 --- a/physx/source/physxextensions/src/serialization/Xml/SnXmlWriter.h +++ b/physx/source/physxextensions/src/serialization/Xml/SnXmlWriter.h @@ -38,7 +38,7 @@ namespace physx { /** * Writer used by extensions to write elements to a file or database */ - class XmlWriter + class PX_DEPRECATED XmlWriter { protected: virtual ~XmlWriter(){} diff --git a/physx/source/physxextensions/src/tet/ExtDelaunayBoundaryInserter.cpp b/physx/source/physxextensions/src/tet/ExtDelaunayBoundaryInserter.cpp index 672967bd0..1e861719d 100644 --- a/physx/source/physxextensions/src/tet/ExtDelaunayBoundaryInserter.cpp +++ b/physx/source/physxextensions/src/tet/ExtDelaunayBoundaryInserter.cpp @@ -64,7 +64,7 @@ namespace Ext //Returns a value proportional to the signed volume of the tetrahedron specified by the points a, b, c and d //Usualy only the result's sign is used in algorithms checking for intersections etc. - PX_FORCE_INLINE PxF64 orient3D(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d) + PX_FORCE_INLINE PxF64 orient3D(const PxVec3d& a, const PxVec3d& b, const PxVec3d& c, const PxVec3d& d) { return (a - d).dot((b - d).cross(c - d)); } @@ -78,15 +78,15 @@ namespace Ext return -1.0; } - PX_FORCE_INLINE PxF64 signedDistancePointPlane(const Vec3& point, const Vec3& normal, PxF64 planeD) + PX_FORCE_INLINE PxF64 signedDistancePointPlane(const PxVec3d& point, const PxVec3d& normal, PxF64 planeD) { return point.dot(normal) + planeD; } - PX_FORCE_INLINE bool lineSegmentIntersectsTriangle(const Vec3& segmentStart, const Vec3& segmentEnd, - const Vec3& triA, const Vec3& triB, const Vec3& triC, Vec3& intersectionPoint) + PX_FORCE_INLINE bool lineSegmentIntersectsTriangle(const PxVec3d& segmentStart, const PxVec3d& segmentEnd, + const PxVec3d& triA, const PxVec3d& triB, const PxVec3d& triC, PxVec3d& intersectionPoint) { - Vec3 n = (triB - triA).cross(triC - triA); + PxVec3d n = (triB - triA).cross(triC - triA); PxF64 l2 = n.magnitudeSquared(); if (l2 < 1e-12) @@ -135,7 +135,7 @@ namespace Ext { private: const PxArray& triangles; - PxArray& points; + PxArray& points; PxHashMap& edgesToSplit; PxArray>& pointToOriginalTriangle; @@ -147,7 +147,7 @@ namespace Ext bool repeat = false; public: - PX_FORCE_INLINE IntersectionFixingTraversalController(const PxArray& triangles_, PxArray& points_, + PX_FORCE_INLINE IntersectionFixingTraversalController(const PxArray& triangles_, PxArray& points_, PxHashMap& edgesToSplit_, PxArray>& pointToOriginalTriangle_) : triangles(triangles_), points(points_), edgesToSplit(edgesToSplit_), pointToOriginalTriangle(pointToOriginalTriangle_) { } @@ -161,8 +161,8 @@ namespace Ext a = PxI32(e >> 32); b = PxI32(e); - const Vec3& pA = points[a]; - const Vec3& pB = points[b]; + const PxVec3d& pA = points[a]; + const PxVec3d& pB = points[b]; box = PxBounds3(PxVec3(PxF32(PxMin(pA.x, pB.x)), PxF32(PxMin(pA.y, pB.y)), PxF32(PxMin(pA.z, pB.z))), PxVec3(PxF32(PxMax(pA.x, pB.x)), PxF32(PxMax(pA.y, pB.y)), PxF32(PxMax(pA.z, pB.z)))); } @@ -175,11 +175,11 @@ namespace Ext if (!contains(pointToOriginalTriangle[a], PxI32(j)) && !contains(pointToOriginalTriangle[b], PxI32(j))) { const Triangle& tri = triangles[j]; - const Vec3& triA = points[tri[0]]; - const Vec3& triB = points[tri[1]]; - const Vec3& triC = points[tri[2]]; + const PxVec3d& triA = points[tri[0]]; + const PxVec3d& triB = points[tri[1]]; + const PxVec3d& triC = points[tri[2]]; - Vec3 intersectionPoint; + PxVec3d intersectionPoint; if (lineSegmentIntersectsTriangle(points[a], points[b], triA, triB, triC, intersectionPoint)) { if (edgesToSplit.find(edge) == NULL) @@ -214,14 +214,14 @@ namespace Ext #pragma GCC diagnostic ignored "-Wmisleading-indentation" #endif - void minMax(const PxArray& points, Vec3& min, Vec3& max) + void minMax(const PxArray& points, PxVec3d& min, PxVec3d& max) { - min = Vec3(DBL_MAX, DBL_MAX, DBL_MAX); - max = Vec3(-DBL_MAX, -DBL_MAX, -DBL_MAX); + min = PxVec3d(DBL_MAX, DBL_MAX, DBL_MAX); + max = PxVec3d(-DBL_MAX, -DBL_MAX, -DBL_MAX); for (PxU32 i = 0; i < points.size(); ++i) { - const Vec3& p = points[i]; + const PxVec3d& p = points[i]; if (!PxIsFinite(p.x) || !PxIsFinite(p.y) || !PxIsFinite(p.z)) continue; if (p.x > max.x) max.x = p.x; if (p.y > max.y) max.y = p.y; if (p.z > max.z) max.z = p.z; @@ -234,9 +234,9 @@ namespace Ext #endif //Creates a delaunay tetrahedralization out of the specified points - void generateDelaunay3D(const PxArray& points, PxArray& tetrahedra) + void generateDelaunay3D(const PxArray& points, PxArray& tetrahedra) { - Vec3 min, max; + PxVec3d min, max; minMax(points, min, max); DelaunayTetrahedralizer delaunay(min, max); @@ -244,23 +244,23 @@ namespace Ext delaunay.insertPoints(points, 0, points.size(), tetrahedra); } - PX_FORCE_INLINE PxF64 determinant(const Vec3& col1, const Vec3& col2, const Vec3& col3) + PX_FORCE_INLINE PxF64 determinant(const PxVec3d& col1, const PxVec3d& col2, const PxVec3d& col3) { return col1.dot(col2.cross(col3)); } //Simple but slow implementation of winding numbers to determine if a point is inside a mesh or not //https://igl.ethz.ch/projects/winding-number/robust-inside-outside-segmentation-using-generalized-winding-numbers-siggraph-2013-jacobson-et-al.pdf - PxF64 windingNumber(const PxArray& points, const PxArray& triangles, const Vec3& p) + PxF64 windingNumber(const PxArray& points, const PxArray& triangles, const PxVec3d& p) { PxF64 sum = 0; for (PxU32 i = 0; i < triangles.size(); i++) { const Triangle& tri = triangles[i]; - const Vec3 a = points[tri[0]] - p; - const Vec3 b = points[tri[1]] - p; - const Vec3 c = points[tri[2]] - p; + const PxVec3d a = points[tri[0]] - p; + const PxVec3d b = points[tri[1]] - p; + const PxVec3d c = points[tri[2]] - p; PxF64 la = a.magnitude(), lb = b.magnitude(), lc = c.magnitude(); PxF64 omega = atan2(determinant(a, b, c), (la * lb * lc + a.dot(b) * lc + b.dot(c) * la + c.dot(a) * lb)); sum += omega; @@ -286,8 +286,8 @@ namespace Ext }; //A memory friendly implementation to compute a full batch of winding numbers for every specified query point in testPoints - void multiWindingNumberMemoryFriendly(const PxArray& meshPoints, const PxArray& meshTriangles, - const PxArray& testPoints, PxArray& result) + void multiWindingNumberMemoryFriendly(const PxArray& meshPoints, const PxArray& meshTriangles, + const PxArray& testPoints, PxArray& result) { PxU32 l = testPoints.size(); result.resize(l); @@ -297,16 +297,16 @@ namespace Ext for (PxU32 i = 0; i < meshTriangles.size(); i++) { const Triangle& tri = meshTriangles[i]; - const Vec3 aa = meshPoints[tri[0]]; - const Vec3 bb = meshPoints[tri[1]]; - const Vec3 cc = meshPoints[tri[2]]; + const PxVec3d aa = meshPoints[tri[0]]; + const PxVec3d bb = meshPoints[tri[1]]; + const PxVec3d cc = meshPoints[tri[2]]; for (PxU32 j = 0; j < l; ++j) { - const Vec3 p = testPoints[j]; - Vec3 a = aa; - Vec3 b = bb; - Vec3 c = cc; + const PxVec3d p = testPoints[j]; + PxVec3d a = aa; + PxVec3d b = bb; + PxVec3d c = cc; a.x -= p.x; a.y -= p.y; a.z -= p.z; b.x -= p.x; b.y -= p.y; b.z -= p.z; c.x -= p.x; c.y -= p.y; c.z -= p.z; @@ -332,15 +332,15 @@ namespace Ext //Generates a tetmesh matching the surface of the specified triangle mesh exactly - might insert additional points on the //triangle mesh's surface. I also provides access about the location of newly created points. - void generateTetmesh(const PxArray& trianglePoints, const PxArray& triangles, + void generateTetmesh(const PxArray& trianglePoints, const PxArray& triangles, PxArray& allEdges, PxI32& numOriginalEdges, PxArray>& pointToOriginalTriangle, - PxI32& numPointsBelongingToMultipleTriangles, PxArray& points, PxArray& finalTets) + PxI32& numPointsBelongingToMultipleTriangles, PxArray& points, PxArray& finalTets) { points.resize(trianglePoints.size()); for (PxU32 i = 0; i < trianglePoints.size(); ++i) points[i] = trianglePoints[i]; - Vec3 min, max; + PxVec3d min, max; minMax(points, min, max); PxHashSet edges; @@ -465,7 +465,7 @@ namespace Ext for (PxU32 i = 0; i < tets.size(); ++i) { const Tetrahedron& tet = tets[i]; - Vec3 q = (points[tet[0]] + points[tet[1]] + points[tet[2]] + points[tet[3]]) * 0.25; + PxVec3d q = (points[tet[0]] + points[tet[1]] + points[tet[2]] + points[tet[3]]) * 0.25; PxF64 windingNumber = computeWindingNumber(tree, q, 2.0, clusters, triangles, points); windingNumbers[i] = windingNumber; @@ -474,7 +474,7 @@ namespace Ext if (windingNumberSum < 0.0) sign = -1; - //Array tetCenters; + //Array tetCenters; //tetCenters.resize(tets.size()); //for (PxU32 i = 0; i < tets.size(); ++i) //{ @@ -496,8 +496,8 @@ namespace Ext } } - void generateTetmesh(const PxArray& trianglePoints, const PxArray& triangles, - PxArray& points, PxArray& finalTets) + void generateTetmesh(const PxArray& trianglePoints, const PxArray& triangles, + PxArray& points, PxArray& finalTets) { PxArray allEdges; PxI32 numOriginalEdges; @@ -580,7 +580,7 @@ namespace Ext } //Removes vertices not referenced by any tetrahedron and maps the tet's indices to match the compacted vertex list - void removeUnusedVertices(PxArray& vertices, PxArray& tets, PxU32 numPointsToKeepAtBeginning = 0) + void removeUnusedVertices(PxArray& vertices, PxArray& tets, PxU32 numPointsToKeepAtBeginning = 0) { PxArray compressorMap; compressorMap.resize(vertices.size()); @@ -627,14 +627,14 @@ namespace Ext vertices.removeRange(indexer, vertices.size() - indexer); } - PxF64 tetQuality(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec3& p3) + PxF64 tetQuality(const PxVec3d& p0, const PxVec3d& p1, const PxVec3d& p2, const PxVec3d& p3) { - const Vec3 d0 = p1 - p0; - const Vec3 d1 = p2 - p0; - const Vec3 d2 = p3 - p0; - const Vec3 d3 = p2 - p1; - const Vec3 d4 = p3 - p2; - const Vec3 d5 = p1 - p3; + const PxVec3d d0 = p1 - p0; + const PxVec3d d1 = p2 - p0; + const PxVec3d d2 = p3 - p0; + const PxVec3d d3 = p2 - p1; + const PxVec3d d4 = p3 - p2; + const PxVec3d d5 = p1 - p3; PxF64 s0 = d0.magnitudeSquared(); PxF64 s1 = d1.magnitudeSquared(); @@ -658,7 +658,7 @@ namespace Ext return tet[0] + tet[1] + tet[2] + tet[3] - faceA - faceB - faceC; } - void improveTetmesh(PxArray& points, PxArray& finalTets, PxI32 numPointsBelongingToMultipleTriangles, + void improveTetmesh(PxArray& points, PxArray& finalTets, PxI32 numPointsBelongingToMultipleTriangles, PxArray>& pointToOriginalTriangle, PxArray>& edges, PxI32 numOriginalPoints) { DelaunayTetrahedralizer del(points, finalTets); @@ -749,10 +749,10 @@ namespace Ext continue; PxI32 other = getTetCornerOppositeToFace(tet, link.triA, link.triB, link.triC); - const Vec3& a = points[link.triA]; - const Vec3& b = points[link.triB]; - const Vec3& c = points[link.triC]; - Vec3 n = (b - a).cross(c - a); + const PxVec3d& a = points[link.triA]; + const PxVec3d& b = points[link.triB]; + const PxVec3d& c = points[link.triC]; + PxVec3d n = (b - a).cross(c - a); //n.normalize(); PxF64 planeD = -(n.dot(a)); @@ -868,8 +868,8 @@ namespace Ext //Generates a tetmesh matching the surface of the specified triangle mesh exactly - might insert additional points on the //triangle mesh's surface. It will try to remove as many points inserted during construction as possible by applying an //edge collapse post processing step. - void generateTetsWithCollapse(const PxArray& trianglePoints, const PxArray& triangles, - PxArray& points, PxArray& finalTets) + void generateTetsWithCollapse(const PxArray& trianglePoints, const PxArray& triangles, + PxArray& points, PxArray& finalTets) { const PxI32 numOriginalPoints = PxI32(trianglePoints.size()); @@ -880,7 +880,7 @@ namespace Ext PxArray> edges; - Vec3 min, max; + PxVec3d min, max; minMax(trianglePoints, min, max); DelaunayTetrahedralizer del(min, max); PxArray tets; @@ -938,7 +938,7 @@ namespace Ext for (PxU32 i = 0; i < tets.size(); ++i) { const Tetrahedron& tet = tets[i]; - Vec3 q = (points[tet[0]] + points[tet[1]] + points[tet[2]] + points[tet[3]]) * 0.25; + PxVec3d q = (points[tet[0]] + points[tet[1]] + points[tet[2]] + points[tet[3]]) * 0.25; PxF64 windingNumber = computeWindingNumber(tree, q, 2.0, clusters, triangles, points); windingNumbers[i] = windingNumber; windingNumberSum += windingNumber; @@ -961,13 +961,13 @@ namespace Ext improveTetmesh(points, finalTets, numPointsBelongingToMultipleTriangles, pointToOriginalTriangle, edges, numOriginalPoints); } - bool convexTetmesh(PxArray& points, const PxArray& tris, PxArray& tets) + bool convexTetmesh(PxArray& points, const PxArray& tris, PxArray& tets) { - Vec3 centroid = Vec3(0.0f, 0.0f, 0.0f); + PxVec3d centroid = PxVec3d(0.0, 0.0, 0.0); PxI32 counter = 0; for (PxU32 i = 0; i < points.size(); ++i) { - const Vec3& p = points[i]; + const PxVec3d& p = points[i]; if (!PxIsFinite(p.x) || !PxIsFinite(p.y) || !PxIsFinite(p.z)) continue; centroid += p; @@ -1007,42 +1007,42 @@ namespace Ext return true; } - void convert(const PxArray& points, PxArray& result) + void convert(const PxArray& points, PxArray& result) { result.resize(points.size() / 3); for (PxU32 i = 0; i < result.size(); ++i) - result[i] = Vec3(points[3 * i], points[3 * i + 1], points[3 * i + 2]); + result[i] = PxVec3d(PxF64(points[3 * i]), PxF64(points[3 * i + 1]), PxF64(points[3 * i + 2])); } - void convert(const PxArray& points, PxArray& result) + void convert(const PxArray& points, PxArray& result) { result.resize(3 * points.size()); for (PxU32 i = 0; i < points.size(); ++i) { - const Vec3& p = points[i]; + const PxVec3d& p = points[i]; result[3 * i] = PxF32(p.x); result[3 * i + 1] = PxF32(p.y); result[3 * i + 2] = PxF32(p.z); } } - void convert(const PxArray& points, PxArray& result) + void convert(const PxArray& points, PxArray& result) { result.resize(points.size()); for (PxU32 i = 0; i < points.size(); ++i) { - const Vec3& p = points[i]; + const PxVec3d& p = points[i]; result[i] = PxVec3(PxF32(p.x), PxF32(p.y), PxF32(p.z)); } } - void convert(const PxBoundedData& points, PxArray& result) + void convert(const PxBoundedData& points, PxArray& result) { result.resize(points.count); for (PxU32 i = 0; i < points.count; ++i) { const PxVec3& p = points.at(i); - result[i] = Vec3(p.x, p.y, p.z); + result[i] = PxVec3d(PxF64(p.x), PxF64(p.y), PxF64(p.z)); } } @@ -1143,7 +1143,7 @@ namespace Ext for (PxU32 i = 0; i < tris.size(); i += 3) { - const PxI32* tri = &tris[3 * i]; + const PxI32* tri = &tris[i]; const PxVec3& a = vertices[tri[0]]; const PxVec3& b = vertices[tri[1]]; const PxVec3& c = vertices[tri[2]]; @@ -1170,7 +1170,7 @@ namespace Ext { //writeOFF("c:\\tmp\\debug.off", trianglePoints, triangles); - PxArray points; + PxArray points; convert(inputPoints, points); PxArray tris; convert(inputTriangles, has16bitIndices, tris); @@ -1179,11 +1179,11 @@ namespace Ext //PX_ASSERT(!(result & PxTriangleMeshAnalysisResult::eMESH_IS_INVALID)); PxArray map; - MeshAnalyzer::mapDuplicatePoints(points, map); + MeshAnalyzer::mapDuplicatePoints(points.begin(), points.size(), map); for (PxI32 i = 0; i < PxI32(points.size()); ++i) { if(map[i] != i) - points[i] = Vec3(NAN, NAN, NAN); + points[i] = PxVec3d(PxF64(NAN), PxF64(NAN), PxF64(NAN)); } for (PxU32 i = 0; i < tris.size(); ++i) { @@ -1198,7 +1198,7 @@ namespace Ext } } - PxArray tetPts; + PxArray tetPts; PxArray tets; //if (makeTriOrientationConsistent(tris)) { @@ -1218,9 +1218,9 @@ namespace Ext else { //Transform points such that the are located inside the unit cube - Vec3 min, max; + PxVec3d min, max; minMax(points, min, max); - Vec3 size = max - min; + PxVec3d size = max - min; PxF64 scaling = 1.0 / PxMax(size.x, PxMax(size.y, size.z)); //Add some noise to avoid geometric degeneracies @@ -1228,7 +1228,7 @@ namespace Ext PxF64 randomMagnitude = 1e-6; for (PxU32 i = 0; i < points.size(); ++i) { - Vec3& p = points[i]; + PxVec3d& p = points[i]; p = (p - min) * scaling; p.x += PxF64(r.rand(-0.5f, 0.5f)) * randomMagnitude; p.y += PxF64(r.rand(-0.5f, 0.5f)) * randomMagnitude; @@ -1240,7 +1240,7 @@ namespace Ext //Scale back to original size scaling = 1.0 / scaling; //for (PxU32 i = 0; i < l; ++i) - // tetPts[i] = Vec3(trianglePoints[3 * i], trianglePoints[3 * i + 1], trianglePoints[3 * i + 2]); + // tetPts[i] = PxVec3d(trianglePoints[3 * i], trianglePoints[3 * i + 1], trianglePoints[3 * i + 2]); for (PxU32 i = 0; i < map.size(); ++i) { tetPts[i] = tetPts[map[i]]; @@ -2120,7 +2120,8 @@ namespace Ext { PxArray flip; PxHashMap edges; - if (!MeshAnalyzer::checkConsistentTriangleOrientation(triangles.begin(), triangles.size(), flip, edges)) + PxArray> connectedTriangleGroups; + if (!MeshAnalyzer::buildConsistentTriangleOrientationMap(triangles.begin(), triangles.size(), flip, edges, connectedTriangleGroups)) return PxTriangleMeshAnalysisResult::Enum::eEDGE_SHARED_BY_MORE_THAN_TWO_TRIANGLES; PxTriangleMeshAnalysisResults result = PxTriangleMeshAnalysisResult::eVALID; @@ -2296,7 +2297,7 @@ namespace Ext PxArray map; - MeshAnalyzer::mapDuplicatePoints(normalizedPoints, map); + MeshAnalyzer::mapDuplicatePoints(normalizedPoints.begin(), normalizedPoints.size(), map); PxArray mappedTriangles; mappedTriangles.reserve(triangles.count); for (PxU32 i = 0; i < triangles.count; ++i) diff --git a/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.cpp b/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.cpp index cdecc07f8..1a8e52645 100644 --- a/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.cpp +++ b/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.cpp @@ -43,18 +43,18 @@ namespace Ext struct Plane { - Vec3 normal; + PxVec3d normal; PxF64 planeD; - PX_FORCE_INLINE Plane(const Vec3& n, PxF64 d) : normal(n), planeD(d) + PX_FORCE_INLINE Plane(const PxVec3d& n, PxF64 d) : normal(n), planeD(d) { } - PX_FORCE_INLINE Plane(const Vec3& n, const Vec3& pointOnPlane) : normal(n) + PX_FORCE_INLINE Plane(const PxVec3d& n, const PxVec3d& pointOnPlane) : normal(n) { planeD = -pointOnPlane.dot(normal); } - PX_FORCE_INLINE Plane(const Vec3& a, const Vec3& b, const Vec3& c) + PX_FORCE_INLINE Plane(const PxVec3d& a, const PxVec3d& b, const PxVec3d& c) { normal = (b - a).cross(c - a); PxF64 norm = normal.magnitude(); @@ -63,18 +63,18 @@ namespace Ext planeD = -a.dot(normal); } - PX_FORCE_INLINE PxF64 signedDistance(const Vec3& p) + PX_FORCE_INLINE PxF64 signedDistance(const PxVec3d& p) { return normal.dot(p) + planeD; } - PX_FORCE_INLINE PxF64 unsignedDistance(const Vec3& p) + PX_FORCE_INLINE PxF64 unsignedDistance(const PxVec3d& p) { return PxAbs(signedDistance(p)); } }; - DelaunayTetrahedralizer::DelaunayTetrahedralizer(const Vec3& min, const Vec3& max) + DelaunayTetrahedralizer::DelaunayTetrahedralizer(const PxVec3d& min, const PxVec3d& max) { for(PxI32 i = 0; i < 4; ++i) neighbors.pushBack(-1); @@ -82,10 +82,10 @@ namespace Ext PxF64 radius = 1.1 * 0.5 * (max - min).magnitude(); PxF64 scaledRadius = 6 * radius; - centeredNormalizedPoints.pushBack(Vec3(-scaledRadius, -scaledRadius, -scaledRadius)); - centeredNormalizedPoints.pushBack(Vec3(scaledRadius, scaledRadius, -scaledRadius)); - centeredNormalizedPoints.pushBack(Vec3(-scaledRadius, scaledRadius, scaledRadius)); - centeredNormalizedPoints.pushBack(Vec3(scaledRadius, -scaledRadius, scaledRadius)); + centeredNormalizedPoints.pushBack(PxVec3d(-scaledRadius, -scaledRadius, -scaledRadius)); + centeredNormalizedPoints.pushBack(PxVec3d(scaledRadius, scaledRadius, -scaledRadius)); + centeredNormalizedPoints.pushBack(PxVec3d(-scaledRadius, scaledRadius, scaledRadius)); + centeredNormalizedPoints.pushBack(PxVec3d(scaledRadius, -scaledRadius, scaledRadius)); numAdditionalPointsAtBeginning = 4; @@ -210,12 +210,12 @@ namespace Ext } } - DelaunayTetrahedralizer::DelaunayTetrahedralizer(PxArray& points, PxArray& tets) + DelaunayTetrahedralizer::DelaunayTetrahedralizer(PxArray& points, PxArray& tets) { initialize(points, tets); } - void DelaunayTetrahedralizer::initialize(PxArray& points, PxArray& tets) + void DelaunayTetrahedralizer::initialize(PxArray& points, PxArray& tets) { clearLockedEdges(); clearLockedTriangles(); @@ -233,7 +233,7 @@ namespace Ext unusedTets.pushBack(i); } - PX_FORCE_INLINE PxF64 inSphere(const Vec3& pa, const Vec3& pb, const Vec3& pc, const Vec3& pd, const Vec3& candidiate) + PX_FORCE_INLINE PxF64 inSphere(const PxVec3d& pa, const PxVec3d& pb, const PxVec3d& pc, const PxVec3d& pd, const PxVec3d& candidiate) { PxF64 aex = pa.x - candidiate.x; PxF64 bex = pb.x - candidiate.x; @@ -269,7 +269,7 @@ namespace Ext return (dlift * abc - clift * dab) + (blift * cda - alift * bcd); } - PX_FORCE_INLINE bool isDelaunay(const PxArray& points, const PxArray& tets, const PxArray& neighbors, PxI32 faceId) + PX_FORCE_INLINE bool isDelaunay(const PxArray& points, const PxArray& tets, const PxArray& neighbors, PxI32 faceId) { PxI32 neighborPointer = neighbors[faceId]; if (neighborPointer < 0) @@ -484,7 +484,7 @@ namespace Ext return true; } - PX_FORCE_INLINE PxF64 orient3D(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d) + PX_FORCE_INLINE PxF64 orient3D(const PxVec3d& a, const PxVec3d& b, const PxVec3d& c, const PxVec3d& d) { return (a - d).dot((b - d).cross(c - d)); } @@ -499,7 +499,7 @@ namespace Ext return lockedTriangles.contains(SortedTriangle(triA, triB, triC)); } - void flip(const PxArray& points, PxArray& tets, PxArray& neighbors, PxArray& vertexToTet, PxI32 faceId, PxArray& unusedTets, PxArray& affectedFaces, + void flip(const PxArray& points, PxArray& tets, PxArray& neighbors, PxArray& vertexToTet, PxI32 faceId, PxArray& unusedTets, PxArray& affectedFaces, const PxHashSet& lockedFaces, const PxHashSet& lockedEdges) { PxI32 neighborPointer = neighbors[faceId]; @@ -561,7 +561,7 @@ namespace Ext } } - void flip(PxArray& faces, PxArray& neighbors, PxArray& vertexToTet, const PxArray& points, + void flip(PxArray& faces, PxArray& neighbors, PxArray& vertexToTet, const PxArray& points, PxArray& tets, PxArray& unusedTets, PxArray& affectedFaces, const PxHashSet& lockedFaces, const PxHashSet& lockedEdges) { @@ -583,7 +583,7 @@ namespace Ext } } - void insertAndFlip(PxI32 pointToInsert, PxI32 tetId, PxArray& neighbors, PxArray& vertexToTet, const PxArray& points, + void insertAndFlip(PxI32 pointToInsert, PxI32 tetId, PxArray& neighbors, PxArray& vertexToTet, const PxArray& points, PxArray& tets, PxArray& unusedTets, PxArray& affectedFaces, const PxHashSet& lockedFaces, const PxHashSet& lockedEdges) { @@ -597,7 +597,7 @@ namespace Ext flip(stack, neighbors, vertexToTet, points, tets, unusedTets, affectedFaces, lockedFaces, lockedEdges); } - PxI32 searchAll(const Vec3& p, const PxArray& tets, const PxArray& points) + PxI32 searchAll(const PxVec3d& p, const PxArray& tets, const PxArray& points) { for (PxU32 i = 0; i < tets.size(); ++i) { @@ -619,7 +619,7 @@ namespace Ext return -1; } - bool runDelaunay(const PxArray& points, PxI32 start, PxI32 end, PxArray& tets, PxArray& neighbors, PxArray& vertexToTet, PxArray& unusedTets, + bool runDelaunay(const PxArray& points, PxI32 start, PxI32 end, PxArray& tets, PxArray& neighbors, PxArray& vertexToTet, PxArray& unusedTets, const PxHashSet& lockedFaces, const PxHashSet& lockedEdges) { PxI32 tetId = 0; @@ -627,7 +627,7 @@ namespace Ext PxArray affectedFaces; for (PxI32 i = start; i < end; ++i) { - const Vec3 p = points[i]; + const PxVec3d p = points[i]; if (!PxIsFinite(p.x) || !PxIsFinite(p.y) || !PxIsFinite(p.z)) continue; @@ -642,7 +642,7 @@ namespace Ext while (!tetLocated) { const Tetrahedron& tet = tets[tetId]; - const Vec3 center = (points[tet[0]] + points[tet[1]] + points[tet[2]] + points[tet[3]]) * 0.25; + const PxVec3d center = (points[tet[0]] + points[tet[1]] + points[tet[2]] + points[tet[3]]) * 0.25; PxF64 minDist = DBL_MAX; PxI32 minFaceNr = -1; @@ -689,7 +689,7 @@ namespace Ext return true; } - bool DelaunayTetrahedralizer::insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end) + bool DelaunayTetrahedralizer::insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end) { for (PxI32 i = start; i < end; ++i) { @@ -713,7 +713,7 @@ namespace Ext } } - void DelaunayTetrahedralizer::insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end, PxArray& tetrahedra) + void DelaunayTetrahedralizer::insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end, PxArray& tetrahedra) { insertPoints(inPoints, start, end); exportTetrahedra(tetrahedra); @@ -722,7 +722,7 @@ namespace Ext //Code below this line is for tetmesh manipulation and not directly required to generate a Delaunay tetrahedron mesh. It is used to impmrove the quality of a tetrahedral mesh. //https://cs.nyu.edu/~panozzo/papers/SLIM-2016.pdf - PxF64 evaluateAmipsEnergyPow3(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d) + PxF64 evaluateAmipsEnergyPow3(const PxVec3d& a, const PxVec3d& b, const PxVec3d& c, const PxVec3d& d) { PxF64 x1 = a.x + d.x - 2.0 * b.x; PxF64 x2 = a.x + b.x + d.x - 3.0 * c.x; @@ -761,12 +761,12 @@ namespace Ext return PxF64(PxPow(PxF32(a), PxF32(b))); } - PX_FORCE_INLINE PxF64 evaluateAmipsEnergy(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d) + PX_FORCE_INLINE PxF64 evaluateAmipsEnergy(const PxVec3d& a, const PxVec3d& b, const PxVec3d& c, const PxVec3d& d) { return pow(evaluateAmipsEnergyPow3(a, b, c, d), 1.0 / 3.0); } - PxF64 maxEnergyPow3(const PxArray& points, const PxArray& tets) + PxF64 maxEnergyPow3(const PxArray& points, const PxArray& tets) { PxF64 maxEnergy = 0; for (PxU32 i = 0; i < tets.size(); ++i) @@ -781,12 +781,12 @@ namespace Ext return maxEnergy; } - PX_FORCE_INLINE PxF64 maxEnergy(const PxArray& points, const PxArray& tets) + PX_FORCE_INLINE PxF64 maxEnergy(const PxArray& points, const PxArray& tets) { return pow(maxEnergyPow3(points, tets), 1.0 / 3.0); } - PxF64 maxEnergyPow3(const PxArray& points, const PxArray& tets, const PxArray& tetIds) + PxF64 maxEnergyPow3(const PxArray& points, const PxArray& tets, const PxArray& tetIds) { PxF64 maxEnergy = 0; for (PxU32 i = 0; i < tetIds.size(); ++i) @@ -801,7 +801,7 @@ namespace Ext return maxEnergy; } - PxF64 minAbsTetVolume(const PxArray& points, const PxArray& tets) + PxF64 minAbsTetVolume(const PxArray& points, const PxArray& tets) { PxF64 minVol = DBL_MAX; for (PxU32 i = 0; i < tets.size(); ++i) { @@ -815,7 +815,7 @@ namespace Ext return minVol; } - PxF64 minTetVolume(const PxArray& points, const PxArray& tets) + PxF64 minTetVolume(const PxArray& points, const PxArray& tets) { PxF64 minVol = DBL_MAX; for (PxU32 i = 0; i < tets.size(); ++i) { @@ -829,7 +829,7 @@ namespace Ext return minVol; } - PxF64 minTetVolume(const PxArray& points, const PxArray& tets, const PxArray& indices) + PxF64 minTetVolume(const PxArray& points, const PxArray& tets, const PxArray& indices) { PxF64 minVol = DBL_MAX; for (PxU32 i = 0; i < indices.size(); ++i) { @@ -1010,7 +1010,7 @@ namespace Ext } //Returns true if the volume of a tet would become negative if a vertex it contains would get replaced by another one - bool tetFlipped(const Tetrahedron& tet, PxI32 vertexToReplace, PxI32 replacement, const PxArray& points, PxF64 volumeChangeThreshold = 0.1) + bool tetFlipped(const Tetrahedron& tet, PxI32 vertexToReplace, PxI32 replacement, const PxArray& points, PxF64 volumeChangeThreshold = 0.1) { PxF64 volumeBefore = tetVolume(points[tet[0]], points[tet[1]], points[tet[2]], points[tet[3]]); @@ -1044,7 +1044,7 @@ namespace Ext } //Returns true if a tetmesh's edge, defined by vertex indices keep and remove, can be collapsed without leading to an invalid tetmesh topology - bool canCollapseEdge(PxI32 keep, PxI32 remove, const PxArray& points, + bool canCollapseEdge(PxI32 keep, PxI32 remove, const PxArray& points, const PxArray& tetsConnectedToKeepVertex, const PxArray& tetsConnectedToRemoveVertex, const PxArray& allTet, PxF64& qualityAfterCollapse, PxF64 volumeChangeThreshold = 0.1, BaseTetAnalyzer* tetAnalyzer = NULL) { @@ -1281,7 +1281,7 @@ namespace Ext } bool removeEdgeByFlip(PxI32 edgeA, PxI32 edgeB, PxArray& faces, PxHashSet& hashset, PxArray& tetIndices, - PxArray& tets, PxArray& pts, PxArray& unusedTets, PxArray& neighbors, PxArray& vertexToTet, + PxArray& tets, PxArray& pts, PxArray& unusedTets, PxArray& neighbors, PxArray& vertexToTet, BaseTetAnalyzer* qualityAnalyzer = NULL) { //validateNeighborhood(tets, neighbors); @@ -1298,8 +1298,8 @@ namespace Ext PxArray ringCopy(ring); - const Vec3& a = pts[edgeA]; - const Vec3& b = pts[edgeB]; + const PxVec3d& a = pts[edgeA]; + const PxVec3d& b = pts[edgeB]; PxArray newTets; newTets.reserve(ring.size() * 2); @@ -1310,9 +1310,9 @@ namespace Ext PxI32 id = -1; for (PxI32 i = 0; i < PxI32(ring.size()); ++i) { - const Vec3& s = pts[ring[(i - 1 + ring.size()) % ring.size()]]; - const Vec3& middle = pts[ring[i]]; - const Vec3& e = pts[ring[(i + 1) % ring.size()]]; + const PxVec3d& s = pts[ring[(i - 1 + ring.size()) % ring.size()]]; + const PxVec3d& middle = pts[ring[i]]; + const PxVec3d& e = pts[ring[(i + 1) % ring.size()]]; const PxF64 d = (s - e).magnitudeSquared(); if (d < shortestDist) { @@ -1486,7 +1486,7 @@ namespace Ext return true; } - bool previewFlip(const PxArray& points, const PxArray& tets, const PxArray& neighbors, PxI32 faceId, + bool previewFlip(const PxArray& points, const PxArray& tets, const PxArray& neighbors, PxI32 faceId, PxArray& newTets, PxArray& removedTets, const PxHashSet& lockedFaces, const PxHashSet& lockedEdges) { @@ -1662,9 +1662,9 @@ namespace Ext PX_ASSERT(false); } - void DelaunayTetrahedralizer::generateTetmeshEnforcingEdges(const PxArray& trianglePoints, const PxArray& triangles, PxArray>& allEdges, + void DelaunayTetrahedralizer::generateTetmeshEnforcingEdges(const PxArray& trianglePoints, const PxArray& triangles, PxArray>& allEdges, PxArray>& pointToOriginalTriangle, - PxArray& points, PxArray& finalTets) + PxArray& points, PxArray& finalTets) { clearLockedEdges(); clearLockedTriangles(); @@ -1727,7 +1727,7 @@ namespace Ext PxU32 i = edgeToIndex[e]; if (allEdges[i].size() < 10) { - Vec3 p = (centeredNormalizedPoints[a] + centeredNormalizedPoints[b]) * 0.5; + PxVec3d p = (centeredNormalizedPoints[a] + centeredNormalizedPoints[b]) * 0.5; points.pushBack(p); insertPoints(points, points.size() - 1, points.size()); @@ -1763,7 +1763,7 @@ namespace Ext PxI32 optimizeByFlipping(PxArray& faces, PxArray& neighbors, PxArray& vertexToTet, - const PxArray& points, PxArray& tets, PxArray& unusedTets, const BaseTetAnalyzer& qualityAnalyzer, + const PxArray& points, PxArray& tets, PxArray& unusedTets, const BaseTetAnalyzer& qualityAnalyzer, PxArray& affectedFaces, const PxHashSet& lockedFaces, const PxHashSet& lockedEdges) { @@ -1964,12 +1964,12 @@ namespace Ext return success; } - void patternSearchOptimize(PxI32 pointToModify, PxF64 step, PxArray& points, BaseTetAnalyzer& score, const PxArray& tetrahedra, PxF64 minStep) + void patternSearchOptimize(PxI32 pointToModify, PxF64 step, PxArray& points, BaseTetAnalyzer& score, const PxArray& tetrahedra, PxF64 minStep) { - const Vec3 dir[] = { Vec3(1.0, 0.0, 0.0), Vec3(-1.0, 0.0, 0.0), Vec3(0.0, 1.0, 0.0), Vec3(0.0, -1.0, 0.0), Vec3(0.0, 0.0, 1.0), Vec3(0.0, 0.0, -1.0), }; + const PxVec3d dir[] = { PxVec3d(1.0, 0.0, 0.0), PxVec3d(-1.0, 0.0, 0.0), PxVec3d(0.0, 1.0, 0.0), PxVec3d(0.0, -1.0, 0.0), PxVec3d(0.0, 0.0, 1.0), PxVec3d(0.0, 0.0, -1.0), }; const PxI32 oppositeDir[] = { 1, 0, 3, 2, 5, 4 }; PxF64 currentScore = score.quality(tetrahedra); // score(); - Vec3 p = points[pointToModify]; + PxVec3d p = points[pointToModify]; PxI32 skip = -1; PxI32 maxIter = 100; @@ -2080,7 +2080,7 @@ namespace Ext return edgesToSplit.size() > 0; } - void updateEdges(PxArray& edges, PxHashSet& tetEdges, const PxArray& tets, const PxArray& points) + void updateEdges(PxArray& edges, PxHashSet& tetEdges, const PxArray& tets, const PxArray& points) { edges.clear(); tetEdges.clear(); @@ -2106,7 +2106,7 @@ namespace Ext } void optimize(DelaunayTetrahedralizer& del, PxArray>& pointToOriginalTriangle, PxI32 numFixPoints, - PxArray& optimizedPoints, PxArray& optimizedTets, PxI32 numPasses) + PxArray& optimizedPoints, PxArray& optimizedTets, PxI32 numPasses) { PxHashSet tetEdges; PxArray edges; @@ -2116,7 +2116,7 @@ namespace Ext //MaximizeMinTetVolume qualityAnalyzer(del.points(), del.tetrahedra()); optimizedTets = PxArray(del.tetrahedra()); - optimizedPoints = PxArray(del.points()); + optimizedPoints = PxArray(del.points()); PxF64 minVolBefore = minAbsTetVolume(del.points(), del.tetrahedra()); PxF64 maxEnergyBefore = maxEnergy(del.points(), del.tetrahedra()); @@ -2165,12 +2165,12 @@ namespace Ext } optimizedTets = PxArray(del.tetrahedra()); - optimizedPoints = PxArray(del.points()); + optimizedPoints = PxArray(del.points()); return; } optimizedTets = PxArray(del.tetrahedra()); - optimizedPoints = PxArray(del.points()); + optimizedPoints = PxArray(del.points()); minVolBefore = minVol; maxEnergyBefore = energy; diff --git a/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.h b/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.h index 50246fa91..c091cff48 100644 --- a/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.h +++ b/physx/source/physxextensions/src/tet/ExtDelaunayTetrahedralizer.h @@ -45,12 +45,12 @@ namespace Ext void buildNeighborhood(const PxArray& tets, PxArray& result); void buildNeighborhood(const PxI32* tets, PxU32 numTets, PxArray& result); - PX_FORCE_INLINE PxF64 tetVolume(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d) + PX_FORCE_INLINE PxF64 tetVolume(const PxVec3d& a, const PxVec3d& b, const PxVec3d& c, const PxVec3d& d) { return (-1.0 / 6.0) * (a - d).dot((b - d).cross(c - d)); } - PX_FORCE_INLINE PxF64 tetVolume(const Tetrahedron& tet, const PxArray& points) + PX_FORCE_INLINE PxF64 tetVolume(const Tetrahedron& tet, const PxArray& points) { return tetVolume(points[tet[0]], points[tet[1]], points[tet[2]], points[tet[3]]); } @@ -107,11 +107,11 @@ namespace Ext class MinimizeMaxAmipsEnergy : public BaseTetAnalyzer { - const PxArray& points; + const PxArray& points; const PxArray& tetrahedra; public: - MinimizeMaxAmipsEnergy(const PxArray& points_, const PxArray& tetrahedra_) : points(points_), tetrahedra(tetrahedra_) + MinimizeMaxAmipsEnergy(const PxArray& points_, const PxArray& tetrahedra_) : points(points_), tetrahedra(tetrahedra_) {} PxF64 quality(const PxArray tetIndices) const; @@ -128,11 +128,11 @@ namespace Ext class MaximizeMinTetVolume : public BaseTetAnalyzer { - const PxArray& points; + const PxArray& points; const PxArray& tetrahedra; public: - MaximizeMinTetVolume(const PxArray& points_, const PxArray& tetrahedra_) : points(points_), tetrahedra(tetrahedra_) + MaximizeMinTetVolume(const PxArray& points_, const PxArray& tetrahedra_) : points(points_), tetrahedra(tetrahedra_) {} PxF64 quality(const PxArray tetIndices) const; @@ -211,18 +211,18 @@ namespace Ext { public: //The bounds specified must contain all points that will get inserted by calling insertPoints. - DelaunayTetrahedralizer(const Vec3& min, const Vec3& max); + DelaunayTetrahedralizer(const PxVec3d& min, const PxVec3d& max); - DelaunayTetrahedralizer(PxArray& points, PxArray& tets); + DelaunayTetrahedralizer(PxArray& points, PxArray& tets); - void initialize(PxArray& points, PxArray& tets); + void initialize(PxArray& points, PxArray& tets); //Inserts a bunch of new points into the tetrahedralization and keeps the delaunay condition satisfied. The new result will //get stored in the tetrahedra array. Points to insert must already be present in inPoints, the indices of the points to insert //can be controlled with start and end index (end index is exclusive, start index is inclusive) - void insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end, PxArray& tetrahedra); + void insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end, PxArray& tetrahedra); - bool insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end); + bool insertPoints(const PxArray& inPoints, PxI32 start, PxI32 end); void exportTetrahedra(PxArray& tetrahedra); @@ -240,14 +240,14 @@ namespace Ext void collectTetsConnectedToEdge(PxI32 edgeStart, PxI32 edgeEnd, PxArray& tetIds); - PX_FORCE_INLINE const Vec3& point(PxI32 index) const { return centeredNormalizedPoints[index]; } + PX_FORCE_INLINE const PxVec3d& point(PxI32 index) const { return centeredNormalizedPoints[index]; } PX_FORCE_INLINE PxU32 numPoints() const { return centeredNormalizedPoints.size(); } - PX_FORCE_INLINE PxArray& points() { return centeredNormalizedPoints; } - PX_FORCE_INLINE const PxArray& points() const { return centeredNormalizedPoints; } + PX_FORCE_INLINE PxArray& points() { return centeredNormalizedPoints; } + PX_FORCE_INLINE const PxArray& points() const { return centeredNormalizedPoints; } - PxU32 addPoint(const Vec3& p) + PxU32 addPoint(const PxVec3d& p) { centeredNormalizedPoints.pushBack(p); vertexToTet.pushBack(-1); @@ -261,7 +261,7 @@ namespace Ext PX_FORCE_INLINE PxArray& tetrahedra() { return result; } PX_FORCE_INLINE const PxArray& tetrahedra() const { return result; } - void copyInternalPointsTo(PxArray& points) { points = centeredNormalizedPoints; } + void copyInternalPointsTo(PxArray& points) { points = centeredNormalizedPoints; } bool optimizeByFlipping(PxArray& affectedFaces, const BaseTetAnalyzer& qualityAnalyzer); @@ -279,12 +279,12 @@ namespace Ext bool recoverEdgeByFlip(PxI32 eStart, PxI32 eEnd, RecoverEdgeMemoryCache& cache); - void generateTetmeshEnforcingEdges(const PxArray& trianglePoints, const PxArray>& triangles, PxArray>& allEdges, + void generateTetmeshEnforcingEdges(const PxArray& trianglePoints, const PxArray>& triangles, PxArray>& allEdges, PxArray>& pointToOriginalTriangle, - PxArray& points, PxArray& finalTets); + PxArray& points, PxArray& finalTets); private: - PxArray centeredNormalizedPoints; + PxArray centeredNormalizedPoints; PxArray neighbors; PxArray unusedTets; PxArray vertexToTet; @@ -354,7 +354,7 @@ namespace Ext //Modified tetmesh quality improvement implementation of the method described in https://cs.nyu.edu/~yixinhu/tetwild.pdf Section 3.2 Mesh Improvement void optimize(DelaunayTetrahedralizer& del, PxArray>& pointToOriginalTriangle, PxI32 numFixPoints, - PxArray& optimizedPoints, PxArray& optimizedTets, PxI32 numPasses = 10); + PxArray& optimizedPoints, PxArray& optimizedTets, PxI32 numPasses = 10); } } diff --git a/physx/source/physxextensions/src/tet/ExtFastWindingNumber.cpp b/physx/source/physxextensions/src/tet/ExtFastWindingNumber.cpp index d678fff4a..9a6cdf32d 100644 --- a/physx/source/physxextensions/src/tet/ExtFastWindingNumber.cpp +++ b/physx/source/physxextensions/src/tet/ExtFastWindingNumber.cpp @@ -38,16 +38,16 @@ namespace physx { namespace Ext { - PxF64 computeWindingNumber(const PxArray& tree, const Vec3& q, PxF64 beta, const PxHashMap& clusters, - const PxArray& triangles, const PxArray& points) + PxF64 computeWindingNumber(const PxArray& tree, const PxVec3d& q, PxF64 beta, const PxHashMap& clusters, + const PxArray& triangles, const PxArray& points) { - return Gu::computeWindingNumber(tree.begin(), q, beta, clusters, reinterpret_cast(triangles.begin()), points.begin()); + return Gu::computeWindingNumber(tree.begin(), q, beta, clusters, reinterpret_cast(triangles.begin()), points.begin()); } void precomputeClusterInformation(PxArray& tree, const PxArray& triangles, - const PxArray& points, PxHashMap& result, PxI32 rootNodeIndex) + const PxArray& points, PxHashMap& result, PxI32 rootNodeIndex) { - Gu::precomputeClusterInformation(tree.begin(), reinterpret_cast(triangles.begin()), triangles.size(), points.begin(), result, rootNodeIndex); + Gu::precomputeClusterInformation(tree.begin(), reinterpret_cast(triangles.begin()), triangles.size(), points.begin(), result, rootNodeIndex); } } } diff --git a/physx/source/physxextensions/src/tet/ExtFastWindingNumber.h b/physx/source/physxextensions/src/tet/ExtFastWindingNumber.h index 688c55954..9a21013ba 100644 --- a/physx/source/physxextensions/src/tet/ExtFastWindingNumber.h +++ b/physx/source/physxextensions/src/tet/ExtFastWindingNumber.h @@ -38,14 +38,14 @@ namespace Ext using Triangle = Gu::IndexedTriangleT; using Triangle16 = Gu::IndexedTriangleT; - typedef Gu::ClusterApproximationT ClusterApproximationF64; - typedef Gu::SecondOrderClusterApproximationT SecondOrderClusterApproximationF64; + typedef Gu::ClusterApproximationT ClusterApproximationF64; + typedef Gu::SecondOrderClusterApproximationT SecondOrderClusterApproximationF64; - PxF64 computeWindingNumber(const PxArray& tree, const Vec3& q, PxF64 beta, const PxHashMap& clusters, - const PxArray& triangles, const PxArray& points); + PxF64 computeWindingNumber(const PxArray& tree, const PxVec3d& q, PxF64 beta, const PxHashMap& clusters, + const PxArray& triangles, const PxArray& points); void precomputeClusterInformation(PxArray& tree, const PxArray& triangles, - const PxArray& points, PxHashMap& result, PxI32 rootNodeIndex = 0); + const PxArray& points, PxHashMap& result, PxI32 rootNodeIndex = 0); } } diff --git a/physx/source/physxextensions/src/tet/ExtMeshSimplificator.cpp b/physx/source/physxextensions/src/tet/ExtMeshSimplificator.cpp index 930db6738..9933d3e9e 100644 --- a/physx/source/physxextensions/src/tet/ExtMeshSimplificator.cpp +++ b/physx/source/physxextensions/src/tet/ExtMeshSimplificator.cpp @@ -27,6 +27,7 @@ #include "ExtMeshSimplificator.h" #include "foundation/PxSort.h" + namespace physx { namespace Ext @@ -204,11 +205,17 @@ namespace physx return 0; } + inline PxVec3Ex MeshSimplificator::projectPoint(const PxVec3& p) + { + PxU32 triangleId; + PxVec3 pos = projector->projectPoint(p, triangleId); + return PxVec3Ex(pos, triangleId); + } + // ------------------------------------------------------------------------------------- - void MeshSimplificator::evalEdgeCost(PxI32 triNr, PxI32 edgeNr, PxReal &cost, PxReal &ratio) + PxVec3Ex MeshSimplificator::evalEdgeCost(PxI32 triNr, PxI32 edgeNr, PxReal &cost) { const PxI32 numSteps = 10; - ratio = -1.0f; cost = -1.0f; PxI32 id0 = triIds[3 * triNr + edgeNr]; PxI32 id1 = triIds[3 * triNr + (edgeNr + 1) % 3]; @@ -217,19 +224,22 @@ namespace physx PxReal maxCost = -FLT_MAX; Quadric q; q = quadrics[id0] + quadrics[id1]; - PxVec3 pos; + PxVec3Ex pos; - PxReal edgeLength = (vertices[id0] - vertices[id1]).magnitude(); + PxReal edgeLength = (vertices[id0].p - vertices[id1].p).magnitude(); for (PxI32 i = 0; i <= numSteps; i++) { float r = 1.0f / numSteps * i; - pos = vertices[id0] * (1.0f - r) + vertices[id1] * r; - float c = q.outerProduct(pos); + pos.p = vertices[id0].p * (1.0f - r) + vertices[id1].p * r; + if (projector) + pos = projectPoint(pos.p); + + float c = q.outerProduct(pos.p); c += edgeLengthCostWeight * edgeLength; if (cost < 0.0f || c < cost) { - cost = c; ratio = r; + cost = c; } if (cost > maxCost) maxCost = cost; @@ -240,10 +250,12 @@ namespace physx if (maxCost - minCost < flatnessDetectionThreshold) { float r = 0.5f; - pos = vertices[id0] * (1.0f - r) + vertices[id1] * r; - cost = q.outerProduct(pos) + edgeLengthCostWeight * edgeLength; - ratio = r; - } + pos.p = vertices[id0].p * (1.0f - r) + vertices[id1].p * r; + if (projector) + pos = projectPoint(pos.p); + cost = q.outerProduct(pos.p) + edgeLengthCostWeight * edgeLength; + } + return pos; } // ------------------------------------------------------------------------------------- @@ -295,10 +307,10 @@ namespace physx // new center pos - float cost, ratio; - evalEdgeCost(triNr, edgeNr, cost, ratio); - PxVec3 newPos = vertices[id0] * (1.0f - ratio) + vertices[id1] * ratio; - + PxReal cost; + PxVec3Ex newPos = evalEdgeCost(triNr, edgeNr, cost); + //PxVec3 newPos = vertices[id0] * (1.0f - ratio) + vertices[id1] * ratio; + // any triangle flips? for (PxI32 side = 0; side < 2; side++) @@ -315,8 +327,8 @@ namespace physx PxI32 id = triIds[3 * adj + j]; if (id == other) deleted = true; - p[j] = vertices[id]; - q[j] = (id == id0 || id == id1) ? newPos : p[j]; + p[j] = vertices[id].p; + q[j] = (id == id0 || id == id1) ? newPos.p : p[j]; } if (!deleted) { @@ -416,7 +428,7 @@ namespace physx PxI32 adj1 = triIds[3 * adj + (j + 1) % 3]; if (adj0 == id0 || adj1 == id0) { - evalEdgeCost(adj, j, cost, ratio); + evalEdgeCost(adj, j, cost); PxI32 id = getEdgeId(adj, j); heap.insert(HeapElem(adj, j, cost), id); @@ -433,14 +445,14 @@ namespace physx #endif - void minMax(const PxArray& points, PxVec3& min, PxVec3& max) + void minMax(const PxArray& points, PxVec3& min, PxVec3& max) { min = PxVec3(FLT_MAX, FLT_MAX, FLT_MAX); max = PxVec3(-FLT_MAX, -FLT_MAX, -FLT_MAX); for (PxU32 i = 0; i < points.size(); ++i) { - const PxVec3& p = points[i]; + const PxVec3& p = points[i].p; if (p.x > max.x) max.x = p.x; if (p.y > max.y) max.y = p.y; if (p.z > max.z) max.z = p.z; if (p.x < min.x) min.x = p.x; if (p.y < min.y) min.y = p.y; if (p.z < min.z) min.z = p.z; } @@ -450,7 +462,7 @@ namespace physx #pragma GCC diagnostic pop #endif - void MeshSimplificator::transformPointsToUnitBox(PxArray& points) + void MeshSimplificator::transformPointsToUnitBox(PxArray& points) { PxVec3 min, max; minMax(points, min, max); @@ -460,7 +472,7 @@ namespace physx scaling = 1.0f / PxMax(PxMax(1e-6f, size.x), PxMax(size.y, size.z)); for (PxU32 i = 0; i < points.size(); ++i) - points[i] = (points[i] - min) * scaling; + points[i].p = (points[i].p - min) * scaling; } void MeshSimplificator::transformPointsToOriginalPosition(PxArray& points) @@ -471,14 +483,15 @@ namespace physx } // ------------------------------------------------------------------------------------- - void MeshSimplificator::init(const PxSimpleTriangleMesh& inputMesh, PxReal edgeLengthCostWeight_, PxReal flatnessDetectionThreshold_) + void MeshSimplificator::init(const PxSimpleTriangleMesh& inputMesh, PxReal edgeLengthCostWeight_, + PxReal flatnessDetectionThreshold_, bool projectSimplifiedPointsOnInputMeshSurface) { edgeLengthCostWeight = edgeLengthCostWeight_; flatnessDetectionThreshold = flatnessDetectionThreshold_; vertices.resize(inputMesh.points.count); for (PxU32 i = 0; i < inputMesh.points.count; i++) - vertices[i] = inputMesh.points.at(i); + vertices[i] = PxVec3Ex(inputMesh.points.at(i)); transformPointsToUnitBox(vertices); @@ -496,16 +509,38 @@ namespace physx triIds[i] = PxI32(inputMesh.triangles.at(i)); } + for (PxU32 i = 0; i < triIds.size(); i++) + vertices[triIds[i]].i = i / 3; + + if (projectSimplifiedPointsOnInputMeshSurface) + { + originalTriIds.resize(triIds.size()); + for (PxU32 i = 0; i < triIds.size(); ++i) + originalTriIds[i] = triIds[i]; + scaledOriginalVertices.resize(inputMesh.points.count); + for (PxU32 i = 0; i < inputMesh.points.count; i++) + scaledOriginalVertices[i] = vertices[i].p; + projector = Gu::PxCreatePointOntoTriangleMeshProjector(scaledOriginalVertices.begin(), originalTriIds.begin(), inputMesh.triangles.count); + } + else + projector = NULL; + init(); } // ------------------------------------------------------------------------------------- - void MeshSimplificator::init(const PxArray &inputVertices, const PxArray &inputTriIds, PxReal edgeLengthCostWeight_, PxReal flatnessDetectionThreshold_) + void MeshSimplificator::init(const PxArray &inputVertices, const PxArray &inputTriIds, PxReal edgeLengthCostWeight_, + PxReal flatnessDetectionThreshold_, bool projectSimplifiedPointsOnInputMeshSurface) { edgeLengthCostWeight = edgeLengthCostWeight_; flatnessDetectionThreshold = flatnessDetectionThreshold_; - vertices = inputVertices; + vertices.resize(inputVertices.size()); + for (PxU32 i = 0; i < inputVertices.size(); i++) + vertices[i] = PxVec3Ex(inputVertices[i]); + + for (PxU32 i = 0; i < inputTriIds.size(); i++) + vertices[inputTriIds[i]].i = i / 3; transformPointsToUnitBox(vertices); @@ -513,9 +548,27 @@ namespace physx for (PxU32 i = 0; i < inputTriIds.size(); i++) triIds[i] = PxI32(inputTriIds[i]); + if (projectSimplifiedPointsOnInputMeshSurface) + { + scaledOriginalVertices.resize(inputVertices.size()); + for (PxU32 i = 0; i < inputVertices.size(); i++) + scaledOriginalVertices[i] = vertices[i].p; + projector = Gu::PxCreatePointOntoTriangleMeshProjector(scaledOriginalVertices.begin(), inputTriIds.begin(), inputTriIds.size() / 3); + } + else + projector = NULL; + init(); } + MeshSimplificator::~MeshSimplificator() + { + if (projector) + { + PX_RELEASE(projector) + } + } + // ------------------------------------------------------------------------------------- void MeshSimplificator::init() { @@ -540,7 +593,7 @@ namespace physx PxI32 id0 = triIds[3 * i]; PxI32 id1 = triIds[3 * i + 1]; PxI32 id2 = triIds[3 * i + 2]; - q.setFromPlane(vertices[id0], vertices[id1], vertices[id2]); + q.setFromPlane(vertices[id0].p, vertices[id1].p, vertices[id2].p); quadrics[id0] += q; quadrics[id1] += q; quadrics[id2] += q; @@ -555,10 +608,10 @@ namespace physx for (PxI32 j = 0; j < 3; j++) { PxI32 n = triNeighbors[3 * i + j]; - if (n < 0 || i < n) { - - float cost, ratio; - evalEdgeCost(i, j, cost, ratio); + if (n < 0 || i < n) + { + PxReal cost; + evalEdgeCost(i, j, cost); heap.insert(HeapElem(i, j, cost), getEdgeId(i, j)); } } @@ -586,7 +639,7 @@ namespace physx PxI32 id0 = triIds[3 * e.triNr + e.edgeNr]; PxI32 id1 = triIds[3 * e.triNr + (e.edgeNr + 1) % 3]; - PxF32 length = (vertices[id0] - vertices[id1]).magnitude(); + PxF32 length = (vertices[id0].p - vertices[id1].p).magnitude(); if (maximalEdgeLength == 0.0f || length < maximalEdgeLength) { collapseEdge(e.triNr, e.edgeNr); @@ -619,7 +672,7 @@ namespace physx } // ------------------------------------------------------------------------------------- - void MeshSimplificator::readBack(PxArray& outVertices, PxArray& outTriIds, PxArray *vertexMap) + void MeshSimplificator::readBack(PxArray& outVertices, PxArray& outTriIds, PxArray *vertexMap, PxArray *outputVertexToInputTriangle) { outVertices.clear(); outTriIds.clear(); @@ -638,7 +691,9 @@ namespace physx if (idMap[id] < 0) { idMap[id] = outVertices.size(); - outVertices.pushBack(vertices[id]); + outVertices.pushBack(vertices[id].p); + if(outputVertexToInputTriangle && projector) + outputVertexToInputTriangle->pushBack(vertices[id].i); } outTriIds.pushBack(PxU32(idMap[id])); } diff --git a/physx/source/physxextensions/src/tet/ExtMeshSimplificator.h b/physx/source/physxextensions/src/tet/ExtMeshSimplificator.h index c397c400f..fad0866c0 100644 --- a/physx/source/physxextensions/src/tet/ExtMeshSimplificator.h +++ b/physx/source/physxextensions/src/tet/ExtMeshSimplificator.h @@ -34,6 +34,7 @@ #include "ExtQuadric.h" #include "ExtRandomAccessHeap.h" +#include "GuSDF.h" // ------------------------------------------------------------------------------ @@ -43,6 +44,19 @@ namespace physx { namespace Ext { + struct PxVec3Ex + { + PxVec3 p; + PxU32 i = 0xFFFFFFFF; + + explicit PxVec3Ex() : p(0.0f), i(0xFFFFFFFF) + { + } + + explicit PxVec3Ex(PxVec3 point, PxU32 sourceTriangleIndex = 0xFFFFFFFF) : p(point), i(sourceTriangleIndex) + { + } + }; class MeshSimplificator { @@ -50,15 +64,20 @@ namespace physx MeshSimplificator(); - void init(const PxSimpleTriangleMesh& inputMesh, PxReal edgeLengthCostWeight_ = 1e-1f, PxReal flatnessDetectionThreshold_ = 1e-2f); - void init(const PxArray &vertices, const PxArray &triIds, PxReal edgeLengthCostWeight_ = 1e-1f, PxReal flatnessDetectionThreshold_ = 1e-2f); + void init(const PxSimpleTriangleMesh& inputMesh, PxReal edgeLengthCostWeight_ = 1e-1f, PxReal flatnessDetectionThreshold_ = 1e-2f, bool projectSimplifiedPointsOnInputMeshSurface = false); + void init(const PxArray &vertices, const PxArray &triIds, PxReal edgeLengthCostWeight_ = 1e-1f, PxReal flatnessDetectionThreshold_ = 1e-2f, bool projectSimplifiedPointsOnInputMeshSurface = false); void decimateByRatio(PxF32 relativeOutputMeshSize = 0.5f, PxF32 maximalEdgeLength = 0.0f); void decimateBySize(PxI32 targetTriangleCount, PxF32 maximalEdgeLength = 0.0f); - void readBack(PxArray& vertices, PxArray& triIds, PxArray *vertexMap = NULL); + void readBack(PxArray& vertices, PxArray& triIds, PxArray *vertexMap = NULL, PxArray *outputVertexToInputTriangle = NULL); + + ~MeshSimplificator(); private: - PxArray vertices; + PxArray vertices; PxArray triIds; + PxArray scaledOriginalVertices; + PxArray originalTriIds; + Gu::PxPointOntoTriangleMeshProjector* projector; void init(); bool step(PxF32 maximalEdgeLength); @@ -69,10 +88,11 @@ namespace physx void replaceNeighbor(PxI32 triNr, PxI32 oldNeighbor, PxI32 newNeighbor); PxI32 getEdgeId(PxI32 triNr, PxI32 edgeNr); bool collapseEdge(PxI32 triNr, PxI32 edgeNr); - void evalEdgeCost(PxI32 triNr, PxI32 edgeNr, float& cost, float& ratio); + PxVec3Ex evalEdgeCost(PxI32 triNr, PxI32 edgeNr, PxReal& costt); + PxVec3Ex projectPoint(const PxVec3& p); void findTriNeighbors(); - void transformPointsToUnitBox(PxArray& points); + void transformPointsToUnitBox(PxArray& points); void transformPointsToOriginalPosition(PxArray& points); PxI32 numMeshTris; diff --git a/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.cpp b/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.cpp index 264e5201d..eb1460a61 100644 --- a/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.cpp +++ b/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.cpp @@ -89,11 +89,11 @@ namespace physx for (PxI32 i = 0; i < PxI32(surfaceVerts.size()); i++) { const PxVec3& v = surfaceVerts[i]; - bounds.include(Vec3(v.x, v.y, v.z)); + bounds.include(PxVec3d(PxF64(v.x), PxF64(v.y), PxF64(v.z))); } bounds.expand(0.01); - Vec3 dims = bounds.getDimensions(); + PxVec3d dims = bounds.getDimensions(); PxF64 size = PxMax(dims.x, PxMax(dims.y, dims.z)); // create root @@ -116,7 +116,7 @@ namespace physx // ------------------------------------------------------------------------------------- - PxI32 OctreeTetrahedralizer::Cell::getChildNr(const Vec3& p) + PxI32 OctreeTetrahedralizer::Cell::getChildNr(const PxVec3d& p) { if (firstChild < 0) return -1; @@ -160,7 +160,7 @@ namespace physx child.init(); child.depth = cells[cellNr].depth + 1; child.size = cells[cellNr].size * 0.5; - child.orig = cells[cellNr].orig + Vec3( + child.orig = cells[cellNr].orig + PxVec3d( childRelPos[i][0] * child.size, childRelPos[i][1] * child.size, childRelPos[i][2] * child.size); @@ -177,10 +177,10 @@ namespace physx // ----------------------------------------------------------------------------------- - static Vec3 jitter(const Vec3& p, Cm::RandomR250& random) + static PxVec3d jitter(const PxVec3d& p, Cm::RandomR250& random) { PxF64 eps = 0.001; - return Vec3( + return PxVec3d( p.x - eps + 2.0 * eps * PxF64(random.rand(0.0f, 1.0f)), p.y - eps + 2.0 * eps * PxF64(random.rand(0.0f, 1.0f)), p.z - eps + 2.0 * eps * PxF64(random.rand(0.0f, 1.0f))); @@ -198,20 +198,20 @@ namespace physx for (PxI32 i = 0; i < PxI32(surfaceVerts.size()); i++) { const PxVec3& v = surfaceVerts[i]; - tetVerts.pushBack(Vec3(v.x, v.y, v.z)); + tetVerts.pushBack(PxVec3d(PxF64(v.x), PxF64(v.y), PxF64(v.z))); } if (includeOctreeNodes) { - PxArray treeVerts; + PxArray treeVerts; for (PxI32 i = 0; i < PxI32(cells.size()); i++) { PxF64 s = cells[i].size; for (PxI32 j = 0; j < 8; j++) { - Vec3 p = cells[i].orig + Vec3( + PxVec3d p = cells[i].orig + PxVec3d( s * cubeCorners[j][0], s * cubeCorners[j][1], s * cubeCorners[j][2]); @@ -238,7 +238,7 @@ namespace physx PxArray refs(numTreeVerts); for (PxI32 i = 0; i < numTreeVerts; i++) { - Vec3& p = treeVerts[i]; + PxVec3d& p = treeVerts[i]; refs[i].d = p.x + 0.3 * p.y + 0.1 * p.z; refs[i].vertNr = i; } @@ -254,8 +254,8 @@ namespace physx nr++; if (duplicate[r.vertNr]) continue; - Vec3& p = treeVerts[r.vertNr]; - Vec3 v = jitter(p, random); + PxVec3d& p = treeVerts[r.vertNr]; + PxVec3d v = jitter(p, random); if (insideTester.isInside(PxVec3(PxReal(v.x), PxReal(v.y), PxReal(v.z)))) tetVerts.pushBack(jitter(p, random)); @@ -263,7 +263,7 @@ namespace physx PxI32 i = nr; while (i < numTreeVerts && fabs(refs[i].d - r.d) < eps) { - Vec3& q = treeVerts[refs[i].vertNr]; + PxVec3d& q = treeVerts[refs[i].vertNr]; if ((p - q).magnitude() < eps) duplicate[refs[i].vertNr] = true; i++; @@ -273,7 +273,7 @@ namespace physx } // ----------------------------------------------------------------------------------- - Vec3 OctreeTetrahedralizer::getTetCenter(PxI32 tetNr) const + PxVec3d OctreeTetrahedralizer::getTetCenter(PxI32 tetNr) const { return (tetVerts[tetIds[4 * tetNr]] + tetVerts[tetIds[4 * tetNr + 1]] + @@ -284,7 +284,7 @@ namespace physx // ----------------------------------------------------------------------------------- void OctreeTetrahedralizer::treeInsertTet(PxI32 tetNr) { - Vec3 center = getTetCenter(tetNr); + PxVec3d center = getTetCenter(tetNr); PxI32 cellNr = 0; while (cellNr >= 0) @@ -294,8 +294,8 @@ namespace physx c.closestTetNr = tetNr; else { - Vec3 cellCenter = c.orig + Vec3(c.size, c.size, c.size) * 0.5; - Vec3 closest = getTetCenter(c.closestTetNr); + PxVec3d cellCenter = c.orig + PxVec3d(c.size, c.size, c.size) * 0.5; + PxVec3d closest = getTetCenter(c.closestTetNr); if ((cellCenter - center).magnitudeSquared() < (cellCenter - closest).magnitudeSquared()) c.closestTetNr = tetNr; } @@ -306,7 +306,7 @@ namespace physx // ----------------------------------------------------------------------------------- void OctreeTetrahedralizer::treeRemoveTet(PxI32 tetNr) { - Vec3 center = getTetCenter(tetNr); + PxVec3d center = getTetCenter(tetNr); PxI32 cellNr = 0; while (cellNr >= 0) @@ -362,7 +362,7 @@ namespace physx } // ----------------------------------------------------------------------------------- - bool OctreeTetrahedralizer::findSurroundingTet(const Vec3& p, PxI32 startTetNr, PxI32& tetNr) + bool OctreeTetrahedralizer::findSurroundingTet(const PxVec3d& p, PxI32 startTetNr, PxI32& tetNr) { currentTetMark++; tetNr = startTetNr; @@ -375,7 +375,7 @@ namespace physx break; tetMarks[tetNr] = currentTetMark; - Vec3 c = getTetCenter(tetNr); + PxVec3d c = getTetCenter(tetNr); PxI32* ids = &tetIds[4 * tetNr]; PxF64 minT = DBL_MAX; @@ -383,11 +383,11 @@ namespace physx for (PxI32 i = 0; i < 4; i++) { - const Vec3& p0 = tetVerts[ids[tetFaces[i][0]]]; - const Vec3& p1 = tetVerts[ids[tetFaces[i][1]]]; - const Vec3& p2 = tetVerts[ids[tetFaces[i][2]]]; + const PxVec3d& p0 = tetVerts[ids[tetFaces[i][0]]]; + const PxVec3d& p1 = tetVerts[ids[tetFaces[i][1]]]; + const PxVec3d& p2 = tetVerts[ids[tetFaces[i][2]]]; - Vec3 n = (p1 - p0).cross(p2 - p0); + PxVec3d n = (p1 - p0).cross(p2 - p0); n = n.getNormalized(); PxF64 hp = (p - p0).dot(n); PxF64 hc = (c - p0).dot(n); @@ -411,7 +411,7 @@ namespace physx } // ----------------------------------------------------------------------------------- - bool OctreeTetrahedralizer::findSurroundingTet(const Vec3& p, PxI32& tetNr) + bool OctreeTetrahedralizer::findSurroundingTet(const PxVec3d& p, PxI32& tetNr) { PxI32 startTet = 0; PxI32 cellNr = 0; @@ -426,17 +426,17 @@ namespace physx } // ----------------------------------------------------------------------------------- - static Vec3 getCircumCenter(Vec3& p0, Vec3& p1, Vec3& p2, Vec3& p3) + static PxVec3d getCircumCenter(PxVec3d& p0, PxVec3d& p1, PxVec3d& p2, PxVec3d& p3) { - Vec3 b = p1 - p0; - Vec3 c = p2 - p0; - Vec3 d = p3 - p0; + PxVec3d b = p1 - p0; + PxVec3d c = p2 - p0; + PxVec3d d = p3 - p0; PxF64 det = 2.0 * (b.x*(c.y*d.z - c.z*d.y) - b.y*(c.x*d.z - c.z*d.x) + b.z*(c.x*d.y - c.y*d.x)); if (det == 0.0) return p0; else { - Vec3 v = c.cross(d)*b.dot(b) + d.cross(b)*c.dot(c) + b.cross(c)*d.dot(d); + PxVec3d v = c.cross(d)*b.dot(b) + d.cross(b)*c.dot(c) + b.cross(c)*d.dot(d); v /= det; return p0 + v; } @@ -446,7 +446,7 @@ namespace physx // ----------------------------------------------------------------------------------- bool OctreeTetrahedralizer::meshInsertTetVert(PxI32 vertNr) { - const Vec3& p = tetVerts[vertNr]; + const PxVec3d& p = tetVerts[vertNr]; PxI32 surroundingTetNr; if (!findSurroundingTet(p, surroundingTetNr)) return false; @@ -475,7 +475,7 @@ namespace physx // Delaunay condition test PxI32* ids = &tetIds[4 * n]; - Vec3 c = getCircumCenter(tetVerts[ids[0]], tetVerts[ids[1]], tetVerts[ids[2]], tetVerts[ids[3]]); + PxVec3d c = getCircumCenter(tetVerts[ids[0]], tetVerts[ids[1]], tetVerts[ids[2]], tetVerts[ids[3]]); PxF64 r2 = (tetVerts[ids[0]] - c).magnitudeSquared(); if ((p - c).magnitudeSquared() < r2) @@ -571,14 +571,14 @@ namespace physx } // ----------------------------------------------------------------------------------- - static PxF64 tetQuality(const Vec3& p0, const Vec3& p1, const Vec3& p2, const Vec3& p3) + static PxF64 tetQuality(const PxVec3d& p0, const PxVec3d& p1, const PxVec3d& p2, const PxVec3d& p3) { - Vec3 d0 = p1 - p0; - Vec3 d1 = p2 - p0; - Vec3 d2 = p3 - p0; - Vec3 d3 = p2 - p1; - Vec3 d4 = p3 - p2; - Vec3 d5 = p1 - p3; + PxVec3d d0 = p1 - p0; + PxVec3d d1 = p2 - p0; + PxVec3d d2 = p3 - p0; + PxVec3d d3 = p2 - p1; + PxVec3d d4 = p3 - p2; + PxVec3d d5 = p1 - p3; PxF64 s0 = d0.magnitudeSquared(); PxF64 s1 = d1.magnitudeSquared(); @@ -624,7 +624,7 @@ namespace physx if (!remove) { - Vec3 c = getTetCenter(i); + PxVec3d c = getTetCenter(i); if (!insideTester.isInside(PxVec3(PxReal(c.x), PxReal(c.y), PxReal(c.z)))) remove = true; @@ -678,11 +678,11 @@ namespace physx bounds.expand(bounds.getDimensions().magnitude() * 0.1); firstABBVert = PxI32(tetVerts.size()); - Vec3 dims = bounds.getDimensions(); + PxVec3d dims = bounds.getDimensions(); for (PxI32 i = 0; i < 8; i++) { - tetVerts.pushBack(bounds.minimum + Vec3( + tetVerts.pushBack(bounds.minimum + PxVec3d( cubeCorners[i][0] * dims.x, cubeCorners[i][1] * dims.y, cubeCorners[i][2] * dims.z)); @@ -718,7 +718,7 @@ namespace physx for (PxU32 i = 0; i < tetVerts.size(); i++) { - Vec3 &v = tetVerts[i]; + PxVec3d &v = tetVerts[i]; outputTetVerts[i] = PxVec3(PxReal(v.x), PxReal(v.y), PxReal(v.z)); } diff --git a/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.h b/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.h index 3d5efd2a6..827e2ac88 100644 --- a/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.h +++ b/physx/source/physxextensions/src/tet/ExtOctreeTetrahedralizer.h @@ -71,24 +71,24 @@ namespace physx void init() { firstChild = -1; - orig = Vec3(0.0, 0.0, 0.0); + orig = PxVec3d(0.0, 0.0, 0.0); size = 0.0; numVerts = 0; closestTetNr = -1; depth = 0; } - PxI32 getChildNr(const Vec3& p); + PxI32 getChildNr(const PxVec3d& p); PX_FORCE_INLINE PxI32 getChildNr(const PxVec3& p) { - return getChildNr(Vec3(p.x, p.y, p.z)); + return getChildNr(PxVec3d(PxF64(p.x), PxF64(p.y), PxF64(p.z))); } PxI32 firstChild; PxI32 firstCellVert; PxI32 firstCellTet; - Vec3 orig; + PxVec3d orig; double size; PxI32 numVerts; PxI32 closestTetNr; @@ -100,7 +100,7 @@ namespace physx // tet mesh - PxArray tetVerts; + PxArray tetVerts; PxArray tetIds; PxArray tetNeighbors; PxArray tetMarks; @@ -142,8 +142,8 @@ namespace physx void treeInsertVert(PxI32 cellNr, PxI32 vertNr); void createTetVerts(bool includeOctreeNodes); - bool findSurroundingTet(const Vec3& p, PxI32 startTetNr, PxI32& tetNr); - bool findSurroundingTet(const Vec3& p, PxI32& tetNr); + bool findSurroundingTet(const PxVec3d& p, PxI32 startTetNr, PxI32& tetNr); + bool findSurroundingTet(const PxVec3d& p, PxI32& tetNr); void treeInsertTet(PxI32 tetNr); void treeRemoveTet(PxI32 tetNr); @@ -151,7 +151,7 @@ namespace physx PxI32 getNewTetNr(); void removeTetNr(PxI32 tetNr); - Vec3 getTetCenter(PxI32 tetNr) const; + PxVec3d getTetCenter(PxI32 tetNr) const; bool meshInsertTetVert(PxI32 vertNr); InsideTester insideTester; diff --git a/physx/source/physxextensions/src/tet/ExtRemesher.cpp b/physx/source/physxextensions/src/tet/ExtRemesher.cpp index 269ab7512..25bab94b5 100644 --- a/physx/source/physxextensions/src/tet/ExtRemesher.cpp +++ b/physx/source/physxextensions/src/tet/ExtRemesher.cpp @@ -90,14 +90,19 @@ namespace physx // ------------------------------------------------------------------------------------- void Remesher::remesh(const PxArray& inputVerts, const PxArray& inputTriIds, - PxI32 resolution, PxArray *vertexMap) + PxU32 resolution, PxArray *vertexMap) + { + remesh(inputVerts.begin(), inputVerts.size(), inputTriIds.begin(), inputTriIds.size(), resolution, vertexMap); + } + + void Remesher::remesh(const PxVec3* inputVerts, PxU32 nbVertices, const PxU32* inputTriIds, PxU32 nbTriangleIndices, PxU32 resolution, PxArray *vertexMap) { clear(); PxBounds3 meshBounds; meshBounds.setEmpty(); - for (PxI32 i = 0; i < PxI32(inputVerts.size()); i++) + for (PxU32 i = 0; i < nbVertices; i++) meshBounds.include(inputVerts[i]); PxVec3 dims = meshBounds.getDimensions(); @@ -106,7 +111,7 @@ namespace physx meshBounds.fattenFast(3.0f * spacing); - PxI32 numTris = PxI32(inputTriIds.size()) / 3; + PxU32 numTris = nbTriangleIndices / 3; PxBounds3 triBounds, cellBounds; Gu::BoxPadded box; box.rot = PxMat33(PxIdentity); @@ -116,7 +121,7 @@ namespace physx // create sparse overlapping cells - for (PxI32 i = 0; i < numTris; i++) + for (PxU32 i = 0; i < numTris; i++) { const PxVec3& p0 = inputVerts[inputTriIds[3 * i]]; const PxVec3& p1 = inputVerts[inputTriIds[3 * i + 1]]; @@ -244,10 +249,10 @@ namespace physx removeDuplicateVertices(); pruneInternalSurfaces(); - project(inputVerts, inputTriIds, 2.0f * spacing, 0.1f * spacing); + project(inputVerts, inputTriIds, nbTriangleIndices, 2.0f * spacing, 0.1f * spacing); if (vertexMap) - createVertexMap(inputVerts, meshBounds.minimum, spacing, *vertexMap); + createVertexMap(inputVerts, nbVertices, meshBounds.minimum, spacing, *vertexMap); computeNormals(); } @@ -491,12 +496,12 @@ namespace physx } // ------------------------------------------------------------------------------------- - void Remesher::project(const PxArray& inputVerts, const PxArray& inputTriIds, + void Remesher::project(const PxVec3* inputVerts, const PxU32* inputTriIds, PxU32 nbTriangleIndices, float searchDist, float surfaceDist) { // build a bvh for the input mesh - PxI32 numInputTris = PxI32(inputTriIds.size()) / 3; + PxI32 numInputTris = PxI32(nbTriangleIndices) / 3; if (numInputTris == 0) return; @@ -518,7 +523,7 @@ namespace physx // project vertices to closest point on surface PxBounds3 pb; - for (PxI32 i = 0; i < PxI32(vertices.size()); i++) + for (PxU32 i = 0; i < vertices.size(); i++) { PxVec3& p = vertices[i]; pb.setEmpty(); @@ -529,7 +534,7 @@ namespace physx float minDist2 = PX_MAX_F32; PxVec3 closest(PxZero); - for (PxI32 j = 0; j < PxI32(bvhTris.size()); j++) + for (PxU32 j = 0; j < bvhTris.size(); j++) { PxI32 triNr = bvhTris[j]; const PxVec3& p0 = inputVerts[inputTriIds[3 * triNr]]; @@ -556,7 +561,7 @@ namespace physx static const int cellNeighbors[6][3] = { { -1,0,0 }, {1,0,0},{0,-1,0},{0,1,0},{0,0,-1},{0,0,1} }; // ------------------------------------------------------------------------------------- - void Remesher::createVertexMap(const PxArray& inputVerts, const PxVec3 &gridOrigin, PxF32 &gridSpacing, + void Remesher::createVertexMap(const PxVec3* inputVerts, PxU32 nbVertices, const PxVec3 &gridOrigin, PxF32 &gridSpacing, PxArray &vertexMap) { PxArray vertexOfCell(cells.size(), -1); @@ -604,9 +609,9 @@ namespace physx // create the map vertexMap.clear(); - vertexMap.resize(inputVerts.size(), 0); + vertexMap.resize(nbVertices, 0); - for (int i = 0; i < PxI32(inputVerts.size()); i++) + for (PxU32 i = 0; i < nbVertices; i++) { const PxVec3& p = inputVerts[i]; PxI32 xi = PxI32(PxFloor((p.x - gridOrigin.x) / gridSpacing)); diff --git a/physx/source/physxextensions/src/tet/ExtRemesher.h b/physx/source/physxextensions/src/tet/ExtRemesher.h index a42206eb1..68c6cb889 100644 --- a/physx/source/physxextensions/src/tet/ExtRemesher.h +++ b/physx/source/physxextensions/src/tet/ExtRemesher.h @@ -44,7 +44,8 @@ namespace physx Remesher() {} ~Remesher() {} - void remesh(const PxArray& verts, const PxArray& triIds, PxI32 resolution = 100, PxArray *vertexMap = nullptr); + void remesh(const PxVec3* verts, PxU32 nbVertices, const PxU32* triIds, PxU32 nbTriangleIndices, PxU32 resolution = 100, PxArray *vertexMap = nullptr); + void remesh(const PxArray& verts, const PxArray& triIds, PxU32 resolution = 100, PxArray *vertexMap = nullptr); void clear(); void readBack(PxArray& vertices, PxArray& triIds); @@ -62,10 +63,10 @@ namespace physx void computeNormals(); void findTriNeighbors(); - void project(const PxArray& inputVerts, const PxArray& inputTriIds, + void project(const PxVec3* inputVerts, const PxU32* inputTriIds, PxU32 nbTriangleIndices, float searchDist, float surfaceDist); - void createVertexMap(const PxArray& inputVerts, const PxVec3 &gridOrigin, PxF32 &gridSpacing, + void createVertexMap(const PxVec3* verts, PxU32 nbVertices, const PxVec3 &gridOrigin, PxF32 &gridSpacing, PxArray &vertexMap); // ------------------------------------------------------------------------------------- diff --git a/physx/source/physxextensions/src/tet/ExtTetSplitting.cpp b/physx/source/physxextensions/src/tet/ExtTetSplitting.cpp index 82d39a9ad..904c73187 100644 --- a/physx/source/physxextensions/src/tet/ExtTetSplitting.cpp +++ b/physx/source/physxextensions/src/tet/ExtTetSplitting.cpp @@ -335,7 +335,7 @@ namespace Ext //Splits all tets according to the specification in tetSubdivisionInfos. The resulting mesh will be watertight if the tetSubdivisionInfos are specified such //that all tets sharing and edge will get the same point inserted on their corresponding edge - void split(PxArray& tets, const PxArray& points, const PxArray& tetSubdivisionInfos) + void split(PxArray& tets, const PxArray& points, const PxArray& tetSubdivisionInfos) { PxU32 originalNumTets = tets.size(); for (PxU32 i = 0; i < originalNumTets; ++i) @@ -769,7 +769,7 @@ namespace Ext } } - void split(PxArray& tets, const PxArray& points, const PxHashMap& edgesToSplit) + void split(PxArray& tets, const PxArray& points, const PxHashMap& edgesToSplit) { PxArray subdivisionInfos; subdivisionInfos.resize(tets.size()); diff --git a/physx/source/physxextensions/src/tet/ExtTetSplitting.h b/physx/source/physxextensions/src/tet/ExtTetSplitting.h index 3b23bb7fe..3c1c9ef1c 100644 --- a/physx/source/physxextensions/src/tet/ExtTetSplitting.h +++ b/physx/source/physxextensions/src/tet/ExtTetSplitting.h @@ -41,7 +41,7 @@ namespace Ext //Splits all edges specified in edgesToSplit. The tets are modified in place. The poitns referenced by index in the key-value pari in //edgesToSplit must already pe present in the points array. This functions guarantees that the tetmesh will remain watertight. - PX_C_EXPORT void PX_CALL_CONV split(PxArray& tets, const PxArray& points, const PxHashMap& edgesToSplit); + PX_C_EXPORT void PX_CALL_CONV split(PxArray& tets, const PxArray& points, const PxHashMap& edgesToSplit); } } diff --git a/physx/source/physxextensions/src/tet/ExtUtilities.cpp b/physx/source/physxextensions/src/tet/ExtUtilities.cpp index cca0a79c6..e99b6da4a 100644 --- a/physx/source/physxextensions/src/tet/ExtUtilities.cpp +++ b/physx/source/physxextensions/src/tet/ExtUtilities.cpp @@ -35,7 +35,12 @@ namespace Ext { using namespace Gu; - void buildTree(const PxU32* triangles, const PxU32 numTriangles, const Vec3* points, PxArray& tree, PxF32 enlargement) + static PxVec3 toFloat(const PxVec3d& p) + { + return PxVec3(PxReal(p.x), PxReal(p.y), PxReal(p.z)); + } + + void buildTree(const PxU32* triangles, const PxU32 numTriangles, const PxVec3d* points, PxArray& tree, PxF32 enlargement) { //Computes a bounding box for every triangle in triangles AABBTreeBounds boxes; @@ -44,9 +49,9 @@ namespace Ext { const PxU32* tri = &triangles[3 * i]; PxBounds3 box = PxBounds3::empty(); - box.include(points[tri[0]].toFloat()); - box.include(points[tri[1]].toFloat()); - box.include(points[tri[2]].toFloat()); + box.include(toFloat(points[tri[0]])); + box.include(toFloat(points[tri[1]])); + box.include(toFloat(points[tri[2]])); box.fattenFast(enlargement); boxes.getBounds()[i] = box; } diff --git a/physx/source/physxextensions/src/tet/ExtUtilities.h b/physx/source/physxextensions/src/tet/ExtUtilities.h index 8ebf70dca..e713d07bc 100644 --- a/physx/source/physxextensions/src/tet/ExtUtilities.h +++ b/physx/source/physxextensions/src/tet/ExtUtilities.h @@ -55,10 +55,10 @@ namespace Ext return ((PxU64(b)) << 32) | (PxU64(a)); } - void buildTree(const PxU32* triangles, const PxU32 numTriangles, const Vec3* points, PxArray& tree, PxF32 enlargement = 1e-4f); + void buildTree(const PxU32* triangles, const PxU32 numTriangles, const PxVec3d* points, PxArray& tree, PxF32 enlargement = 1e-4f); //Builds a BVH from a set of triangles - PX_FORCE_INLINE void buildTree(const PxArray& triangles, const PxArray& points, PxArray& tree, PxF32 enlargement = 1e-4f) + PX_FORCE_INLINE void buildTree(const PxArray& triangles, const PxArray& points, PxArray& tree, PxF32 enlargement = 1e-4f) { buildTree(reinterpret_cast(triangles.begin()), triangles.size(), points.begin(), tree, enlargement); } diff --git a/physx/source/physxextensions/src/tet/ExtVec3.h b/physx/source/physxextensions/src/tet/ExtVec3.h index 9331afc26..630976a74 100644 --- a/physx/source/physxextensions/src/tet/ExtVec3.h +++ b/physx/source/physxextensions/src/tet/ExtVec3.h @@ -34,172 +34,34 @@ namespace physx { namespace Ext { - //3D vector class with double precision - class Vec3 - { - public: - PxF64 x; - PxF64 y; - PxF64 z; - - PX_FORCE_INLINE Vec3() : x(0), y(0), z(0) {} - - PX_FORCE_INLINE Vec3(const Vec3 &other) { x = other.x; y = other.y; z = other.z; } - - PX_FORCE_INLINE Vec3(PxF64 x_, PxF64 y_, PxF64 z_) : x(x_), y(y_), z(z_) - {} - - PX_FORCE_INLINE Vec3(PxF32 x_, PxF32 y_, PxF32 z_) : x(PxF64(x_)), y(PxF64(y_)), z(PxF64(z_)) - {} - - PX_FORCE_INLINE void set(PxF64 xCoord, PxF64 yCoord, PxF64 zCoord) - { - x = xCoord; - y = yCoord; - z = zCoord; - } - - PX_FORCE_INLINE PxVec3 toFloat() const - { - return PxVec3(PxF32(x), PxF32(y), PxF32(z)); - } - - PX_FORCE_INLINE Vec3 max(const Vec3& lhs) const - { - return Vec3(PxMax(x, lhs.x), PxMax(y, lhs.y), PxMax(z, lhs.z)); - } - - PX_FORCE_INLINE Vec3 min(const Vec3& lhs) const - { - return Vec3(PxMin(x, lhs.x), PxMin(y, lhs.y), PxMin(z, lhs.z)); - } - - PX_FORCE_INLINE PxF64 magnitudeSquared() const - { - return x * x + y * y + z * z; - } - - PX_FORCE_INLINE PxF64 magnitude() const - { - return PxSqrt(x * x + y * y + z * z); - } - - PX_FORCE_INLINE Vec3 getNormalized() const - { - PxF64 s = magnitudeSquared(); - if (s == 0) - return *this; - s = 1.0 / PxSqrt(s); - return Vec3(s * x, s * y, s * z); - } - - PX_FORCE_INLINE PxF64 dot(const Vec3& rhs) const - { - return x * rhs.x + y * rhs.y + z * rhs.z; - } - - PX_FORCE_INLINE Vec3 cross(const Vec3& v) const - { - return Vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); - } - - PX_FORCE_INLINE Vec3 operator+(const Vec3& v) const - { - return Vec3(x + v.x, y + v.y, z + v.z); - } - - PX_FORCE_INLINE Vec3 operator-(const Vec3& v) const - { - return Vec3(x - v.x, y - v.y, z - v.z); - } - - PX_FORCE_INLINE Vec3 operator*(const PxF64& v) const - { - return Vec3(x * v, y * v, z * v); - } - - PX_FORCE_INLINE Vec3 operator/(const PxF64& v) const - { - PxF64 inv = 1.0 / v; - return Vec3(x * inv, y * inv, z * inv); - } - - PX_FORCE_INLINE Vec3& operator+=(const Vec3& v) - { - x += v.x; - y += v.y; - z += v.z; - return *this; - } - - PX_FORCE_INLINE Vec3& operator-=(const Vec3& v) - { - x -= v.x; - y -= v.y; - z -= v.z; - return *this; - } - - PX_FORCE_INLINE Vec3& operator*=(PxF64 f) - { - x *= f; - y *= f; - z *= f; - return *this; - } - - PX_FORCE_INLINE Vec3& operator/=(PxF64 f) - { - f = 1.0 / f; - x *= f; - y *= f; - z *= f; - return *this; - } - - PX_FORCE_INLINE PxF64& operator[](PxU32 index) - { - PX_ASSERT(index <= 2); - - return reinterpret_cast(this)[index]; - } - - PX_FORCE_INLINE const PxF64& operator[](PxU32 index) const - { - PX_ASSERT(index <= 2); - - return reinterpret_cast(this)[index]; - } - }; - // --------------------------------------------------------------------------------- struct Bounds3 { Bounds3() {} - Bounds3(const Vec3 &min, const Vec3 &max) : minimum(min), maximum(max) {} + Bounds3(const PxVec3d &min, const PxVec3d &max) : minimum(min), maximum(max) {} void setEmpty() { - minimum = Vec3(PX_MAX_F64, PX_MAX_F64, PX_MAX_F64); - maximum = Vec3(-PX_MAX_F64, -PX_MAX_F64, -PX_MAX_F64); + minimum = PxVec3d(PX_MAX_F64, PX_MAX_F64, PX_MAX_F64); + maximum = PxVec3d(-PX_MAX_F64, -PX_MAX_F64, -PX_MAX_F64); } - Vec3 getDimensions() const { + PxVec3d getDimensions() const { return maximum - minimum; } - void include(const Vec3 &p) { - minimum = minimum.min(p); - maximum = maximum.max(p); + void include(const PxVec3d &p) { + minimum = minimum.minimum(p); + maximum = maximum.maximum(p); } void include(const Bounds3 &b) { - minimum = minimum.min(b.minimum); - maximum = maximum.max(b.maximum); + minimum = minimum.minimum(b.minimum); + maximum = maximum.maximum(b.maximum); } void expand(double d) { - minimum -= Vec3(d, d, d); - maximum += Vec3(d, d, d); + minimum -= PxVec3d(d, d, d); + maximum += PxVec3d(d, d, d); } - Vec3 minimum, maximum; + PxVec3d minimum, maximum; }; } } diff --git a/physx/source/physxgpu/include/PxPhysXGpu.h b/physx/source/physxgpu/include/PxPhysXGpu.h index 4d4ea0ac6..070d8a604 100644 --- a/physx/source/physxgpu/include/PxPhysXGpu.h +++ b/physx/source/physxgpu/include/PxPhysXGpu.h @@ -34,8 +34,8 @@ #include "foundation/PxPinnedArray.h" #include "common/PxPhysXCommonConfig.h" #include "PxSceneDesc.h" -#include "PxBuffer.h" #include "cudamanager/PxCudaContextManager.h" +#include "PxSparseGridParams.h" namespace physx { @@ -57,6 +57,15 @@ class PxParticleAndDiffuseBuffer; class PxParticleClothBuffer; class PxParticleRigidBuffer; +class PxIsosurfaceExtractor; +class PxSparseGridIsosurfaceExtractor; +struct PxIsosurfaceParams; + +class PxAnisotropyGenerator; +class PxSmoothedPositionGenerator; +class PxParticleNeighborhoodProvider; +class PxPhysicsGpu; + struct PxvSimStats; namespace Bp @@ -100,25 +109,11 @@ class PxPhysXGpu */ virtual void release() = 0; - /** - Create GPU user buffers. - */ - virtual PxBuffer* createBuffer(PxU64 byteSize, PxBufferType::Enum bufferType, PxCudaContextManager* cudaContexManager, PxU64* memStat) = 0; - virtual PxBuffer* createBuffer(PxU64 byteSyte, PxBufferType::Enum type, PxCudaContextManager* contextManager, PxU64* memStat, PxsHeapMemoryAllocatorManager* heapMemoryManager, void* stream) = 0; - virtual PxParticleBuffer* createParticleBuffer(PxU32 maxNumParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContextManager, PxU64* memStat, void (*onParticleBufferRelease)(PxParticleBuffer* buffer)) = 0; virtual PxParticleClothBuffer* createParticleClothBuffer(PxU32 maxNumParticles, PxU32 maxVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContextManager, PxU64* memStat, void (*onParticleBufferRelease)(PxParticleBuffer* buffer)) = 0; virtual PxParticleRigidBuffer* createParticleRigidBuffer(PxU32 maxNumParticles, PxU32 maxVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContextManager, PxU64* memStat, void (*onParticleBufferRelease)(PxParticleBuffer* buffer)) = 0; virtual PxParticleAndDiffuseBuffer* createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContextManager, PxU64* memStat, void (*onParticleBufferRelease)(PxParticleBuffer* buffer)) = 0; - virtual void resizeBuffer(PxBuffer* buffer, PxU64 byteSize) = 0; - - /** - Queue user buffer copy command. - */ - virtual void addCopyCommand(PxBuffer& dst, PxBuffer& src, bool flush) = 0; - virtual void addCopyCommand(PxBuffer& dst, PxBuffer& src, PxU32 srcOffset, PxU32 dstOffset, PxU32 size, bool flush) = 0; - /** Create GPU memory manager. */ @@ -129,13 +124,12 @@ class PxPhysXGpu PxsMemoryManager* memoryManager, const PxU32 gpuComputeVersion) = 0; - /** - Create GPU kernel wrangler manager. + /** + Create GPU kernel wrangler manager. If a kernel wrangler manager already exists, then that one will be returned. + The kernel wrangler manager should not be deleted. It will automatically be deleted when the PxPhysXGpu singleton gets released. */ - virtual PxsKernelWranglerManager* createGpuKernelWranglerManager( - PxCudaContextManager* cudaContextManager, - PxErrorCallback& errorCallback, - const PxU32 gpuComputeVersion) = 0; + virtual PxsKernelWranglerManager* getGpuKernelWranglerManager( + PxCudaContextManager* cudaContextManager) = 0; /** Create GPU broadphase. @@ -195,8 +189,7 @@ class PxPhysXGpu const PxgDynamicsMemoryConfig& config, IG::SimpleIslandManager* islandManager, const PxU32 maxNumPartitions, const PxU32 maxNumStaticPartitions, const bool enableStabilization, const bool useEnhancedDeterminism, const PxReal maxBiasCoefficient, const PxU32 gpuComputeVersion, PxvSimStats& simStats, PxsHeapMemoryAllocatorManager* heapMemoryManager, - const bool frictionEveryIteration, PxSolverType::Enum solverType, const PxReal lengthScale) = 0; - + const bool frictionEveryIteration, PxSolverType::Enum solverType, const PxReal lengthScale, bool enableDirectGPUAPI) = 0; }; } @@ -229,6 +222,8 @@ PX_C_EXPORT PX_PHYSX_GPU_API physx::PxKernelIndex* PX_CALL_CONV PxGpuGetCudaFunc PX_C_EXPORT PX_PHYSX_GPU_API physx::PxU32 PX_CALL_CONV PxGpuGetCudaFunctionTableSize(); PX_C_EXPORT PX_PHYSX_GPU_API void** PX_CALL_CONV PxGpuGetCudaModuleTable(); PX_C_EXPORT PX_PHYSX_GPU_API physx::PxU32 PX_CALL_CONV PxGpuGetCudaModuleTableSize(); +PX_C_EXPORT PX_PHYSX_GPU_API physx::PxPhysicsGpu* PX_CALL_CONV PxGpuCreatePhysicsGpu(); + #endif #endif // PX_PHYSX_GPU_H diff --git a/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjectNames.h b/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjectNames.h index b5ecb4ce4..3c504c496 100644 --- a/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjectNames.h +++ b/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjectNames.h @@ -41,14 +41,12 @@ PxPhysics_TetrahedronMeshes, PxPhysics_HeightFields, PxPhysics_ConvexMeshes, PxPhysics_BVHs, -PxPhysics_BVHStructures, PxPhysics_Scenes, PxPhysics_Shapes, PxPhysics_Materials, PxPhysics_FEMSoftBodyMaterials, PxPhysics_FEMClothMaterials, PxPhysics_PBDMaterials, -PxPhysics_CustomMaterials, PxPhysics_PropertiesStop, PxRefCounted_PropertiesStart, PxRefCounted_ReferenceCount, @@ -74,6 +72,7 @@ PxFEMMaterial_PropertiesStop, PxFEMSoftBodyMaterial_PropertiesStart, PxFEMSoftBodyMaterial_Damping, PxFEMSoftBodyMaterial_DampingScale, +PxFEMSoftBodyMaterial_MaterialModel, PxFEMSoftBodyMaterial_ConcreteTypeName, PxFEMSoftBodyMaterial_PropertiesStop, PxParticleMaterial_PropertiesStart, @@ -202,7 +201,6 @@ PxConstraint_ConcreteTypeName, PxConstraint_UserData, PxConstraint_PropertiesStop, PxShape_PropertiesStart, -PxShape_GeometryType, PxShape_LocalPose, PxShape_SimulationFilterData, PxShape_QueryFilterData, @@ -212,6 +210,7 @@ PxShape_RestOffset, PxShape_DensityForFluid, PxShape_TorsionalPatchRadius, PxShape_MinTorsionalPatchRadius, +PxShape_InternalShapeIndex, PxShape_Flags, PxShape_IsExclusive, PxShape_Name, @@ -280,6 +279,7 @@ PxScene_PropertiesStart, PxScene_Flags, PxScene_Limits, PxScene_Timestamp, +PxScene_Name, PxScene_Actors, PxScene_SoftBodies, PxScene_Articulations, diff --git a/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjects.h b/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjects.h index 801952652..78ad76076 100644 --- a/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjects.h +++ b/physx/source/physxmetadata/core/include/PxAutoGeneratedMetaDataObjects.h @@ -44,13 +44,6 @@ }; template<> struct PxEnumTraits< physx::PxShapeFlag::Enum > { PxEnumTraits() : NameConversion( g_physx__PxShapeFlag__EnumConversion ) {} const PxU32ToName* NameConversion; }; - static PxU32ToName g_physx__PxBufferType__EnumConversion[] = { - { "eHOST", static_cast( physx::PxBufferType::eHOST ) }, - { "eDEVICE", static_cast( physx::PxBufferType::eDEVICE ) }, - { NULL, 0 } - }; - -template<> struct PxEnumTraits< physx::PxBufferType::Enum > { PxEnumTraits() : NameConversion( g_physx__PxBufferType__EnumConversion ) {} const PxU32ToName* NameConversion; }; class PxPhysics; struct PxPhysicsGeneratedValues { @@ -68,14 +61,12 @@ template<> struct PxEnumTraits< physx::PxBufferType::Enum > { PxEnumTraits() : N PxFactoryCollectionPropertyInfo HeightFields; PxFactoryCollectionPropertyInfo ConvexMeshes; PxFactoryCollectionPropertyInfo BVHs; - PxFactoryCollectionPropertyInfo BVHStructures; PxFactoryCollectionPropertyInfo Scenes; PxReadOnlyCollectionPropertyInfo Shapes; PxReadOnlyCollectionPropertyInfo Materials; PxReadOnlyCollectionPropertyInfo FEMSoftBodyMaterials; PxReadOnlyCollectionPropertyInfo FEMClothMaterials; PxReadOnlyCollectionPropertyInfo PBDMaterials; - PxFactoryCollectionPropertyInfo CustomMaterials; PX_PHYSX_CORE_API PxPhysicsGeneratedInfo(); template @@ -95,7 +86,7 @@ template<> struct PxEnumTraits< physx::PxBufferType::Enum > { PxEnumTraits() : N PX_UNUSED(inStartIndex); return inStartIndex; } - static PxU32 instancePropertyCount() { return 14; } + static PxU32 instancePropertyCount() { return 12; } static PxU32 totalPropertyCount() { return instancePropertyCount(); } template PxU32 visitInstanceProperties( TOperator inOperator, PxU32 inStartIndex = 0 ) const @@ -108,15 +99,13 @@ template<> struct PxEnumTraits< physx::PxBufferType::Enum > { PxEnumTraits() : N inOperator( HeightFields, inStartIndex + 3 );; inOperator( ConvexMeshes, inStartIndex + 4 );; inOperator( BVHs, inStartIndex + 5 );; - inOperator( BVHStructures, inStartIndex + 6 );; - inOperator( Scenes, inStartIndex + 7 );; - inOperator( Shapes, inStartIndex + 8 );; - inOperator( Materials, inStartIndex + 9 );; - inOperator( FEMSoftBodyMaterials, inStartIndex + 10 );; - inOperator( FEMClothMaterials, inStartIndex + 11 );; - inOperator( PBDMaterials, inStartIndex + 12 );; - inOperator( CustomMaterials, inStartIndex + 13 );; - return 14 + inStartIndex; + inOperator( Scenes, inStartIndex + 6 );; + inOperator( Shapes, inStartIndex + 7 );; + inOperator( Materials, inStartIndex + 8 );; + inOperator( FEMSoftBodyMaterials, inStartIndex + 9 );; + inOperator( FEMClothMaterials, inStartIndex + 10 );; + inOperator( PBDMaterials, inStartIndex + 11 );; + return 12 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -385,16 +374,25 @@ template<> struct PxEnumTraits< physx::PxCombineMode::Enum > { PxEnumTraits() : const PxFEMMaterialGeneratedInfo* getInfo() { return &Info; } }; + static PxU32ToName g_physx__PxFEMSoftBodyMaterialModel__EnumConversion[] = { + { "eCO_ROTATIONAL", static_cast( physx::PxFEMSoftBodyMaterialModel::eCO_ROTATIONAL ) }, + { "eNEO_HOOKEAN", static_cast( physx::PxFEMSoftBodyMaterialModel::eNEO_HOOKEAN ) }, + { NULL, 0 } + }; + +template<> struct PxEnumTraits< physx::PxFEMSoftBodyMaterialModel::Enum > { PxEnumTraits() : NameConversion( g_physx__PxFEMSoftBodyMaterialModel__EnumConversion ) {} const PxU32ToName* NameConversion; }; class PxFEMSoftBodyMaterial; struct PxFEMSoftBodyMaterialGeneratedValues : PxFEMMaterialGeneratedValues { PxReal Damping; PxReal DampingScale; + PxFEMSoftBodyMaterialModel::Enum MaterialModel; const char * ConcreteTypeName; PX_PHYSX_CORE_API PxFEMSoftBodyMaterialGeneratedValues( const PxFEMSoftBodyMaterial* inSource ); }; DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFEMSoftBodyMaterial, Damping, PxFEMSoftBodyMaterialGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFEMSoftBodyMaterial, DampingScale, PxFEMSoftBodyMaterialGeneratedValues) + DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFEMSoftBodyMaterial, MaterialModel, PxFEMSoftBodyMaterialGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFEMSoftBodyMaterial, ConcreteTypeName, PxFEMSoftBodyMaterialGeneratedValues) struct PxFEMSoftBodyMaterialGeneratedInfo : PxFEMMaterialGeneratedInfo @@ -402,6 +400,7 @@ template<> struct PxEnumTraits< physx::PxCombineMode::Enum > { PxEnumTraits() : static const char* getClassName() { return "PxFEMSoftBodyMaterial"; } PxPropertyInfo Damping; PxPropertyInfo DampingScale; + PxPropertyInfo MaterialModel; PxReadOnlyPropertyInfo ConcreteTypeName; PX_PHYSX_CORE_API PxFEMSoftBodyMaterialGeneratedInfo(); @@ -425,7 +424,7 @@ template<> struct PxEnumTraits< physx::PxCombineMode::Enum > { PxEnumTraits() : inStartIndex = PxFEMMaterialGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 3; } + static PxU32 instancePropertyCount() { return 4; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxFEMMaterialGeneratedInfo::totalPropertyCount(); } template @@ -435,8 +434,9 @@ template<> struct PxEnumTraits< physx::PxCombineMode::Enum > { PxEnumTraits() : PX_UNUSED(inStartIndex); inOperator( Damping, inStartIndex + 0 );; inOperator( DampingScale, inStartIndex + 1 );; - inOperator( ConcreteTypeName, inStartIndex + 2 );; - return 3 + inStartIndex; + inOperator( MaterialModel, inStartIndex + 2 );; + inOperator( ConcreteTypeName, inStartIndex + 3 );; + return 4 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -610,7 +610,6 @@ template<> struct PxEnumTraits< physx::PxCombineMode::Enum > { PxEnumTraits() : { "ePBD_PARTICLESYSTEM", static_cast( physx::PxActorType::ePBD_PARTICLESYSTEM ) }, { "eFLIP_PARTICLESYSTEM", static_cast( physx::PxActorType::eFLIP_PARTICLESYSTEM ) }, { "eMPM_PARTICLESYSTEM", static_cast( physx::PxActorType::eMPM_PARTICLESYSTEM ) }, - { "eCUSTOM_PARTICLESYSTEM", static_cast( physx::PxActorType::eCUSTOM_PARTICLESYSTEM ) }, { "eHAIRSYSTEM", static_cast( physx::PxActorType::eHAIRSYSTEM ) }, { NULL, 0 } }; @@ -1142,16 +1141,6 @@ template<> struct PxEnumTraits< physx::PxArticulationAxis::Enum > { PxEnumTraits }; template<> struct PxEnumTraits< physx::PxArticulationMotion::Enum > { PxEnumTraits() : NameConversion( g_physx__PxArticulationMotion__EnumConversion ) {} const PxU32ToName* NameConversion; }; - static PxU32ToName g_physx__PxArticulationDriveType__EnumConversion[] = { - { "eFORCE", static_cast( physx::PxArticulationDriveType::eFORCE ) }, - { "eACCELERATION", static_cast( physx::PxArticulationDriveType::eACCELERATION ) }, - { "eTARGET", static_cast( physx::PxArticulationDriveType::eTARGET ) }, - { "eVELOCITY", static_cast( physx::PxArticulationDriveType::eVELOCITY ) }, - { "eNONE", static_cast( physx::PxArticulationDriveType::eNONE ) }, - { NULL, 0 } - }; - -template<> struct PxEnumTraits< physx::PxArticulationDriveType::Enum > { PxEnumTraits() : NameConversion( g_physx__PxArticulationDriveType__EnumConversion ) {} const PxU32ToName* NameConversion; }; class PxArticulationJointReducedCoordinate; struct PxArticulationJointReducedCoordinateGeneratedValues { @@ -1268,6 +1257,7 @@ template<> struct PxEnumTraits< physx::PxArticulationFlag::Enum > { PxEnumTraits { "eROOT_VELOCITIES", static_cast( physx::PxArticulationCacheFlag::eROOT_VELOCITIES ) }, { "eSENSOR_FORCES", static_cast( physx::PxArticulationCacheFlag::eSENSOR_FORCES ) }, { "eJOINT_SOLVER_FORCES", static_cast( physx::PxArticulationCacheFlag::eJOINT_SOLVER_FORCES ) }, + { "eLINK_INCOMING_JOINT_FORCE", static_cast( physx::PxArticulationCacheFlag::eLINK_INCOMING_JOINT_FORCE ) }, { "eALL", static_cast( physx::PxArticulationCacheFlag::eALL ) }, { NULL, 0 } }; @@ -1447,9 +1437,6 @@ template<> struct PxEnumTraits< physx::PxArticulationCacheFlag::Enum > { PxEnumT static PxU32ToName g_physx__PxConstraintFlag__EnumConversion[] = { { "eBROKEN", static_cast( physx::PxConstraintFlag::eBROKEN ) }, - { "ePROJECT_TO_ACTOR0", static_cast( physx::PxConstraintFlag::ePROJECT_TO_ACTOR0 ) }, - { "ePROJECT_TO_ACTOR1", static_cast( physx::PxConstraintFlag::ePROJECT_TO_ACTOR1 ) }, - { "ePROJECTION", static_cast( physx::PxConstraintFlag::ePROJECTION ) }, { "eCOLLISION_ENABLED", static_cast( physx::PxConstraintFlag::eCOLLISION_ENABLED ) }, { "eVISUALIZATION", static_cast( physx::PxConstraintFlag::eVISUALIZATION ) }, { "eDRIVE_LIMITS_ARE_FORCES", static_cast( physx::PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES ) }, @@ -1539,26 +1526,9 @@ template<> struct PxEnumTraits< physx::PxConstraintFlag::Enum > { PxEnumTraits() const PxConstraintGeneratedInfo* getInfo() { return &Info; } }; - static PxU32ToName g_physx__PxGeometryType__EnumConversion[] = { - { "eSPHERE", static_cast( physx::PxGeometryType::eSPHERE ) }, - { "ePLANE", static_cast( physx::PxGeometryType::ePLANE ) }, - { "eCAPSULE", static_cast( physx::PxGeometryType::eCAPSULE ) }, - { "eBOX", static_cast( physx::PxGeometryType::eBOX ) }, - { "eCONVEXMESH", static_cast( physx::PxGeometryType::eCONVEXMESH ) }, - { "ePARTICLESYSTEM", static_cast( physx::PxGeometryType::ePARTICLESYSTEM ) }, - { "eTETRAHEDRONMESH", static_cast( physx::PxGeometryType::eTETRAHEDRONMESH ) }, - { "eTRIANGLEMESH", static_cast( physx::PxGeometryType::eTRIANGLEMESH ) }, - { "eHEIGHTFIELD", static_cast( physx::PxGeometryType::eHEIGHTFIELD ) }, - { "eHAIRSYSTEM", static_cast( physx::PxGeometryType::eHAIRSYSTEM ) }, - { "eCUSTOM", static_cast( physx::PxGeometryType::eCUSTOM ) }, - { NULL, 0 } - }; - -template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : NameConversion( g_physx__PxGeometryType__EnumConversion ) {} const PxU32ToName* NameConversion; }; class PxShape; struct PxShapeGeneratedValues : PxRefCountedGeneratedValues { - PxGeometryType::Enum GeometryType; PxTransform LocalPose; PxFilterData SimulationFilterData; PxFilterData QueryFilterData; @@ -1567,6 +1537,7 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : PxReal DensityForFluid; PxReal TorsionalPatchRadius; PxReal MinTorsionalPatchRadius; + PxU32 InternalShapeIndex; PxShapeFlags Flags; _Bool IsExclusive; const char * Name; @@ -1575,7 +1546,6 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : PxGeometryHolder Geom; PX_PHYSX_CORE_API PxShapeGeneratedValues( const PxShape* inSource ); }; - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, GeometryType, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, LocalPose, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, SimulationFilterData, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, QueryFilterData, PxShapeGeneratedValues) @@ -1584,6 +1554,7 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, DensityForFluid, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, TorsionalPatchRadius, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, MinTorsionalPatchRadius, PxShapeGeneratedValues) + DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, InternalShapeIndex, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, Flags, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, IsExclusive, PxShapeGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxShape, Name, PxShapeGeneratedValues) @@ -1594,7 +1565,6 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : : PxRefCountedGeneratedInfo { static const char* getClassName() { return "PxShape"; } - PxReadOnlyPropertyInfo GeometryType; PxPropertyInfo LocalPose; PxPropertyInfo SimulationFilterData; PxPropertyInfo QueryFilterData; @@ -1604,6 +1574,7 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : PxPropertyInfo DensityForFluid; PxPropertyInfo TorsionalPatchRadius; PxPropertyInfo MinTorsionalPatchRadius; + PxReadOnlyPropertyInfo InternalShapeIndex; PxPropertyInfo Flags; PxReadOnlyPropertyInfo IsExclusive; PxPropertyInfo Name; @@ -1640,16 +1611,16 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : { PX_UNUSED(inOperator); PX_UNUSED(inStartIndex); - inOperator( GeometryType, inStartIndex + 0 );; - inOperator( LocalPose, inStartIndex + 1 );; - inOperator( SimulationFilterData, inStartIndex + 2 );; - inOperator( QueryFilterData, inStartIndex + 3 );; - inOperator( Materials, inStartIndex + 4 );; - inOperator( ContactOffset, inStartIndex + 5 );; - inOperator( RestOffset, inStartIndex + 6 );; - inOperator( DensityForFluid, inStartIndex + 7 );; - inOperator( TorsionalPatchRadius, inStartIndex + 8 );; - inOperator( MinTorsionalPatchRadius, inStartIndex + 9 );; + inOperator( LocalPose, inStartIndex + 0 );; + inOperator( SimulationFilterData, inStartIndex + 1 );; + inOperator( QueryFilterData, inStartIndex + 2 );; + inOperator( Materials, inStartIndex + 3 );; + inOperator( ContactOffset, inStartIndex + 4 );; + inOperator( RestOffset, inStartIndex + 5 );; + inOperator( DensityForFluid, inStartIndex + 6 );; + inOperator( TorsionalPatchRadius, inStartIndex + 7 );; + inOperator( MinTorsionalPatchRadius, inStartIndex + 8 );; + inOperator( InternalShapeIndex, inStartIndex + 9 );; inOperator( Flags, inStartIndex + 10 );; inOperator( IsExclusive, inStartIndex + 11 );; inOperator( Name, inStartIndex + 12 );; @@ -1779,6 +1750,22 @@ template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : const PxTolerancesScaleGeneratedInfo* getInfo() { return &Info; } }; + static PxU32ToName g_physx__PxGeometryType__EnumConversion[] = { + { "eSPHERE", static_cast( physx::PxGeometryType::eSPHERE ) }, + { "ePLANE", static_cast( physx::PxGeometryType::ePLANE ) }, + { "eCAPSULE", static_cast( physx::PxGeometryType::eCAPSULE ) }, + { "eBOX", static_cast( physx::PxGeometryType::eBOX ) }, + { "eCONVEXMESH", static_cast( physx::PxGeometryType::eCONVEXMESH ) }, + { "ePARTICLESYSTEM", static_cast( physx::PxGeometryType::ePARTICLESYSTEM ) }, + { "eTETRAHEDRONMESH", static_cast( physx::PxGeometryType::eTETRAHEDRONMESH ) }, + { "eTRIANGLEMESH", static_cast( physx::PxGeometryType::eTRIANGLEMESH ) }, + { "eHEIGHTFIELD", static_cast( physx::PxGeometryType::eHEIGHTFIELD ) }, + { "eHAIRSYSTEM", static_cast( physx::PxGeometryType::eHAIRSYSTEM ) }, + { "eCUSTOM", static_cast( physx::PxGeometryType::eCUSTOM ) }, + { NULL, 0 } + }; + +template<> struct PxEnumTraits< physx::PxGeometryType::Enum > { PxEnumTraits() : NameConversion( g_physx__PxGeometryType__EnumConversion ) {} const PxU32ToName* NameConversion; }; class PxGeometry; struct PxGeometryGeneratedValues { @@ -2460,6 +2447,7 @@ template<> struct PxEnumTraits< physx::PxPruningStructureType::Enum > { PxEnumTr { "eENABLE_GPU_DYNAMICS", static_cast( physx::PxSceneFlag::eENABLE_GPU_DYNAMICS ) }, { "eENABLE_ENHANCED_DETERMINISM", static_cast( physx::PxSceneFlag::eENABLE_ENHANCED_DETERMINISM ) }, { "eENABLE_FRICTION_EVERY_ITERATION", static_cast( physx::PxSceneFlag::eENABLE_FRICTION_EVERY_ITERATION ) }, + { "eENABLE_DIRECT_GPU_API", static_cast( physx::PxSceneFlag::eENABLE_DIRECT_GPU_API ) }, { "eSUPPRESS_READBACK", static_cast( physx::PxSceneFlag::eSUPPRESS_READBACK ) }, { "eFORCE_READBACK", static_cast( physx::PxSceneFlag::eFORCE_READBACK ) }, { "eMUTABLE_FLAGS", static_cast( physx::PxSceneFlag::eMUTABLE_FLAGS ) }, @@ -2478,7 +2466,6 @@ template<> struct PxEnumTraits< physx::PxActorTypeFlag::Enum > { PxEnumTraits() { "ePBD", static_cast( physx::PxParticleSolverType::ePBD ) }, { "eFLIP", static_cast( physx::PxParticleSolverType::eFLIP ) }, { "eMPM", static_cast( physx::PxParticleSolverType::eMPM ) }, - { "eCUSTOM", static_cast( physx::PxParticleSolverType::eCUSTOM ) }, { NULL, 0 } }; @@ -2562,6 +2549,8 @@ template<> struct PxEnumTraits< physx::PxBroadPhaseType::Enum > { PxEnumTraits() { "eROOT_VELOCITY", static_cast( physx::PxArticulationGpuDataType::eROOT_VELOCITY ) }, { "eLINK_TRANSFORM", static_cast( physx::PxArticulationGpuDataType::eLINK_TRANSFORM ) }, { "eLINK_VELOCITY", static_cast( physx::PxArticulationGpuDataType::eLINK_VELOCITY ) }, + { "eLINK_ACCELERATION", static_cast( physx::PxArticulationGpuDataType::eLINK_ACCELERATION ) }, + { "eLINK_INCOMING_JOINT_FORCE", static_cast( physx::PxArticulationGpuDataType::eLINK_INCOMING_JOINT_FORCE ) }, { "eLINK_FORCE", static_cast( physx::PxArticulationGpuDataType::eLINK_FORCE ) }, { "eLINK_TORQUE", static_cast( physx::PxArticulationGpuDataType::eLINK_TORQUE ) }, { "eFIXED_TENDON", static_cast( physx::PxArticulationGpuDataType::eFIXED_TENDON ) }, @@ -2572,21 +2561,19 @@ template<> struct PxEnumTraits< physx::PxBroadPhaseType::Enum > { PxEnumTraits() }; template<> struct PxEnumTraits< physx::PxArticulationGpuDataType::Enum > { PxEnumTraits() : NameConversion( g_physx__PxArticulationGpuDataType__EnumConversion ) {} const PxU32ToName* NameConversion; }; - static PxU32ToName g_physx__PxSoftBodyDataFlag__EnumConversion[] = { - { "eTET_INDICES", static_cast( physx::PxSoftBodyDataFlag::eTET_INDICES ) }, - { "eTET_STRESS", static_cast( physx::PxSoftBodyDataFlag::eTET_STRESS ) }, - { "eTET_STRESSCOEFF", static_cast( physx::PxSoftBodyDataFlag::eTET_STRESSCOEFF ) }, - { "eTET_REST_POSES", static_cast( physx::PxSoftBodyDataFlag::eTET_REST_POSES ) }, - { "eTET_ROTATIONS", static_cast( physx::PxSoftBodyDataFlag::eTET_ROTATIONS ) }, - { "eTET_POSITION_INV_MASS", static_cast( physx::PxSoftBodyDataFlag::eTET_POSITION_INV_MASS ) }, - { "eSIM_TET_INDICES", static_cast( physx::PxSoftBodyDataFlag::eSIM_TET_INDICES ) }, - { "eSIM_VELOCITY_INV_MASS", static_cast( physx::PxSoftBodyDataFlag::eSIM_VELOCITY_INV_MASS ) }, - { "eSIM_POSITION_INV_MASS", static_cast( physx::PxSoftBodyDataFlag::eSIM_POSITION_INV_MASS ) }, - { "eSIM_KINEMATIC_TARGET", static_cast( physx::PxSoftBodyDataFlag::eSIM_KINEMATIC_TARGET ) }, + static PxU32ToName g_physx__PxSoftBodyGpuDataFlag__EnumConversion[] = { + { "eTET_INDICES", static_cast( physx::PxSoftBodyGpuDataFlag::eTET_INDICES ) }, + { "eTET_REST_POSES", static_cast( physx::PxSoftBodyGpuDataFlag::eTET_REST_POSES ) }, + { "eTET_ROTATIONS", static_cast( physx::PxSoftBodyGpuDataFlag::eTET_ROTATIONS ) }, + { "eTET_POSITION_INV_MASS", static_cast( physx::PxSoftBodyGpuDataFlag::eTET_POSITION_INV_MASS ) }, + { "eSIM_TET_INDICES", static_cast( physx::PxSoftBodyGpuDataFlag::eSIM_TET_INDICES ) }, + { "eSIM_TET_ROTATIONS", static_cast( physx::PxSoftBodyGpuDataFlag::eSIM_TET_ROTATIONS ) }, + { "eSIM_VELOCITY_INV_MASS", static_cast( physx::PxSoftBodyGpuDataFlag::eSIM_VELOCITY_INV_MASS ) }, + { "eSIM_POSITION_INV_MASS", static_cast( physx::PxSoftBodyGpuDataFlag::eSIM_POSITION_INV_MASS ) }, { NULL, 0 } }; -template<> struct PxEnumTraits< physx::PxSoftBodyDataFlag::Enum > { PxEnumTraits() : NameConversion( g_physx__PxSoftBodyDataFlag__EnumConversion ) {} const PxU32ToName* NameConversion; }; +template<> struct PxEnumTraits< physx::PxSoftBodyGpuDataFlag::Enum > { PxEnumTraits() : NameConversion( g_physx__PxSoftBodyGpuDataFlag__EnumConversion ) {} const PxU32ToName* NameConversion; }; static PxU32ToName g_physx__PxActorCacheFlag__EnumConversion[] = { { "eACTOR_DATA", static_cast( physx::PxActorCacheFlag::eACTOR_DATA ) }, { "eFORCE", static_cast( physx::PxActorCacheFlag::eFORCE ) }, @@ -2601,6 +2588,7 @@ template<> struct PxEnumTraits< physx::PxActorCacheFlag::Enum > { PxEnumTraits() PxSceneFlags Flags; PxSceneLimits Limits; PxU32 Timestamp; + const char * Name; PxCpuDispatcher * CpuDispatcher; PxCudaContextManager * CudaContextManager; PxSimulationEventCallback * SimulationEventCallback; @@ -2638,6 +2626,7 @@ template<> struct PxEnumTraits< physx::PxActorCacheFlag::Enum > { PxEnumTraits() DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, Flags, PxSceneGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, Limits, PxSceneGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, Timestamp, PxSceneGeneratedValues) + DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, Name, PxSceneGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, CpuDispatcher, PxSceneGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, CudaContextManager, PxSceneGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxScene, SimulationEventCallback, PxSceneGeneratedValues) @@ -2677,6 +2666,7 @@ template<> struct PxEnumTraits< physx::PxActorCacheFlag::Enum > { PxEnumTraits() PxReadOnlyPropertyInfo Flags; PxPropertyInfo Limits; PxReadOnlyPropertyInfo Timestamp; + PxPropertyInfo Name; PxReadOnlyFilteredCollectionPropertyInfo Actors; PxReadOnlyCollectionPropertyInfo SoftBodies; PxReadOnlyCollectionPropertyInfo Articulations; @@ -2738,7 +2728,7 @@ template<> struct PxEnumTraits< physx::PxActorCacheFlag::Enum > { PxEnumTraits() inStartIndex = PxSceneSQSystemGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 42; } + static PxU32 instancePropertyCount() { return 43; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxSceneSQSystemGeneratedInfo::totalPropertyCount(); } template @@ -2749,46 +2739,47 @@ template<> struct PxEnumTraits< physx::PxActorCacheFlag::Enum > { PxEnumTraits() inOperator( Flags, inStartIndex + 0 );; inOperator( Limits, inStartIndex + 1 );; inOperator( Timestamp, inStartIndex + 2 );; - inOperator( Actors, inStartIndex + 3 );; - inOperator( SoftBodies, inStartIndex + 4 );; - inOperator( Articulations, inStartIndex + 5 );; - inOperator( Constraints, inStartIndex + 6 );; - inOperator( Aggregates, inStartIndex + 7 );; - inOperator( CpuDispatcher, inStartIndex + 8 );; - inOperator( CudaContextManager, inStartIndex + 9 );; - inOperator( SimulationEventCallback, inStartIndex + 10 );; - inOperator( ContactModifyCallback, inStartIndex + 11 );; - inOperator( CCDContactModifyCallback, inStartIndex + 12 );; - inOperator( BroadPhaseCallback, inStartIndex + 13 );; - inOperator( FilterShaderDataSize, inStartIndex + 14 );; - inOperator( FilterShader, inStartIndex + 15 );; - inOperator( FilterCallback, inStartIndex + 16 );; - inOperator( KinematicKinematicFilteringMode, inStartIndex + 17 );; - inOperator( StaticKinematicFilteringMode, inStartIndex + 18 );; - inOperator( Gravity, inStartIndex + 19 );; - inOperator( BounceThresholdVelocity, inStartIndex + 20 );; - inOperator( CCDMaxPasses, inStartIndex + 21 );; - inOperator( CCDMaxSeparation, inStartIndex + 22 );; - inOperator( CCDThreshold, inStartIndex + 23 );; - inOperator( MaxBiasCoefficient, inStartIndex + 24 );; - inOperator( FrictionOffsetThreshold, inStartIndex + 25 );; - inOperator( FrictionCorrelationDistance, inStartIndex + 26 );; - inOperator( FrictionType, inStartIndex + 27 );; - inOperator( SolverType, inStartIndex + 28 );; - inOperator( VisualizationCullingBox, inStartIndex + 29 );; - inOperator( BroadPhaseType, inStartIndex + 30 );; - inOperator( BroadPhaseRegions, inStartIndex + 31 );; - inOperator( TaskManager, inStartIndex + 32 );; - inOperator( NbContactDataBlocks, inStartIndex + 33 );; - inOperator( MaxNbContactDataBlocksUsed, inStartIndex + 34 );; - inOperator( ContactReportStreamBufferSize, inStartIndex + 35 );; - inOperator( SolverBatchSize, inStartIndex + 36 );; - inOperator( SolverArticulationBatchSize, inStartIndex + 37 );; - inOperator( WakeCounterResetValue, inStartIndex + 38 );; - inOperator( GpuDynamicsConfig, inStartIndex + 39 );; - inOperator( UserData, inStartIndex + 40 );; - inOperator( SimulationStatistics, inStartIndex + 41 );; - return 42 + inStartIndex; + inOperator( Name, inStartIndex + 3 );; + inOperator( Actors, inStartIndex + 4 );; + inOperator( SoftBodies, inStartIndex + 5 );; + inOperator( Articulations, inStartIndex + 6 );; + inOperator( Constraints, inStartIndex + 7 );; + inOperator( Aggregates, inStartIndex + 8 );; + inOperator( CpuDispatcher, inStartIndex + 9 );; + inOperator( CudaContextManager, inStartIndex + 10 );; + inOperator( SimulationEventCallback, inStartIndex + 11 );; + inOperator( ContactModifyCallback, inStartIndex + 12 );; + inOperator( CCDContactModifyCallback, inStartIndex + 13 );; + inOperator( BroadPhaseCallback, inStartIndex + 14 );; + inOperator( FilterShaderDataSize, inStartIndex + 15 );; + inOperator( FilterShader, inStartIndex + 16 );; + inOperator( FilterCallback, inStartIndex + 17 );; + inOperator( KinematicKinematicFilteringMode, inStartIndex + 18 );; + inOperator( StaticKinematicFilteringMode, inStartIndex + 19 );; + inOperator( Gravity, inStartIndex + 20 );; + inOperator( BounceThresholdVelocity, inStartIndex + 21 );; + inOperator( CCDMaxPasses, inStartIndex + 22 );; + inOperator( CCDMaxSeparation, inStartIndex + 23 );; + inOperator( CCDThreshold, inStartIndex + 24 );; + inOperator( MaxBiasCoefficient, inStartIndex + 25 );; + inOperator( FrictionOffsetThreshold, inStartIndex + 26 );; + inOperator( FrictionCorrelationDistance, inStartIndex + 27 );; + inOperator( FrictionType, inStartIndex + 28 );; + inOperator( SolverType, inStartIndex + 29 );; + inOperator( VisualizationCullingBox, inStartIndex + 30 );; + inOperator( BroadPhaseType, inStartIndex + 31 );; + inOperator( BroadPhaseRegions, inStartIndex + 32 );; + inOperator( TaskManager, inStartIndex + 33 );; + inOperator( NbContactDataBlocks, inStartIndex + 34 );; + inOperator( MaxNbContactDataBlocksUsed, inStartIndex + 35 );; + inOperator( ContactReportStreamBufferSize, inStartIndex + 36 );; + inOperator( SolverBatchSize, inStartIndex + 37 );; + inOperator( SolverArticulationBatchSize, inStartIndex + 38 );; + inOperator( WakeCounterResetValue, inStartIndex + 39 );; + inOperator( GpuDynamicsConfig, inStartIndex + 40 );; + inOperator( UserData, inStartIndex + 41 );; + inOperator( SimulationStatistics, inStartIndex + 42 );; + return 43 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -3033,6 +3024,16 @@ template<> struct PxEnumTraits< physx::PxHeightFieldFlag::Enum > { PxEnumTraits( const PxArticulationLimitGeneratedInfo* getInfo() { return &Info; } }; + static PxU32ToName g_physx__PxArticulationDriveType__EnumConversion[] = { + { "eFORCE", static_cast( physx::PxArticulationDriveType::eFORCE ) }, + { "eACCELERATION", static_cast( physx::PxArticulationDriveType::eACCELERATION ) }, + { "eTARGET", static_cast( physx::PxArticulationDriveType::eTARGET ) }, + { "eVELOCITY", static_cast( physx::PxArticulationDriveType::eVELOCITY ) }, + { "eNONE", static_cast( physx::PxArticulationDriveType::eNONE ) }, + { NULL, 0 } + }; + +template<> struct PxEnumTraits< physx::PxArticulationDriveType::Enum > { PxEnumTraits() : NameConversion( g_physx__PxArticulationDriveType__EnumConversion ) {} const PxU32ToName* NameConversion; }; struct PxArticulationDrive; struct PxArticulationDriveGeneratedValues { diff --git a/physx/source/physxmetadata/core/src/PxAutoGeneratedMetaDataObjects.cpp b/physx/source/physxmetadata/core/src/PxAutoGeneratedMetaDataObjects.cpp index 74a91b0b1..9e1ca7a3b 100644 --- a/physx/source/physxmetadata/core/src/PxAutoGeneratedMetaDataObjects.cpp +++ b/physx/source/physxmetadata/core/src/PxAutoGeneratedMetaDataObjects.cpp @@ -60,9 +60,6 @@ PxConvexMesh * createPxPhysics_ConvexMeshes( PxPhysics* inObj, PxInputStream & i PxU32 getPxPhysics_BVHs( const PxPhysics* inObj, PxBVH ** outBuffer, PxU32 inBufSize ) { return inObj->getBVHs( outBuffer, inBufSize ); } PxU32 getNbPxPhysics_BVHs( const PxPhysics* inObj ) { return inObj->getNbBVHs( ); } PxBVH * createPxPhysics_BVHs( PxPhysics* inObj, PxInputStream & inCreateParam ){ return inObj->createBVH( inCreateParam ); } -PxU32 getPxPhysics_BVHStructures( const PxPhysics* inObj, PxBVHStructure ** outBuffer, PxU32 inBufSize ) { return inObj->getBVHStructures( outBuffer, inBufSize ); } -PxU32 getNbPxPhysics_BVHStructures( const PxPhysics* inObj ) { return inObj->getNbBVHStructures( ); } -PxBVHStructure * createPxPhysics_BVHStructures( PxPhysics* inObj, PxInputStream & inCreateParam ){ return inObj->createBVHStructure( inCreateParam ); } PxU32 getPxPhysics_Scenes( const PxPhysics* inObj, PxScene ** outBuffer, PxU32 inBufSize ) { return inObj->getScenes( outBuffer, inBufSize ); } PxU32 getNbPxPhysics_Scenes( const PxPhysics* inObj ) { return inObj->getNbScenes( ); } PxScene * createPxPhysics_Scenes( PxPhysics* inObj, const PxSceneDesc & inCreateParam ){ return inObj->createScene( inCreateParam ); } @@ -76,9 +73,6 @@ PxU32 getPxPhysics_FEMClothMaterials( const PxPhysics* inObj, PxFEMClothMaterial PxU32 getNbPxPhysics_FEMClothMaterials( const PxPhysics* inObj ) { return inObj->getNbFEMClothMaterials( ); } PxU32 getPxPhysics_PBDMaterials( const PxPhysics* inObj, PxPBDMaterial ** outBuffer, PxU32 inBufSize ) { return inObj->getPBDMaterials( outBuffer, inBufSize ); } PxU32 getNbPxPhysics_PBDMaterials( const PxPhysics* inObj ) { return inObj->getNbPBDMaterials( ); } -PxU32 getPxPhysics_CustomMaterials( const PxPhysics* inObj, PxCustomMaterial ** outBuffer, PxU32 inBufSize ) { return inObj->getCustomMaterials( outBuffer, inBufSize ); } -PxU32 getNbPxPhysics_CustomMaterials( const PxPhysics* inObj ) { return inObj->getNbCustomMaterials( ); } -PxCustomMaterial * createPxPhysics_CustomMaterials( PxPhysics* inObj, void * inCreateParam ){ return inObj->createCustomMaterial( inCreateParam ); } PX_PHYSX_CORE_API PxPhysicsGeneratedInfo::PxPhysicsGeneratedInfo() : TolerancesScale( "TolerancesScale", getPxPhysics_TolerancesScale) , TriangleMeshes( "TriangleMeshes", getPxPhysics_TriangleMeshes, getNbPxPhysics_TriangleMeshes, createPxPhysics_TriangleMeshes ) @@ -86,14 +80,12 @@ PX_PHYSX_CORE_API PxPhysicsGeneratedInfo::PxPhysicsGeneratedInfo() , HeightFields( "HeightFields", getPxPhysics_HeightFields, getNbPxPhysics_HeightFields, createPxPhysics_HeightFields ) , ConvexMeshes( "ConvexMeshes", getPxPhysics_ConvexMeshes, getNbPxPhysics_ConvexMeshes, createPxPhysics_ConvexMeshes ) , BVHs( "BVHs", getPxPhysics_BVHs, getNbPxPhysics_BVHs, createPxPhysics_BVHs ) - , BVHStructures( "BVHStructures", getPxPhysics_BVHStructures, getNbPxPhysics_BVHStructures, createPxPhysics_BVHStructures ) , Scenes( "Scenes", getPxPhysics_Scenes, getNbPxPhysics_Scenes, createPxPhysics_Scenes ) , Shapes( "Shapes", getPxPhysics_Shapes, getNbPxPhysics_Shapes ) , Materials( "Materials", getPxPhysics_Materials, getNbPxPhysics_Materials ) , FEMSoftBodyMaterials( "FEMSoftBodyMaterials", getPxPhysics_FEMSoftBodyMaterials, getNbPxPhysics_FEMSoftBodyMaterials ) , FEMClothMaterials( "FEMClothMaterials", getPxPhysics_FEMClothMaterials, getNbPxPhysics_FEMClothMaterials ) , PBDMaterials( "PBDMaterials", getPxPhysics_PBDMaterials, getNbPxPhysics_PBDMaterials ) - , CustomMaterials( "CustomMaterials", getPxPhysics_CustomMaterials, getNbPxPhysics_CustomMaterials, createPxPhysics_CustomMaterials ) {} PX_PHYSX_CORE_API PxPhysicsGeneratedValues::PxPhysicsGeneratedValues( const PxPhysics* inSource ) :TolerancesScale( getPxPhysics_TolerancesScale( inSource ) ) @@ -181,16 +173,20 @@ void setPxFEMSoftBodyMaterial_Damping( PxFEMSoftBodyMaterial* inObj, PxReal inAr PxReal getPxFEMSoftBodyMaterial_Damping( const PxFEMSoftBodyMaterial* inObj ) { return inObj->getDamping(); } void setPxFEMSoftBodyMaterial_DampingScale( PxFEMSoftBodyMaterial* inObj, PxReal inArg){ inObj->setDampingScale( inArg ); } PxReal getPxFEMSoftBodyMaterial_DampingScale( const PxFEMSoftBodyMaterial* inObj ) { return inObj->getDampingScale(); } +void setPxFEMSoftBodyMaterial_MaterialModel( PxFEMSoftBodyMaterial* inObj, PxFEMSoftBodyMaterialModel::Enum inArg){ inObj->setMaterialModel( inArg ); } +PxFEMSoftBodyMaterialModel::Enum getPxFEMSoftBodyMaterial_MaterialModel( const PxFEMSoftBodyMaterial* inObj ) { return inObj->getMaterialModel(); } const char * getPxFEMSoftBodyMaterial_ConcreteTypeName( const PxFEMSoftBodyMaterial* inObj ) { return inObj->getConcreteTypeName(); } PX_PHYSX_CORE_API PxFEMSoftBodyMaterialGeneratedInfo::PxFEMSoftBodyMaterialGeneratedInfo() : Damping( "Damping", setPxFEMSoftBodyMaterial_Damping, getPxFEMSoftBodyMaterial_Damping) , DampingScale( "DampingScale", setPxFEMSoftBodyMaterial_DampingScale, getPxFEMSoftBodyMaterial_DampingScale) + , MaterialModel( "MaterialModel", setPxFEMSoftBodyMaterial_MaterialModel, getPxFEMSoftBodyMaterial_MaterialModel) , ConcreteTypeName( "ConcreteTypeName", getPxFEMSoftBodyMaterial_ConcreteTypeName) {} PX_PHYSX_CORE_API PxFEMSoftBodyMaterialGeneratedValues::PxFEMSoftBodyMaterialGeneratedValues( const PxFEMSoftBodyMaterial* inSource ) :PxFEMMaterialGeneratedValues( inSource ) ,Damping( getPxFEMSoftBodyMaterial_Damping( inSource ) ) ,DampingScale( getPxFEMSoftBodyMaterial_DampingScale( inSource ) ) + ,MaterialModel( getPxFEMSoftBodyMaterial_MaterialModel( inSource ) ) ,ConcreteTypeName( getPxFEMSoftBodyMaterial_ConcreteTypeName( inSource ) ) { PX_UNUSED(inSource); @@ -654,7 +650,6 @@ PX_PHYSX_CORE_API PxConstraintGeneratedValues::PxConstraintGeneratedValues( cons getPxConstraint_Actors( inSource, Actors[0], Actors[1] ); getPxConstraint_BreakForce( inSource, BreakForce[0], BreakForce[1] ); } -PxGeometryType::Enum getPxShape_GeometryType( const PxShape* inObj ) { return inObj->getGeometryType(); } void setPxShape_LocalPose( PxShape* inObj, const PxTransform & inArg){ inObj->setLocalPose( inArg ); } PxTransform getPxShape_LocalPose( const PxShape* inObj ) { return inObj->getLocalPose(); } void setPxShape_SimulationFilterData( PxShape* inObj, const PxFilterData & inArg){ inObj->setSimulationFilterData( inArg ); } @@ -673,6 +668,7 @@ void setPxShape_TorsionalPatchRadius( PxShape* inObj, PxReal inArg){ inObj->setT PxReal getPxShape_TorsionalPatchRadius( const PxShape* inObj ) { return inObj->getTorsionalPatchRadius(); } void setPxShape_MinTorsionalPatchRadius( PxShape* inObj, PxReal inArg){ inObj->setMinTorsionalPatchRadius( inArg ); } PxReal getPxShape_MinTorsionalPatchRadius( const PxShape* inObj ) { return inObj->getMinTorsionalPatchRadius(); } +PxU32 getPxShape_InternalShapeIndex( const PxShape* inObj ) { return inObj->getInternalShapeIndex(); } void setPxShape_Flags( PxShape* inObj, PxShapeFlags inArg){ inObj->setFlags( inArg ); } PxShapeFlags getPxShape_Flags( const PxShape* inObj ) { return inObj->getFlags(); } _Bool getPxShape_IsExclusive( const PxShape* inObj ) { return inObj->isExclusive(); } @@ -682,8 +678,7 @@ const char * getPxShape_ConcreteTypeName( const PxShape* inObj ) { return inObj- inline void * getPxShapeUserData( const PxShape* inOwner ) { return inOwner->userData; } inline void setPxShapeUserData( PxShape* inOwner, void * inData) { inOwner->userData = inData; } PX_PHYSX_CORE_API PxShapeGeneratedInfo::PxShapeGeneratedInfo() - : GeometryType( "GeometryType", getPxShape_GeometryType) - , LocalPose( "LocalPose", setPxShape_LocalPose, getPxShape_LocalPose) + : LocalPose( "LocalPose", setPxShape_LocalPose, getPxShape_LocalPose) , SimulationFilterData( "SimulationFilterData", setPxShape_SimulationFilterData, getPxShape_SimulationFilterData) , QueryFilterData( "QueryFilterData", setPxShape_QueryFilterData, getPxShape_QueryFilterData) , Materials( "Materials", getPxShape_Materials, getNbPxShape_Materials ) @@ -692,6 +687,7 @@ PX_PHYSX_CORE_API PxShapeGeneratedInfo::PxShapeGeneratedInfo() , DensityForFluid( "DensityForFluid", setPxShape_DensityForFluid, getPxShape_DensityForFluid) , TorsionalPatchRadius( "TorsionalPatchRadius", setPxShape_TorsionalPatchRadius, getPxShape_TorsionalPatchRadius) , MinTorsionalPatchRadius( "MinTorsionalPatchRadius", setPxShape_MinTorsionalPatchRadius, getPxShape_MinTorsionalPatchRadius) + , InternalShapeIndex( "InternalShapeIndex", getPxShape_InternalShapeIndex) , Flags( "Flags", setPxShape_Flags, getPxShape_Flags) , IsExclusive( "IsExclusive", getPxShape_IsExclusive) , Name( "Name", setPxShape_Name, getPxShape_Name) @@ -700,7 +696,6 @@ PX_PHYSX_CORE_API PxShapeGeneratedInfo::PxShapeGeneratedInfo() {} PX_PHYSX_CORE_API PxShapeGeneratedValues::PxShapeGeneratedValues( const PxShape* inSource ) :PxRefCountedGeneratedValues( inSource ) - ,GeometryType( getPxShape_GeometryType( inSource ) ) ,LocalPose( getPxShape_LocalPose( inSource ) ) ,SimulationFilterData( getPxShape_SimulationFilterData( inSource ) ) ,QueryFilterData( getPxShape_QueryFilterData( inSource ) ) @@ -709,6 +704,7 @@ PX_PHYSX_CORE_API PxShapeGeneratedValues::PxShapeGeneratedValues( const PxShape* ,DensityForFluid( getPxShape_DensityForFluid( inSource ) ) ,TorsionalPatchRadius( getPxShape_TorsionalPatchRadius( inSource ) ) ,MinTorsionalPatchRadius( getPxShape_MinTorsionalPatchRadius( inSource ) ) + ,InternalShapeIndex( getPxShape_InternalShapeIndex( inSource ) ) ,Flags( getPxShape_Flags( inSource ) ) ,IsExclusive( getPxShape_IsExclusive( inSource ) ) ,Name( getPxShape_Name( inSource ) ) @@ -923,6 +919,8 @@ PxSceneFlags getPxScene_Flags( const PxScene* inObj ) { return inObj->getFlags() void setPxScene_Limits( PxScene* inObj, const PxSceneLimits & inArg){ inObj->setLimits( inArg ); } PxSceneLimits getPxScene_Limits( const PxScene* inObj ) { return inObj->getLimits(); } PxU32 getPxScene_Timestamp( const PxScene* inObj ) { return inObj->getTimestamp(); } +void setPxScene_Name( PxScene* inObj, const char * inArg){ inObj->setName( inArg ); } +const char * getPxScene_Name( const PxScene* inObj ) { return inObj->getName(); } PxU32 getPxScene_Actors( const PxScene* inObj, PxActorTypeFlags inFilter, PxActor ** outBuffer, PxU32 inBufSize ) { return inObj->getActors( inFilter, outBuffer, inBufSize ); } PxU32 getNbPxScene_Actors( const PxScene* inObj, PxActorTypeFlags inFilter ) { return inObj->getNbActors( inFilter ); } PxU32 getPxScene_SoftBodies( const PxScene* inObj, PxSoftBody ** outBuffer, PxU32 inBufSize ) { return inObj->getSoftBodies( outBuffer, inBufSize ); } @@ -987,6 +985,7 @@ PX_PHYSX_CORE_API PxSceneGeneratedInfo::PxSceneGeneratedInfo() : Flags( "Flags", getPxScene_Flags) , Limits( "Limits", setPxScene_Limits, getPxScene_Limits) , Timestamp( "Timestamp", getPxScene_Timestamp) + , Name( "Name", setPxScene_Name, getPxScene_Name) , Actors( "Actors", getPxScene_Actors, getNbPxScene_Actors ) , SoftBodies( "SoftBodies", getPxScene_SoftBodies, getNbPxScene_SoftBodies ) , Articulations( "Articulations", getPxScene_Articulations, getNbPxScene_Articulations ) @@ -1031,6 +1030,7 @@ PX_PHYSX_CORE_API PxSceneGeneratedValues::PxSceneGeneratedValues( const PxScene* ,Flags( getPxScene_Flags( inSource ) ) ,Limits( getPxScene_Limits( inSource ) ) ,Timestamp( getPxScene_Timestamp( inSource ) ) + ,Name( getPxScene_Name( inSource ) ) ,CpuDispatcher( getPxScene_CpuDispatcher( inSource ) ) ,CudaContextManager( getPxScene_CudaContextManager( inSource ) ) ,SimulationEventCallback( getPxScene_SimulationEventCallback( inSource ) ) diff --git a/physx/source/physxmetadata/core/src/PxMetaDataObjects.cpp b/physx/source/physxmetadata/core/src/PxMetaDataObjects.cpp index e309119ba..db68da0b9 100644 --- a/physx/source/physxmetadata/core/src/PxMetaDataObjects.cpp +++ b/physx/source/physxmetadata/core/src/PxMetaDataObjects.cpp @@ -34,16 +34,31 @@ using namespace physx; -PX_PHYSX_CORE_API PxGeometryType::Enum PxShapeGeomPropertyHelper::getGeometryType(const PxShape* inShape) const { return inShape->getGeometryType(); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxBoxGeometry& geometry) const { return inShape->getBoxGeometry( geometry ); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxSphereGeometry& geometry) const { return inShape->getSphereGeometry( geometry ); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxCapsuleGeometry& geometry) const { return inShape->getCapsuleGeometry( geometry ); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxPlaneGeometry& geometry) const { return inShape->getPlaneGeometry( geometry ); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxConvexMeshGeometry& geometry) const { return inShape->getConvexMeshGeometry( geometry ); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxTetrahedronMeshGeometry& geometry) const { return inShape->getTetrahedronMeshGeometry(geometry); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxParticleSystemGeometry& geometry) const { return inShape->getParticleSystemGeometry(geometry); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxTriangleMeshGeometry& geometry) const { return inShape->getTriangleMeshGeometry( geometry ); } -PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxHeightFieldGeometry& geometry) const { return inShape->getHeightFieldGeometry( geometry ); } +namespace { + +template +PX_FORCE_INLINE bool getGeometryT(PxGeometryType::Enum type, const PxShape* inShape, T& geom) +{ + const PxGeometry& inGeometry = inShape->getGeometry(); + if(inShape == NULL || inGeometry.getType() != type) + return false; + + geom = static_cast(inGeometry); + return true; +} + +} + +PX_PHYSX_CORE_API PxGeometryType::Enum PxShapeGeomPropertyHelper::getGeometryType(const PxShape* inShape) const { return inShape->getGeometry().getType(); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxBoxGeometry& geometry) const { return getGeometryT(PxGeometryType::eBOX, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxSphereGeometry& geometry) const { return getGeometryT(PxGeometryType::eSPHERE, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxCapsuleGeometry& geometry) const { return getGeometryT(PxGeometryType::eCAPSULE, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxPlaneGeometry& geometry) const { return getGeometryT(PxGeometryType::ePLANE, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxConvexMeshGeometry& geometry) const { return getGeometryT(PxGeometryType::eCONVEXMESH, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxTetrahedronMeshGeometry& geometry) const { return getGeometryT(PxGeometryType::eTETRAHEDRONMESH, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxParticleSystemGeometry& geometry) const { return getGeometryT(PxGeometryType::ePARTICLESYSTEM, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxTriangleMeshGeometry& geometry) const { return getGeometryT(PxGeometryType::eTRIANGLEMESH, inShape, geometry); } +PX_PHYSX_CORE_API bool PxShapeGeomPropertyHelper::getGeometry(const PxShape* inShape, PxHeightFieldGeometry& geometry) const { return getGeometryT(PxGeometryType::eHEIGHTFIELD, inShape, geometry); } PX_PHYSX_CORE_API void PxShapeMaterialsPropertyHelper::setMaterials(PxShape* inShape, PxMaterial*const* materials, PxU16 materialCount) const { diff --git a/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjectNames.h b/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjectNames.h index 394903434..e3833ca18 100644 --- a/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjectNames.h +++ b/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjectNames.h @@ -72,8 +72,6 @@ PxD6Joint_SwingLimit, PxD6Joint_PyramidSwingLimit, PxD6Joint_Drive, PxD6Joint_DrivePosition, -PxD6Joint_ProjectionLinearTolerance, -PxD6Joint_ProjectionAngularTolerance, PxD6Joint_ConcreteTypeName, PxD6Joint_PropertiesStop, PxDistanceJoint_PropertiesStart, @@ -83,7 +81,6 @@ PxDistanceJoint_MaxDistance, PxDistanceJoint_Tolerance, PxDistanceJoint_Stiffness, PxDistanceJoint_Damping, -PxDistanceJoint_ContactDistance, PxDistanceJoint_DistanceJointFlags, PxDistanceJoint_ConcreteTypeName, PxDistanceJoint_PropertiesStop, @@ -96,8 +93,6 @@ PxContactJoint_BounceThreshold, PxContactJoint_ConcreteTypeName, PxContactJoint_PropertiesStop, PxFixedJoint_PropertiesStart, -PxFixedJoint_ProjectionLinearTolerance, -PxFixedJoint_ProjectionAngularTolerance, PxFixedJoint_ConcreteTypeName, PxFixedJoint_PropertiesStop, PxPrismaticJoint_PropertiesStart, @@ -105,8 +100,6 @@ PxPrismaticJoint_Position, PxPrismaticJoint_Velocity, PxPrismaticJoint_Limit, PxPrismaticJoint_PrismaticJointFlags, -PxPrismaticJoint_ProjectionLinearTolerance, -PxPrismaticJoint_ProjectionAngularTolerance, PxPrismaticJoint_ConcreteTypeName, PxPrismaticJoint_PropertiesStop, PxRevoluteJoint_PropertiesStart, @@ -117,8 +110,6 @@ PxRevoluteJoint_DriveVelocity, PxRevoluteJoint_DriveForceLimit, PxRevoluteJoint_DriveGearRatio, PxRevoluteJoint_RevoluteJointFlags, -PxRevoluteJoint_ProjectionLinearTolerance, -PxRevoluteJoint_ProjectionAngularTolerance, PxRevoluteJoint_ConcreteTypeName, PxRevoluteJoint_PropertiesStop, PxSphericalJoint_PropertiesStart, @@ -126,7 +117,6 @@ PxSphericalJoint_LimitCone, PxSphericalJoint_SwingYAngle, PxSphericalJoint_SwingZAngle, PxSphericalJoint_SphericalJointFlags, -PxSphericalJoint_ProjectionLinearTolerance, PxSphericalJoint_ConcreteTypeName, PxSphericalJoint_PropertiesStop, PxJointLimitParameters_PropertiesStart, @@ -134,7 +124,6 @@ PxJointLimitParameters_Restitution, PxJointLimitParameters_BounceThreshold, PxJointLimitParameters_Stiffness, PxJointLimitParameters_Damping, -PxJointLimitParameters_ContactDistance_deprecated, PxJointLimitParameters_PropertiesStop, PxJointLinearLimit_PropertiesStart, PxJointLinearLimit_Value, diff --git a/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjects.h b/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjects.h index 3d2b8bbe3..e42aa27bb 100644 --- a/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjects.h +++ b/physx/source/physxmetadata/extensions/include/PxExtensionAutoGeneratedMetaDataObjects.h @@ -303,8 +303,6 @@ template<> struct PxEnumTraits< physx::PxD6Drive::Enum > { PxEnumTraits() : Name PxJointLimitPyramid PyramidSwingLimit; PxD6JointDrive Drive[physx::PxD6Drive::eCOUNT]; PxTransform DrivePosition; - PxReal ProjectionLinearTolerance; - PxReal ProjectionAngularTolerance; const char * ConcreteTypeName; PxD6JointGeneratedValues( const PxD6Joint* inSource ); }; @@ -320,8 +318,6 @@ template<> struct PxEnumTraits< physx::PxD6Drive::Enum > { PxEnumTraits() : Name DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxD6Joint, PyramidSwingLimit, PxD6JointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxD6Joint, Drive, PxD6JointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxD6Joint, DrivePosition, PxD6JointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxD6Joint, ProjectionLinearTolerance, PxD6JointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxD6Joint, ProjectionAngularTolerance, PxD6JointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxD6Joint, ConcreteTypeName, PxD6JointGeneratedValues) struct PxD6JointGeneratedInfo : PxJointGeneratedInfo @@ -339,8 +335,6 @@ template<> struct PxEnumTraits< physx::PxD6Drive::Enum > { PxEnumTraits() : Name PxPropertyInfo PyramidSwingLimit; PxIndexedPropertyInfo Drive; PxPropertyInfo DrivePosition; - PxPropertyInfo ProjectionLinearTolerance; - PxPropertyInfo ProjectionAngularTolerance; PxReadOnlyPropertyInfo ConcreteTypeName; PxD6JointGeneratedInfo(); @@ -364,7 +358,7 @@ template<> struct PxEnumTraits< physx::PxD6Drive::Enum > { PxEnumTraits() : Name inStartIndex = PxJointGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 15; } + static PxU32 instancePropertyCount() { return 13; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxJointGeneratedInfo::totalPropertyCount(); } template @@ -384,10 +378,8 @@ template<> struct PxEnumTraits< physx::PxD6Drive::Enum > { PxEnumTraits() : Name inOperator( PyramidSwingLimit, inStartIndex + 9 );; inOperator( Drive, inStartIndex + 10 );; inOperator( DrivePosition, inStartIndex + 11 );; - inOperator( ProjectionLinearTolerance, inStartIndex + 12 );; - inOperator( ProjectionAngularTolerance, inStartIndex + 13 );; - inOperator( ConcreteTypeName, inStartIndex + 14 );; - return 15 + inStartIndex; + inOperator( ConcreteTypeName, inStartIndex + 12 );; + return 13 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -413,7 +405,6 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait PxReal Tolerance; PxReal Stiffness; PxReal Damping; - PxReal ContactDistance; PxDistanceJointFlags DistanceJointFlags; const char * ConcreteTypeName; PxDistanceJointGeneratedValues( const PxDistanceJoint* inSource ); @@ -424,7 +415,6 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxDistanceJoint, Tolerance, PxDistanceJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxDistanceJoint, Stiffness, PxDistanceJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxDistanceJoint, Damping, PxDistanceJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxDistanceJoint, ContactDistance, PxDistanceJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxDistanceJoint, DistanceJointFlags, PxDistanceJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxDistanceJoint, ConcreteTypeName, PxDistanceJointGeneratedValues) struct PxDistanceJointGeneratedInfo @@ -437,7 +427,6 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait PxPropertyInfo Tolerance; PxPropertyInfo Stiffness; PxPropertyInfo Damping; - PxPropertyInfo ContactDistance; PxPropertyInfo DistanceJointFlags; PxReadOnlyPropertyInfo ConcreteTypeName; @@ -462,7 +451,7 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait inStartIndex = PxJointGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 9; } + static PxU32 instancePropertyCount() { return 8; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxJointGeneratedInfo::totalPropertyCount(); } template @@ -476,10 +465,9 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait inOperator( Tolerance, inStartIndex + 3 );; inOperator( Stiffness, inStartIndex + 4 );; inOperator( Damping, inStartIndex + 5 );; - inOperator( ContactDistance, inStartIndex + 6 );; - inOperator( DistanceJointFlags, inStartIndex + 7 );; - inOperator( ConcreteTypeName, inStartIndex + 8 );; - return 9 + inStartIndex; + inOperator( DistanceJointFlags, inStartIndex + 6 );; + inOperator( ConcreteTypeName, inStartIndex + 7 );; + return 8 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -563,20 +551,14 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait class PxFixedJoint; struct PxFixedJointGeneratedValues : PxJointGeneratedValues { - PxReal ProjectionLinearTolerance; - PxReal ProjectionAngularTolerance; const char * ConcreteTypeName; PxFixedJointGeneratedValues( const PxFixedJoint* inSource ); }; - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFixedJoint, ProjectionLinearTolerance, PxFixedJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFixedJoint, ProjectionAngularTolerance, PxFixedJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxFixedJoint, ConcreteTypeName, PxFixedJointGeneratedValues) struct PxFixedJointGeneratedInfo : PxJointGeneratedInfo { static const char* getClassName() { return "PxFixedJoint"; } - PxPropertyInfo ProjectionLinearTolerance; - PxPropertyInfo ProjectionAngularTolerance; PxReadOnlyPropertyInfo ConcreteTypeName; PxFixedJointGeneratedInfo(); @@ -600,7 +582,7 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait inStartIndex = PxJointGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 3; } + static PxU32 instancePropertyCount() { return 1; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxJointGeneratedInfo::totalPropertyCount(); } template @@ -608,10 +590,8 @@ template<> struct PxEnumTraits< physx::PxDistanceJointFlag::Enum > { PxEnumTrait { PX_UNUSED(inOperator); PX_UNUSED(inStartIndex); - inOperator( ProjectionLinearTolerance, inStartIndex + 0 );; - inOperator( ProjectionAngularTolerance, inStartIndex + 1 );; - inOperator( ConcreteTypeName, inStartIndex + 2 );; - return 3 + inStartIndex; + inOperator( ConcreteTypeName, inStartIndex + 0 );; + return 1 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -633,8 +613,6 @@ template<> struct PxEnumTraits< physx::PxPrismaticJointFlag::Enum > { PxEnumTrai PxReal Velocity; PxJointLinearLimitPair Limit; PxPrismaticJointFlags PrismaticJointFlags; - PxReal ProjectionLinearTolerance; - PxReal ProjectionAngularTolerance; const char * ConcreteTypeName; PxPrismaticJointGeneratedValues( const PxPrismaticJoint* inSource ); }; @@ -642,8 +620,6 @@ template<> struct PxEnumTraits< physx::PxPrismaticJointFlag::Enum > { PxEnumTrai DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxPrismaticJoint, Velocity, PxPrismaticJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxPrismaticJoint, Limit, PxPrismaticJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxPrismaticJoint, PrismaticJointFlags, PxPrismaticJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxPrismaticJoint, ProjectionLinearTolerance, PxPrismaticJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxPrismaticJoint, ProjectionAngularTolerance, PxPrismaticJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxPrismaticJoint, ConcreteTypeName, PxPrismaticJointGeneratedValues) struct PxPrismaticJointGeneratedInfo : PxJointGeneratedInfo @@ -653,8 +629,6 @@ template<> struct PxEnumTraits< physx::PxPrismaticJointFlag::Enum > { PxEnumTrai PxReadOnlyPropertyInfo Velocity; PxPropertyInfo Limit; PxPropertyInfo PrismaticJointFlags; - PxPropertyInfo ProjectionLinearTolerance; - PxPropertyInfo ProjectionAngularTolerance; PxReadOnlyPropertyInfo ConcreteTypeName; PxPrismaticJointGeneratedInfo(); @@ -678,7 +652,7 @@ template<> struct PxEnumTraits< physx::PxPrismaticJointFlag::Enum > { PxEnumTrai inStartIndex = PxJointGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 7; } + static PxU32 instancePropertyCount() { return 5; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxJointGeneratedInfo::totalPropertyCount(); } template @@ -690,10 +664,8 @@ template<> struct PxEnumTraits< physx::PxPrismaticJointFlag::Enum > { PxEnumTrai inOperator( Velocity, inStartIndex + 1 );; inOperator( Limit, inStartIndex + 2 );; inOperator( PrismaticJointFlags, inStartIndex + 3 );; - inOperator( ProjectionLinearTolerance, inStartIndex + 4 );; - inOperator( ProjectionAngularTolerance, inStartIndex + 5 );; - inOperator( ConcreteTypeName, inStartIndex + 6 );; - return 7 + inStartIndex; + inOperator( ConcreteTypeName, inStartIndex + 4 );; + return 5 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -720,8 +692,6 @@ template<> struct PxEnumTraits< physx::PxRevoluteJointFlag::Enum > { PxEnumTrait PxReal DriveForceLimit; PxReal DriveGearRatio; PxRevoluteJointFlags RevoluteJointFlags; - PxReal ProjectionLinearTolerance; - PxReal ProjectionAngularTolerance; const char * ConcreteTypeName; PxRevoluteJointGeneratedValues( const PxRevoluteJoint* inSource ); }; @@ -732,8 +702,6 @@ template<> struct PxEnumTraits< physx::PxRevoluteJointFlag::Enum > { PxEnumTrait DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxRevoluteJoint, DriveForceLimit, PxRevoluteJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxRevoluteJoint, DriveGearRatio, PxRevoluteJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxRevoluteJoint, RevoluteJointFlags, PxRevoluteJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxRevoluteJoint, ProjectionLinearTolerance, PxRevoluteJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxRevoluteJoint, ProjectionAngularTolerance, PxRevoluteJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxRevoluteJoint, ConcreteTypeName, PxRevoluteJointGeneratedValues) struct PxRevoluteJointGeneratedInfo : PxJointGeneratedInfo @@ -746,8 +714,6 @@ template<> struct PxEnumTraits< physx::PxRevoluteJointFlag::Enum > { PxEnumTrait PxPropertyInfo DriveForceLimit; PxPropertyInfo DriveGearRatio; PxPropertyInfo RevoluteJointFlags; - PxPropertyInfo ProjectionLinearTolerance; - PxPropertyInfo ProjectionAngularTolerance; PxReadOnlyPropertyInfo ConcreteTypeName; PxRevoluteJointGeneratedInfo(); @@ -771,7 +737,7 @@ template<> struct PxEnumTraits< physx::PxRevoluteJointFlag::Enum > { PxEnumTrait inStartIndex = PxJointGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 10; } + static PxU32 instancePropertyCount() { return 8; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxJointGeneratedInfo::totalPropertyCount(); } template @@ -786,10 +752,8 @@ template<> struct PxEnumTraits< physx::PxRevoluteJointFlag::Enum > { PxEnumTrait inOperator( DriveForceLimit, inStartIndex + 4 );; inOperator( DriveGearRatio, inStartIndex + 5 );; inOperator( RevoluteJointFlags, inStartIndex + 6 );; - inOperator( ProjectionLinearTolerance, inStartIndex + 7 );; - inOperator( ProjectionAngularTolerance, inStartIndex + 8 );; - inOperator( ConcreteTypeName, inStartIndex + 9 );; - return 10 + inStartIndex; + inOperator( ConcreteTypeName, inStartIndex + 7 );; + return 8 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -811,7 +775,6 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai PxReal SwingYAngle; PxReal SwingZAngle; PxSphericalJointFlags SphericalJointFlags; - PxReal ProjectionLinearTolerance; const char * ConcreteTypeName; PxSphericalJointGeneratedValues( const PxSphericalJoint* inSource ); }; @@ -819,7 +782,6 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxSphericalJoint, SwingYAngle, PxSphericalJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxSphericalJoint, SwingZAngle, PxSphericalJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxSphericalJoint, SphericalJointFlags, PxSphericalJointGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxSphericalJoint, ProjectionLinearTolerance, PxSphericalJointGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxSphericalJoint, ConcreteTypeName, PxSphericalJointGeneratedValues) struct PxSphericalJointGeneratedInfo : PxJointGeneratedInfo @@ -829,7 +791,6 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai PxReadOnlyPropertyInfo SwingYAngle; PxReadOnlyPropertyInfo SwingZAngle; PxPropertyInfo SphericalJointFlags; - PxPropertyInfo ProjectionLinearTolerance; PxReadOnlyPropertyInfo ConcreteTypeName; PxSphericalJointGeneratedInfo(); @@ -853,7 +814,7 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai inStartIndex = PxJointGeneratedInfo::visitInstanceProperties( inOperator, inStartIndex ); return inStartIndex; } - static PxU32 instancePropertyCount() { return 6; } + static PxU32 instancePropertyCount() { return 5; } static PxU32 totalPropertyCount() { return instancePropertyCount() + PxJointGeneratedInfo::totalPropertyCount(); } template @@ -865,9 +826,8 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai inOperator( SwingYAngle, inStartIndex + 1 );; inOperator( SwingZAngle, inStartIndex + 2 );; inOperator( SphericalJointFlags, inStartIndex + 3 );; - inOperator( ProjectionLinearTolerance, inStartIndex + 4 );; - inOperator( ConcreteTypeName, inStartIndex + 5 );; - return 6 + inStartIndex; + inOperator( ConcreteTypeName, inStartIndex + 4 );; + return 5 + inStartIndex; } }; template<> struct PxClassInfoTraits @@ -883,14 +843,12 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai PxReal BounceThreshold; PxReal Stiffness; PxReal Damping; - PxReal ContactDistance_deprecated; PxJointLimitParametersGeneratedValues( const PxJointLimitParameters* inSource ); }; DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxJointLimitParameters, Restitution, PxJointLimitParametersGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxJointLimitParameters, BounceThreshold, PxJointLimitParametersGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxJointLimitParameters, Stiffness, PxJointLimitParametersGeneratedValues) DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxJointLimitParameters, Damping, PxJointLimitParametersGeneratedValues) - DEFINE_PROPERTY_TO_VALUE_STRUCT_MAP( PxJointLimitParameters, ContactDistance_deprecated, PxJointLimitParametersGeneratedValues) struct PxJointLimitParametersGeneratedInfo { @@ -899,7 +857,6 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai PxPropertyInfo BounceThreshold; PxPropertyInfo Stiffness; PxPropertyInfo Damping; - PxPropertyInfo ContactDistance_deprecated; PxJointLimitParametersGeneratedInfo(); template @@ -919,7 +876,7 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai PX_UNUSED(inStartIndex); return inStartIndex; } - static PxU32 instancePropertyCount() { return 5; } + static PxU32 instancePropertyCount() { return 4; } static PxU32 totalPropertyCount() { return instancePropertyCount(); } template PxU32 visitInstanceProperties( TOperator inOperator, PxU32 inStartIndex = 0 ) const @@ -930,8 +887,7 @@ template<> struct PxEnumTraits< physx::PxSphericalJointFlag::Enum > { PxEnumTrai inOperator( BounceThreshold, inStartIndex + 1 );; inOperator( Stiffness, inStartIndex + 2 );; inOperator( Damping, inStartIndex + 3 );; - inOperator( ContactDistance_deprecated, inStartIndex + 4 );; - return 5 + inStartIndex; + return 4 + inStartIndex; } }; template<> struct PxClassInfoTraits diff --git a/physx/source/physxmetadata/extensions/src/PxExtensionAutoGeneratedMetaDataObjects.cpp b/physx/source/physxmetadata/extensions/src/PxExtensionAutoGeneratedMetaDataObjects.cpp index d1c185cf1..837f8e10a 100644 --- a/physx/source/physxmetadata/extensions/src/PxExtensionAutoGeneratedMetaDataObjects.cpp +++ b/physx/source/physxmetadata/extensions/src/PxExtensionAutoGeneratedMetaDataObjects.cpp @@ -155,10 +155,6 @@ void setPxD6Joint_Drive( PxD6Joint* inObj, PxD6Drive::Enum inIndex, PxD6JointDri PxD6JointDrive getPxD6Joint_Drive( const PxD6Joint* inObj, PxD6Drive::Enum inIndex ) { return inObj->getDrive( inIndex ); } void setPxD6Joint_DrivePosition( PxD6Joint* inObj, const PxTransform & inArg){ inObj->setDrivePosition( inArg ); } PxTransform getPxD6Joint_DrivePosition( const PxD6Joint* inObj ) { return inObj->getDrivePosition(); } -void setPxD6Joint_ProjectionLinearTolerance( PxD6Joint* inObj, PxReal inArg){ inObj->setProjectionLinearTolerance( inArg ); } -PxReal getPxD6Joint_ProjectionLinearTolerance( const PxD6Joint* inObj ) { return inObj->getProjectionLinearTolerance(); } -void setPxD6Joint_ProjectionAngularTolerance( PxD6Joint* inObj, PxReal inArg){ inObj->setProjectionAngularTolerance( inArg ); } -PxReal getPxD6Joint_ProjectionAngularTolerance( const PxD6Joint* inObj ) { return inObj->getProjectionAngularTolerance(); } const char * getPxD6Joint_ConcreteTypeName( const PxD6Joint* inObj ) { return inObj->getConcreteTypeName(); } PxD6JointGeneratedInfo::PxD6JointGeneratedInfo() : Motion( "Motion", setPxD6Joint_Motion, getPxD6Joint_Motion) @@ -173,8 +169,6 @@ const char * getPxD6Joint_ConcreteTypeName( const PxD6Joint* inObj ) { return in , PyramidSwingLimit( "PyramidSwingLimit", setPxD6Joint_PyramidSwingLimit, getPxD6Joint_PyramidSwingLimit) , Drive( "Drive", setPxD6Joint_Drive, getPxD6Joint_Drive) , DrivePosition( "DrivePosition", setPxD6Joint_DrivePosition, getPxD6Joint_DrivePosition) - , ProjectionLinearTolerance( "ProjectionLinearTolerance", setPxD6Joint_ProjectionLinearTolerance, getPxD6Joint_ProjectionLinearTolerance) - , ProjectionAngularTolerance( "ProjectionAngularTolerance", setPxD6Joint_ProjectionAngularTolerance, getPxD6Joint_ProjectionAngularTolerance) , ConcreteTypeName( "ConcreteTypeName", getPxD6Joint_ConcreteTypeName) {} PxD6JointGeneratedValues::PxD6JointGeneratedValues( const PxD6Joint* inSource ) @@ -189,8 +183,6 @@ const char * getPxD6Joint_ConcreteTypeName( const PxD6Joint* inObj ) { return in ,SwingLimit( getPxD6Joint_SwingLimit( inSource ) ) ,PyramidSwingLimit( getPxD6Joint_PyramidSwingLimit( inSource ) ) ,DrivePosition( getPxD6Joint_DrivePosition( inSource ) ) - ,ProjectionLinearTolerance( getPxD6Joint_ProjectionLinearTolerance( inSource ) ) - ,ProjectionAngularTolerance( getPxD6Joint_ProjectionAngularTolerance( inSource ) ) ,ConcreteTypeName( getPxD6Joint_ConcreteTypeName( inSource ) ) { PX_UNUSED(inSource); @@ -210,8 +202,6 @@ void setPxDistanceJoint_Stiffness( PxDistanceJoint* inObj, PxReal inArg){ inObj- PxReal getPxDistanceJoint_Stiffness( const PxDistanceJoint* inObj ) { return inObj->getStiffness(); } void setPxDistanceJoint_Damping( PxDistanceJoint* inObj, PxReal inArg){ inObj->setDamping( inArg ); } PxReal getPxDistanceJoint_Damping( const PxDistanceJoint* inObj ) { return inObj->getDamping(); } -void setPxDistanceJoint_ContactDistance( PxDistanceJoint* inObj, PxReal inArg){ inObj->setContactDistance( inArg ); } -PxReal getPxDistanceJoint_ContactDistance( const PxDistanceJoint* inObj ) { return inObj->getContactDistance(); } void setPxDistanceJoint_DistanceJointFlags( PxDistanceJoint* inObj, PxDistanceJointFlags inArg){ inObj->setDistanceJointFlags( inArg ); } PxDistanceJointFlags getPxDistanceJoint_DistanceJointFlags( const PxDistanceJoint* inObj ) { return inObj->getDistanceJointFlags(); } const char * getPxDistanceJoint_ConcreteTypeName( const PxDistanceJoint* inObj ) { return inObj->getConcreteTypeName(); } @@ -222,7 +212,6 @@ const char * getPxDistanceJoint_ConcreteTypeName( const PxDistanceJoint* inObj ) , Tolerance( "Tolerance", setPxDistanceJoint_Tolerance, getPxDistanceJoint_Tolerance) , Stiffness( "Stiffness", setPxDistanceJoint_Stiffness, getPxDistanceJoint_Stiffness) , Damping( "Damping", setPxDistanceJoint_Damping, getPxDistanceJoint_Damping) - , ContactDistance( "ContactDistance", setPxDistanceJoint_ContactDistance, getPxDistanceJoint_ContactDistance) , DistanceJointFlags( "DistanceJointFlags", setPxDistanceJoint_DistanceJointFlags, getPxDistanceJoint_DistanceJointFlags) , ConcreteTypeName( "ConcreteTypeName", getPxDistanceJoint_ConcreteTypeName) {} @@ -234,7 +223,6 @@ const char * getPxDistanceJoint_ConcreteTypeName( const PxDistanceJoint* inObj ) ,Tolerance( getPxDistanceJoint_Tolerance( inSource ) ) ,Stiffness( getPxDistanceJoint_Stiffness( inSource ) ) ,Damping( getPxDistanceJoint_Damping( inSource ) ) - ,ContactDistance( getPxDistanceJoint_ContactDistance( inSource ) ) ,DistanceJointFlags( getPxDistanceJoint_DistanceJointFlags( inSource ) ) ,ConcreteTypeName( getPxDistanceJoint_ConcreteTypeName( inSource ) ) { @@ -270,20 +258,12 @@ const char * getPxContactJoint_ConcreteTypeName( const PxContactJoint* inObj ) { { PX_UNUSED(inSource); } -void setPxFixedJoint_ProjectionLinearTolerance( PxFixedJoint* inObj, PxReal inArg){ inObj->setProjectionLinearTolerance( inArg ); } -PxReal getPxFixedJoint_ProjectionLinearTolerance( const PxFixedJoint* inObj ) { return inObj->getProjectionLinearTolerance(); } -void setPxFixedJoint_ProjectionAngularTolerance( PxFixedJoint* inObj, PxReal inArg){ inObj->setProjectionAngularTolerance( inArg ); } -PxReal getPxFixedJoint_ProjectionAngularTolerance( const PxFixedJoint* inObj ) { return inObj->getProjectionAngularTolerance(); } const char * getPxFixedJoint_ConcreteTypeName( const PxFixedJoint* inObj ) { return inObj->getConcreteTypeName(); } PxFixedJointGeneratedInfo::PxFixedJointGeneratedInfo() - : ProjectionLinearTolerance( "ProjectionLinearTolerance", setPxFixedJoint_ProjectionLinearTolerance, getPxFixedJoint_ProjectionLinearTolerance) - , ProjectionAngularTolerance( "ProjectionAngularTolerance", setPxFixedJoint_ProjectionAngularTolerance, getPxFixedJoint_ProjectionAngularTolerance) - , ConcreteTypeName( "ConcreteTypeName", getPxFixedJoint_ConcreteTypeName) + : ConcreteTypeName( "ConcreteTypeName", getPxFixedJoint_ConcreteTypeName) {} PxFixedJointGeneratedValues::PxFixedJointGeneratedValues( const PxFixedJoint* inSource ) :PxJointGeneratedValues( inSource ) - ,ProjectionLinearTolerance( getPxFixedJoint_ProjectionLinearTolerance( inSource ) ) - ,ProjectionAngularTolerance( getPxFixedJoint_ProjectionAngularTolerance( inSource ) ) ,ConcreteTypeName( getPxFixedJoint_ConcreteTypeName( inSource ) ) { PX_UNUSED(inSource); @@ -294,18 +274,12 @@ void setPxPrismaticJoint_Limit( PxPrismaticJoint* inObj, const PxJointLinearLimi PxJointLinearLimitPair getPxPrismaticJoint_Limit( const PxPrismaticJoint* inObj ) { return inObj->getLimit(); } void setPxPrismaticJoint_PrismaticJointFlags( PxPrismaticJoint* inObj, PxPrismaticJointFlags inArg){ inObj->setPrismaticJointFlags( inArg ); } PxPrismaticJointFlags getPxPrismaticJoint_PrismaticJointFlags( const PxPrismaticJoint* inObj ) { return inObj->getPrismaticJointFlags(); } -void setPxPrismaticJoint_ProjectionLinearTolerance( PxPrismaticJoint* inObj, PxReal inArg){ inObj->setProjectionLinearTolerance( inArg ); } -PxReal getPxPrismaticJoint_ProjectionLinearTolerance( const PxPrismaticJoint* inObj ) { return inObj->getProjectionLinearTolerance(); } -void setPxPrismaticJoint_ProjectionAngularTolerance( PxPrismaticJoint* inObj, PxReal inArg){ inObj->setProjectionAngularTolerance( inArg ); } -PxReal getPxPrismaticJoint_ProjectionAngularTolerance( const PxPrismaticJoint* inObj ) { return inObj->getProjectionAngularTolerance(); } const char * getPxPrismaticJoint_ConcreteTypeName( const PxPrismaticJoint* inObj ) { return inObj->getConcreteTypeName(); } PxPrismaticJointGeneratedInfo::PxPrismaticJointGeneratedInfo() : Position( "Position", getPxPrismaticJoint_Position) , Velocity( "Velocity", getPxPrismaticJoint_Velocity) , Limit( "Limit", setPxPrismaticJoint_Limit, getPxPrismaticJoint_Limit) , PrismaticJointFlags( "PrismaticJointFlags", setPxPrismaticJoint_PrismaticJointFlags, getPxPrismaticJoint_PrismaticJointFlags) - , ProjectionLinearTolerance( "ProjectionLinearTolerance", setPxPrismaticJoint_ProjectionLinearTolerance, getPxPrismaticJoint_ProjectionLinearTolerance) - , ProjectionAngularTolerance( "ProjectionAngularTolerance", setPxPrismaticJoint_ProjectionAngularTolerance, getPxPrismaticJoint_ProjectionAngularTolerance) , ConcreteTypeName( "ConcreteTypeName", getPxPrismaticJoint_ConcreteTypeName) {} PxPrismaticJointGeneratedValues::PxPrismaticJointGeneratedValues( const PxPrismaticJoint* inSource ) @@ -314,8 +288,6 @@ const char * getPxPrismaticJoint_ConcreteTypeName( const PxPrismaticJoint* inObj ,Velocity( getPxPrismaticJoint_Velocity( inSource ) ) ,Limit( getPxPrismaticJoint_Limit( inSource ) ) ,PrismaticJointFlags( getPxPrismaticJoint_PrismaticJointFlags( inSource ) ) - ,ProjectionLinearTolerance( getPxPrismaticJoint_ProjectionLinearTolerance( inSource ) ) - ,ProjectionAngularTolerance( getPxPrismaticJoint_ProjectionAngularTolerance( inSource ) ) ,ConcreteTypeName( getPxPrismaticJoint_ConcreteTypeName( inSource ) ) { PX_UNUSED(inSource); @@ -332,10 +304,6 @@ void setPxRevoluteJoint_DriveGearRatio( PxRevoluteJoint* inObj, PxReal inArg){ i PxReal getPxRevoluteJoint_DriveGearRatio( const PxRevoluteJoint* inObj ) { return inObj->getDriveGearRatio(); } void setPxRevoluteJoint_RevoluteJointFlags( PxRevoluteJoint* inObj, PxRevoluteJointFlags inArg){ inObj->setRevoluteJointFlags( inArg ); } PxRevoluteJointFlags getPxRevoluteJoint_RevoluteJointFlags( const PxRevoluteJoint* inObj ) { return inObj->getRevoluteJointFlags(); } -void setPxRevoluteJoint_ProjectionLinearTolerance( PxRevoluteJoint* inObj, PxReal inArg){ inObj->setProjectionLinearTolerance( inArg ); } -PxReal getPxRevoluteJoint_ProjectionLinearTolerance( const PxRevoluteJoint* inObj ) { return inObj->getProjectionLinearTolerance(); } -void setPxRevoluteJoint_ProjectionAngularTolerance( PxRevoluteJoint* inObj, PxReal inArg){ inObj->setProjectionAngularTolerance( inArg ); } -PxReal getPxRevoluteJoint_ProjectionAngularTolerance( const PxRevoluteJoint* inObj ) { return inObj->getProjectionAngularTolerance(); } const char * getPxRevoluteJoint_ConcreteTypeName( const PxRevoluteJoint* inObj ) { return inObj->getConcreteTypeName(); } PxRevoluteJointGeneratedInfo::PxRevoluteJointGeneratedInfo() : Angle( "Angle", getPxRevoluteJoint_Angle) @@ -345,8 +313,6 @@ const char * getPxRevoluteJoint_ConcreteTypeName( const PxRevoluteJoint* inObj ) , DriveForceLimit( "DriveForceLimit", setPxRevoluteJoint_DriveForceLimit, getPxRevoluteJoint_DriveForceLimit) , DriveGearRatio( "DriveGearRatio", setPxRevoluteJoint_DriveGearRatio, getPxRevoluteJoint_DriveGearRatio) , RevoluteJointFlags( "RevoluteJointFlags", setPxRevoluteJoint_RevoluteJointFlags, getPxRevoluteJoint_RevoluteJointFlags) - , ProjectionLinearTolerance( "ProjectionLinearTolerance", setPxRevoluteJoint_ProjectionLinearTolerance, getPxRevoluteJoint_ProjectionLinearTolerance) - , ProjectionAngularTolerance( "ProjectionAngularTolerance", setPxRevoluteJoint_ProjectionAngularTolerance, getPxRevoluteJoint_ProjectionAngularTolerance) , ConcreteTypeName( "ConcreteTypeName", getPxRevoluteJoint_ConcreteTypeName) {} PxRevoluteJointGeneratedValues::PxRevoluteJointGeneratedValues( const PxRevoluteJoint* inSource ) @@ -358,8 +324,6 @@ const char * getPxRevoluteJoint_ConcreteTypeName( const PxRevoluteJoint* inObj ) ,DriveForceLimit( getPxRevoluteJoint_DriveForceLimit( inSource ) ) ,DriveGearRatio( getPxRevoluteJoint_DriveGearRatio( inSource ) ) ,RevoluteJointFlags( getPxRevoluteJoint_RevoluteJointFlags( inSource ) ) - ,ProjectionLinearTolerance( getPxRevoluteJoint_ProjectionLinearTolerance( inSource ) ) - ,ProjectionAngularTolerance( getPxRevoluteJoint_ProjectionAngularTolerance( inSource ) ) ,ConcreteTypeName( getPxRevoluteJoint_ConcreteTypeName( inSource ) ) { PX_UNUSED(inSource); @@ -370,15 +334,12 @@ PxReal getPxSphericalJoint_SwingYAngle( const PxSphericalJoint* inObj ) { return PxReal getPxSphericalJoint_SwingZAngle( const PxSphericalJoint* inObj ) { return inObj->getSwingZAngle(); } void setPxSphericalJoint_SphericalJointFlags( PxSphericalJoint* inObj, PxSphericalJointFlags inArg){ inObj->setSphericalJointFlags( inArg ); } PxSphericalJointFlags getPxSphericalJoint_SphericalJointFlags( const PxSphericalJoint* inObj ) { return inObj->getSphericalJointFlags(); } -void setPxSphericalJoint_ProjectionLinearTolerance( PxSphericalJoint* inObj, PxReal inArg){ inObj->setProjectionLinearTolerance( inArg ); } -PxReal getPxSphericalJoint_ProjectionLinearTolerance( const PxSphericalJoint* inObj ) { return inObj->getProjectionLinearTolerance(); } const char * getPxSphericalJoint_ConcreteTypeName( const PxSphericalJoint* inObj ) { return inObj->getConcreteTypeName(); } PxSphericalJointGeneratedInfo::PxSphericalJointGeneratedInfo() : LimitCone( "LimitCone", setPxSphericalJoint_LimitCone, getPxSphericalJoint_LimitCone) , SwingYAngle( "SwingYAngle", getPxSphericalJoint_SwingYAngle) , SwingZAngle( "SwingZAngle", getPxSphericalJoint_SwingZAngle) , SphericalJointFlags( "SphericalJointFlags", setPxSphericalJoint_SphericalJointFlags, getPxSphericalJoint_SphericalJointFlags) - , ProjectionLinearTolerance( "ProjectionLinearTolerance", setPxSphericalJoint_ProjectionLinearTolerance, getPxSphericalJoint_ProjectionLinearTolerance) , ConcreteTypeName( "ConcreteTypeName", getPxSphericalJoint_ConcreteTypeName) {} PxSphericalJointGeneratedValues::PxSphericalJointGeneratedValues( const PxSphericalJoint* inSource ) @@ -387,7 +348,6 @@ const char * getPxSphericalJoint_ConcreteTypeName( const PxSphericalJoint* inObj ,SwingYAngle( getPxSphericalJoint_SwingYAngle( inSource ) ) ,SwingZAngle( getPxSphericalJoint_SwingZAngle( inSource ) ) ,SphericalJointFlags( getPxSphericalJoint_SphericalJointFlags( inSource ) ) - ,ProjectionLinearTolerance( getPxSphericalJoint_ProjectionLinearTolerance( inSource ) ) ,ConcreteTypeName( getPxSphericalJoint_ConcreteTypeName( inSource ) ) { PX_UNUSED(inSource); @@ -400,21 +360,17 @@ inline PxReal getPxJointLimitParametersStiffness( const PxJointLimitParameters* inline void setPxJointLimitParametersStiffness( PxJointLimitParameters* inOwner, PxReal inData) { inOwner->stiffness = inData; } inline PxReal getPxJointLimitParametersDamping( const PxJointLimitParameters* inOwner ) { return inOwner->damping; } inline void setPxJointLimitParametersDamping( PxJointLimitParameters* inOwner, PxReal inData) { inOwner->damping = inData; } -inline PxReal getPxJointLimitParametersContactDistance_deprecated( const PxJointLimitParameters* inOwner ) { return inOwner->contactDistance_deprecated; } -inline void setPxJointLimitParametersContactDistance_deprecated( PxJointLimitParameters* inOwner, PxReal inData) { inOwner->contactDistance_deprecated = inData; } PxJointLimitParametersGeneratedInfo::PxJointLimitParametersGeneratedInfo() : Restitution( "Restitution", setPxJointLimitParametersRestitution, getPxJointLimitParametersRestitution ) , BounceThreshold( "BounceThreshold", setPxJointLimitParametersBounceThreshold, getPxJointLimitParametersBounceThreshold ) , Stiffness( "Stiffness", setPxJointLimitParametersStiffness, getPxJointLimitParametersStiffness ) , Damping( "Damping", setPxJointLimitParametersDamping, getPxJointLimitParametersDamping ) - , ContactDistance_deprecated( "ContactDistance_deprecated", setPxJointLimitParametersContactDistance_deprecated, getPxJointLimitParametersContactDistance_deprecated ) {} PxJointLimitParametersGeneratedValues::PxJointLimitParametersGeneratedValues( const PxJointLimitParameters* inSource ) :Restitution( inSource->restitution ) ,BounceThreshold( inSource->bounceThreshold ) ,Stiffness( inSource->stiffness ) ,Damping( inSource->damping ) - ,ContactDistance_deprecated( inSource->contactDistance_deprecated ) { PX_UNUSED(inSource); } diff --git a/physx/source/physxvehicle/src/PxVehicleSuspLimitConstraintShader.h b/physx/source/physxvehicle/src/PxVehicleSuspLimitConstraintShader.h index 761be6891..5f19c3940 100644 --- a/physx/source/physxvehicle/src/PxVehicleSuspLimitConstraintShader.h +++ b/physx/source/physxvehicle/src/PxVehicleSuspLimitConstraintShader.h @@ -45,12 +45,6 @@ namespace physx class PxVehicleConstraintShader : public PxConstraintConnector { -//= 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. -//================================================================================================== public: friend class PxVehicleWheels; diff --git a/physx/source/physxvehicle/src/PxVehicleSuspWheelTire4.h b/physx/source/physxvehicle/src/PxVehicleSuspWheelTire4.h index 38d6a8fe6..30fe4cf90 100644 --- a/physx/source/physxvehicle/src/PxVehicleSuspWheelTire4.h +++ b/physx/source/physxvehicle/src/PxVehicleSuspWheelTire4.h @@ -52,12 +52,6 @@ class PxShape; class PxVehicleWheels4SimData { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; @@ -165,12 +159,6 @@ PX_COMPILE_TIME_ASSERT(0 == (sizeof(PxVehicleWheels4SimData) & 15)); class PxVehicleWheels4DynData { -//= 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. -//================================================================================================== public: friend class PxVehicleUpdate; diff --git a/physx/source/physxvehicle/src/PxVehicleUpdate.cpp b/physx/source/physxvehicle/src/PxVehicleUpdate.cpp index a8a536ab9..7252f3ea1 100644 --- a/physx/source/physxvehicle/src/PxVehicleUpdate.cpp +++ b/physx/source/physxvehicle/src/PxVehicleUpdate.cpp @@ -7291,10 +7291,11 @@ static const PxSweepBuffer* vehicleWheels4SuspensionSweeps vehActor->getShapes(&wheelShape, 1, PxU32(wheelShapeIds[j])); PxGeometryHolder suspGeometry; - if (PxGeometryType::eCONVEXMESH == wheelShape->getGeometryType()) + const PxGeometry& geom = wheelShape->getGeometry(); + const PxGeometryType::Enum geomType = geom.getType(); + if (PxGeometryType::eCONVEXMESH == geomType) { - PxConvexMeshGeometry convMeshGeom; - wheelShape->getConvexMeshGeometry(convMeshGeom); + PxConvexMeshGeometry convMeshGeom = static_cast(geom); convMeshGeom.scale.scale = convMeshGeom.scale.scale.multiply( PxVec3( PxAbs(sideAxis.x*sweepWidthScale + (upAxis.x + forwardAxis.x)*sweepRadiusScale), @@ -7303,19 +7304,17 @@ static const PxSweepBuffer* vehicleWheels4SuspensionSweeps ); suspGeometry.storeAny(convMeshGeom); } - else if (PxGeometryType::eCAPSULE == wheelShape->getGeometryType()) + else if (PxGeometryType::eCAPSULE == geomType) { - PxCapsuleGeometry capsuleGeom; - wheelShape->getCapsuleGeometry(capsuleGeom); + PxCapsuleGeometry capsuleGeom = static_cast(geom); capsuleGeom.halfHeight *= sweepWidthScale; capsuleGeom.radius *= sweepRadiusScale; suspGeometry.storeAny(capsuleGeom); } else { - PX_ASSERT(PxGeometryType::eSPHERE == wheelShape->getGeometryType()); - PxSphereGeometry sphereGeom; - wheelShape->getSphereGeometry(sphereGeom); + PX_ASSERT(PxGeometryType::eSPHERE == geomType); + PxSphereGeometry sphereGeom = static_cast(geom); sphereGeom.radius *= sweepRadiusScale; suspGeometry.storeAny(sphereGeom); } diff --git a/physx/source/physxvehicle/src/PxVehicleWheels.cpp b/physx/source/physxvehicle/src/PxVehicleWheels.cpp index a7538e791..225a4d1ab 100644 --- a/physx/source/physxvehicle/src/PxVehicleWheels.cpp +++ b/physx/source/physxvehicle/src/PxVehicleWheels.cpp @@ -715,10 +715,9 @@ void PxVehicleWheels::onConstraintRelease() } } -static PxConstraintShaderTable t = +static PxConstraintShaderTable table = { PxVehicleConstraintShader::vehicleSuspLimitConstraintSolverPrep, - 0, PxVehicleConstraintShader::visualiseConstraint, PxConstraintFlag::Enum(0) }; @@ -784,7 +783,7 @@ void PxVehicleWheels::setup } - shader.mConstraint=physics->createConstraint(vehActor, NULL, shader, t, sizeof(PxVehicleConstraintShader::VehicleConstraintData)); + shader.mConstraint=physics->createConstraint(vehActor, NULL, shader, table, sizeof(PxVehicleConstraintShader::VehicleConstraintData)); shader.mConstraint->markDirty(); } @@ -848,7 +847,7 @@ void PxVehicleWheels::resolveReferences(PxDeserializationContext& context) for(PxU32 i=0;icurrentGear != gearState->targetGear)) + if ((throttle && ((*throttle) > 0.0f)) || + (gearState && (gearState->currentGear != gearState->targetGear))) { setWakeCounter(wakeCounterResetValue, rd, link); diff --git a/physx/source/physxvehicle2/src/physxConstraints/VhPhysXConstraintHelpers.cpp b/physx/source/physxvehicle2/src/physxConstraints/VhPhysXConstraintHelpers.cpp index 9dd633bbb..90329e9b7 100644 --- a/physx/source/physxvehicle2/src/physxConstraints/VhPhysXConstraintHelpers.cpp +++ b/physx/source/physxvehicle2/src/physxConstraints/VhPhysXConstraintHelpers.cpp @@ -48,7 +48,6 @@ namespace vehicle2 PxConstraintShaderTable gVehicleConstraintTable = { vehicleConstraintSolverPrep, - 0, visualiseVehicleConstraint, PxConstraintFlag::Enum(0) }; diff --git a/physx/source/physxvehicle2/src/physxRoadGeometry/VhPhysXRoadGeometryFunctions.cpp b/physx/source/physxvehicle2/src/physxRoadGeometry/VhPhysXRoadGeometryFunctions.cpp index d4fcf1fb7..0ef7c5792 100644 --- a/physx/source/physxvehicle2/src/physxRoadGeometry/VhPhysXRoadGeometryFunctions.cpp +++ b/physx/source/physxvehicle2/src/physxRoadGeometry/VhPhysXRoadGeometryFunctions.cpp @@ -87,14 +87,16 @@ PX_FORCE_INLINE void copyHitInfo(const THitBuffer& hitBuffer, PxMaterial* hitMat void PxVehiclePhysXRoadGeometryQueryUpdate (const PxVehicleWheelParams& wheelParams, const PxVehicleSuspensionParams& suspParams, - const PxVehiclePhysXRoadGeometryQueryParams& roadGeomParams, const PxVehiclePhysXMaterialFrictionParams& materialFrictionParams, + const PxVehiclePhysXRoadGeometryQueryType::Enum queryType, + PxQueryFilterCallback* filterCallback, const PxQueryFilterData& filterData, + const PxVehiclePhysXMaterialFrictionParams& materialFrictionParams, const PxF32 steerAngle, const PxVehicleRigidBodyState& rigidBodyState, const PxScene& scene, const PxConvexMesh* unitCylinderSweepMesh, const PxVehicleFrame& frame, PxVehicleRoadGeometryState& roadGeomState, PxVehiclePhysXRoadGeometryQueryState* physxRoadGeometryState) { - if(PxVehiclePhysXRoadGeometryQueryType::eRAYCAST == roadGeomParams.roadGeometryQueryType) + if(PxVehiclePhysXRoadGeometryQueryType::eRAYCAST == queryType) { //Assume no hits until we know otherwise. roadGeomState.setToDefault(); @@ -106,7 +108,7 @@ void PxVehiclePhysXRoadGeometryQueryUpdate //Perform the raycast. PxRaycastBuffer buff; - scene.raycast(v, w, dist, buff, PxHitFlag::eDEFAULT, roadGeomParams.filterData, roadGeomParams.filterCallback); + scene.raycast(v, w, dist, buff, PxHitFlag::eDEFAULT, filterData, filterCallback); //Process the raycast result. if(buff.hasBlock && buff.block.distance != 0.0f) @@ -130,7 +132,7 @@ void PxVehiclePhysXRoadGeometryQueryUpdate physxRoadGeometryState->setToDefault(); } } - else if(PxVehiclePhysXRoadGeometryQueryType::eSWEEP == roadGeomParams.roadGeometryQueryType) + else if(PxVehiclePhysXRoadGeometryQueryType::eSWEEP == queryType) { PX_ASSERT(unitCylinderSweepMesh); @@ -150,10 +152,10 @@ void PxVehiclePhysXRoadGeometryQueryUpdate //Perform the sweep. PxSweepBuffer buff; - scene.sweep(convMeshGeom, T, w, dist, buff, PxHitFlag::eDEFAULT | PxHitFlag::eMTD, roadGeomParams.filterData, roadGeomParams.filterCallback); + scene.sweep(convMeshGeom, T, w, dist, buff, PxHitFlag::eDEFAULT | PxHitFlag::eMTD, filterData, filterCallback); //Process the sweep result. - if (buff.hasBlock && buff.block.distance > 0.0f) + if (buff.hasBlock && buff.block.distance >= 0.0f) { //Sweep started outside scene geometry. const PxPlane hitPlane(buff.block.position, buff.block.normal); diff --git a/physx/source/physxvehicle2/src/pvd/VhPvdFunctions.cpp b/physx/source/physxvehicle2/src/pvd/VhPvdFunctions.cpp index c2b74144d..82b072029 100644 --- a/physx/source/physxvehicle2/src/pvd/VhPvdFunctions.cpp +++ b/physx/source/physxvehicle2/src/pvd/VhPvdFunctions.cpp @@ -45,29 +45,29 @@ namespace vehicle2 #if PX_SUPPORT_OMNI_PVD PX_FORCE_INLINE void createPvdObject -(OmniPvdWriter* omniWriter, OmniPvdContextHandle contextHandle, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle contextHandle, OmniPvdClassHandle classHandle, OmniPvdObjectHandle objectHandle, const char* objectName) { - omniWriter->createObject(contextHandle, classHandle, objectHandle, objectName); + omniWriter.createObject(contextHandle, classHandle, objectHandle, objectName); } PX_FORCE_INLINE void writeObjectHandleAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, OmniPvdObjectHandle val) { PX_ASSERT(oh); PX_ASSERT(ah); if(val) - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(OmniPvdObjectHandle)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(OmniPvdObjectHandle)); } -PX_FORCE_INLINE void addObjectHandleToSet -(OmniPvdWriter* ow, OmniPvdContextHandle ch, OmniPvdObjectHandle setOwnerOH, OmniPvdAttributeHandle setAH, OmniPvdObjectHandle ohToAdd) +PX_FORCE_INLINE void addObjectHandleToUniqueList +(OmniPvdWriter& ow, OmniPvdContextHandle ch, OmniPvdObjectHandle setOwnerOH, OmniPvdAttributeHandle setAH, OmniPvdObjectHandle ohToAdd) { PX_ASSERT(setOwnerOH); PX_ASSERT(setAH); if(ohToAdd) - ow->addToSetAttributeShallow(ch, setOwnerOH, setAH, reinterpret_cast(&ohToAdd), sizeof(OmniPvdObjectHandle)); + ow.addToUniqueListAttribute(ch, setOwnerOH, setAH, reinterpret_cast(&ohToAdd), sizeof(OmniPvdObjectHandle)); } PX_FORCE_INLINE void appendWithInt(char* buffer, PxU32 number) @@ -79,15 +79,15 @@ PX_FORCE_INLINE void appendWithInt(char* buffer, PxU32 number) PX_FORCE_INLINE void createVehicleObject (const PxVehiclePvdAttributeHandles& attributeHandles, - PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter) + PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter& omniWriter) { // Register the top-level vehicle object if this hasn't already been done. - if(0 == objectHandles->vehicleOH) + if(0 == objectHandles.vehicleOH) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle vehicleOH = reinterpret_cast(&objectHandles->vehicleOH); - createPvdObject(omniWriter, objectHandles->contextHandle, attributeHandles.vehicle.CH, vehicleOH, "Vehicle"); - objectHandles->vehicleOH = vehicleOH; + const OmniPvdObjectHandle vehicleOH = reinterpret_cast(&objectHandles.vehicleOH); + createPvdObject(omniWriter, objectHandles.contextHandle, attributeHandles.vehicle.CH, vehicleOH, "Vehicle"); + objectHandles.vehicleOH = vehicleOH; } } @@ -99,41 +99,37 @@ PX_FORCE_INLINE void createVehicleObject void PxVehiclePvdRigidBodyRegister (const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdRigidBodyRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; if(rbodyParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->rigidBodyParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.rigidBodyParamsOH); createPvdObject(ow, ch, ah.rigidBodyParams.CH, oh, "RigidBodyParams"); - objHands->rigidBodyParamsOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.rigidBodyParamsAH, oh); + objHands.rigidBodyParamsOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.rigidBodyParamsAH, oh); } if(rbodyState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->rigidBodyStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.rigidBodyStateOH); createPvdObject(ow, ch, ah.rigidBodyState.CH, oh, "RigidBodyState"); - objHands->rigidBodyStateOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.rigidBodyStateAH, oh); + objHands.rigidBodyStateOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.rigidBodyStateAH, oh); } } void PxVehiclePvdRigidBodyWrite (const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdRigidBodyWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - const OmniPvdContextHandle ch = oh.contextHandle; if(oh.rigidBodyParamsOH && rbodyParams) @@ -154,32 +150,28 @@ void PxVehiclePvdRigidBodyWrite void PxVehiclePvdSuspensionStateCalculationParamsRegister (const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdSuspensionStateCalculationParamsRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; if(suspStateCalcParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspStateCalcParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspStateCalcParamsOH); createPvdObject(ow, ch, ah.suspStateCalcParams.CH, oh, "SuspStateCalcParams"); - objHands->suspStateCalcParamsOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.suspStateCalcParamsAH, oh); + objHands.suspStateCalcParamsOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.suspStateCalcParamsAH, oh); } } void PxVehiclePvdSuspensionStateCalculationParamsWrite (const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* omniWriter) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& omniWriter) { - PX_CHECK_AND_RETURN(omniWriter, "PxVehiclePvdSuspensionStateCalculationParamsWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - if(oh.suspStateCalcParamsOH && suspStateCalcParams) { writeSuspStateCalcParams(*suspStateCalcParams, oh.suspStateCalcParamsOH, ah.suspStateCalcParams, omniWriter, oh.contextHandle); @@ -196,10 +188,8 @@ void PxVehiclePvdCommandResponseRegister const PxVehicleArrayData& brakeResponseStates, const PxVehicleArrayData& steerResponseStates, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdCommandResponseRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - PX_CHECK_AND_RETURN( brakeResponseParams.size <= 2, "PxVehiclePvdCommandResponseRegister : brakeResponseParams.size must have less than or equal to 2"); @@ -207,46 +197,46 @@ void PxVehiclePvdCommandResponseRegister // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; for(PxU32 i = 0; i < brakeResponseParams.size; i++) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->brakeResponseParamOHs[i]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.brakeResponseParamOHs[i]); char objectName[32] = "BrakeComandResponseParams"; appendWithInt(objectName, i); createPvdObject(ow, ch, ah.brakeCommandResponseParams.CH, oh, objectName); - objHands->brakeResponseParamOHs[i] = oh; + objHands.brakeResponseParamOHs[i] = oh; - addObjectHandleToSet(ow, ch, objHands->vehicleOH, ah.vehicle.brakeResponseParamsSetAH, oh); + addObjectHandleToUniqueList(ow, ch, objHands.vehicleOH, ah.vehicle.brakeResponseParamsSetAH, oh); } if(steerResponseParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->steerResponseParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.steerResponseParamsOH); const char objectName[32] = "SteerCommandResponseParams"; createPvdObject(ow, ch, ah.steerCommandResponseParams.CH, oh, objectName); - objHands->steerResponseParamsOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.steerResponseParamsAH, oh); + objHands.steerResponseParamsOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.steerResponseParamsAH, oh); } if(!brakeResponseStates.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->brakeResponseStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.brakeResponseStateOH); const char objectName[32] = "BrakeCommandResponseStates"; createPvdObject(ow, ch, ah.brakeCommandResponseStates.CH, oh, objectName); - objHands->brakeResponseStateOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.brakeResponseStatesAH, oh); + objHands.brakeResponseStateOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.brakeResponseStatesAH, oh); } if(!steerResponseStates.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->steerResponseStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.steerResponseStateOH); const char objectName[32] = "SteerCommandResponseStates"; createPvdObject(ow, ch, ah.steerCommandResponseStates.CH, oh, objectName); - objHands->steerResponseStateOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.steerResponseStatesAH, oh); + objHands.steerResponseStateOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.steerResponseStatesAH, oh); } } @@ -257,10 +247,8 @@ void PxVehiclePvdCommandResponseWrite const PxVehicleArrayData& brakeResponseStates, const PxVehicleArrayData& steerResponseStates, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdCommandResponseWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - PX_CHECK_AND_RETURN( brakeResponseParams.size <= 2, "PxVehiclePvdCommandResponseWrite : brakeResponseParams.size must have less than or equal to 2"); @@ -316,14 +304,12 @@ void PxVehiclePvdWheelAttachmentsRegister const PxVehicleArrayData& tireCamberStates, const PxVehicleArrayData& tireForces, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdWheelAttachmentsRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; // Register the wheel attachments for(PxU32 i = 0; i < axleDesc.nbWheels; i++) @@ -331,249 +317,249 @@ void PxVehiclePvdWheelAttachmentsRegister const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i]; PX_CHECK_AND_RETURN( - wheelId < objHands->nbWheels, + wheelId < objHands.nbWheels, "PxVehiclePvdWheelAttachmentsRegister - axleDesc.axleToWheelIds[i] must be less than the value of the nbWheels argument in the function PxVehiclePvdObjectCreate()"); if(!wheelParams.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->wheelParamsOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.wheelParamsOHs[wheelId]); char objectName[32] = "WheelParams"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.wheelParams.CH, oh, objectName); - objHands->wheelParamsOHs[wheelId] = oh; + objHands.wheelParamsOHs[wheelId] = oh; } if(!wheelActuationStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->wheelActuationStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.wheelActuationStateOHs[wheelId]); char objectName[32] = "WheelActuationState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.wheelActuationState.CH, oh, objectName); - objHands->wheelActuationStateOHs[wheelId] = oh; + objHands.wheelActuationStateOHs[wheelId] = oh; } if(!wheelRigidBody1dStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->wheelRigidBody1dStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.wheelRigidBody1dStateOHs[wheelId]); char objectName[32] = "WheelRigidBody1dState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.wheelRigidBody1dState.CH, oh, objectName); - objHands->wheelRigidBody1dStateOHs[wheelId] = oh; + objHands.wheelRigidBody1dStateOHs[wheelId] = oh; } if(!wheelLocalPoses.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->wheelLocalPoseStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.wheelLocalPoseStateOHs[wheelId]); char objectName[32] = "WheelLocalPoseState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.wheelLocalPoseState.CH, oh, objectName); - objHands->wheelLocalPoseStateOHs[wheelId] = oh; + objHands.wheelLocalPoseStateOHs[wheelId] = oh; } if(!roadGeometryStates.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->roadGeomStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.roadGeomStateOHs[wheelId]); char objectName[32] = "RoadGeometryState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.roadGeomState.CH, oh, objectName); - objHands->roadGeomStateOHs[wheelId] = oh; + objHands.roadGeomStateOHs[wheelId] = oh; } if(!suspParams.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspParamsOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspParamsOHs[wheelId]); char objectName[32] = "SuspParams"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.suspParams.CH, oh, objectName); - objHands->suspParamsOHs[wheelId] = oh; + objHands.suspParamsOHs[wheelId] = oh; } if(!suspCompParams.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspCompParamsOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspCompParamsOHs[wheelId]); char objectName[32] = "SuspCompParams"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.suspCompParams.CH, oh, objectName); - objHands->suspCompParamsOHs[wheelId] = oh; + objHands.suspCompParamsOHs[wheelId] = oh; } if(!suspForceParams.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspForceParamsOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspForceParamsOHs[wheelId]); char objectName[32] = "SuspForceParams"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.suspForceParams.CH, oh, objectName); - objHands->suspForceParamsOHs[wheelId] = oh; + objHands.suspForceParamsOHs[wheelId] = oh; } if(!suspStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspStateOHs[wheelId]); char objectName[32] = "SuspState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.suspState.CH, oh, objectName); - objHands->suspStateOHs[wheelId] = oh; + objHands.suspStateOHs[wheelId] = oh; } if(!suspCompStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspCompStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspCompStateOHs[wheelId]); char objectName[32] = "SuspComplianceState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.suspCompState.CH, oh, objectName); - objHands->suspCompStateOHs[wheelId] = oh; + objHands.suspCompStateOHs[wheelId] = oh; } if(!suspForces.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->suspForceOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.suspForceOHs[wheelId]); char objectName[32] = "SuspForce"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.suspForce.CH, oh, objectName); - objHands->suspForceOHs[wheelId] = oh; + objHands.suspForceOHs[wheelId] = oh; } if(!tireForceParams.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireParamsOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireParamsOHs[wheelId]); char objectName[32] = "TireParams"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireParams.CH, oh, objectName); - objHands->tireParamsOHs[wheelId] = oh; + objHands.tireParamsOHs[wheelId] = oh; } if(!tireDirectionStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireDirectionStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireDirectionStateOHs[wheelId]); char objectName[32] = "TireDirectionState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireDirectionState.CH, oh, objectName); - objHands->tireDirectionStateOHs[wheelId] = oh; + objHands.tireDirectionStateOHs[wheelId] = oh; } if(!tireSpeedStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireSpeedStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireSpeedStateOHs[wheelId]); char objectName[32] = "TireSpeedState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireSpeedState.CH, oh, objectName); - objHands->tireSpeedStateOHs[wheelId] = oh; + objHands.tireSpeedStateOHs[wheelId] = oh; } if(!tireSlipStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireSlipStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireSlipStateOHs[wheelId]); char objectName[32] = "TireSlipState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireSlipState.CH, oh, objectName); - objHands->tireSlipStateOHs[wheelId] = oh; + objHands.tireSlipStateOHs[wheelId] = oh; } if(!tireStickyStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireStickyStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireStickyStateOHs[wheelId]); char objectName[32] = "TireStickyState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireStickyState.CH, oh, objectName); - objHands->tireStickyStateOHs[wheelId] = oh; + objHands.tireStickyStateOHs[wheelId] = oh; } if(!tireGripStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireGripStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireGripStateOHs[wheelId]); char objectName[32] = "TireGripState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireGripState.CH, oh, objectName); - objHands->tireGripStateOHs[wheelId] = oh; + objHands.tireGripStateOHs[wheelId] = oh; } if(!tireCamberStates.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireCamberStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireCamberStateOHs[wheelId]); char objectName[32] = "TireCamberState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireCamberState.CH, oh, objectName); - objHands->tireCamberStateOHs[wheelId] = oh; + objHands.tireCamberStateOHs[wheelId] = oh; } if(!tireForces.isEmpty()) { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->tireForceOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.tireForceOHs[wheelId]); char objectName[32] = "TireForce"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.tireForce.CH, oh, objectName); - objHands->tireForceOHs[wheelId] = oh; + objHands.tireForceOHs[wheelId] = oh; } { //Get a unique id from a memory adress in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->wheelAttachmentOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.wheelAttachmentOHs[wheelId]); char objectName[32] = "WheelAttachment"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.wheelAttachment.CH, oh, objectName); - objHands->wheelAttachmentOHs[wheelId] = oh; + objHands.wheelAttachmentOHs[wheelId] = oh; // Point the wheel attachment object at the wheel params, susp state, tire force etc objects. writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.wheelParamsAH, objHands->wheelParamsOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.wheelParamsAH, objHands.wheelParamsOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.wheelActuationStateAH, objHands->wheelActuationStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.wheelActuationStateAH, objHands.wheelActuationStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.wheelRigidBody1dStateAH, objHands->wheelRigidBody1dStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.wheelRigidBody1dStateAH, objHands.wheelRigidBody1dStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.wheelLocalPoseStateAH, objHands->wheelLocalPoseStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.wheelLocalPoseStateAH, objHands.wheelLocalPoseStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.roadGeomStateAH, objHands->roadGeomStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.roadGeomStateAH, objHands.roadGeomStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.suspParamsAH, objHands->suspParamsOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.suspParamsAH, objHands.suspParamsOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.suspCompParamsAH, objHands->suspCompParamsOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.suspCompParamsAH, objHands.suspCompParamsOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.suspForceParamsAH, objHands->suspForceParamsOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.suspForceParamsAH, objHands.suspForceParamsOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.suspStateAH, objHands->suspStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.suspStateAH, objHands.suspStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.suspCompStateAH, objHands->suspCompStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.suspCompStateAH, objHands.suspCompStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.suspForceAH, objHands->suspForceOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.suspForceAH, objHands.suspForceOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireParamsAH, objHands->tireParamsOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireParamsAH, objHands.tireParamsOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireDirectionStateAH, objHands->tireDirectionStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireDirectionStateAH, objHands.tireDirectionStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireSpeedStateAH, objHands->tireSpeedStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireSpeedStateAH, objHands.tireSpeedStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireSlipStateAH, objHands->tireSlipStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireSlipStateAH, objHands.tireSlipStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireStickyStateAH, objHands->tireStickyStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireStickyStateAH, objHands.tireStickyStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireGripStateAH, objHands->tireGripStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireGripStateAH, objHands.tireGripStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireCamberStateAH, objHands->tireCamberStateOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireCamberStateAH, objHands.tireCamberStateOHs[wheelId]); writeObjectHandleAttribute( - ow, ch, oh, ah.wheelAttachment.tireForceAH, objHands->tireForceOHs[wheelId]); + ow, ch, oh, ah.wheelAttachment.tireForceAH, objHands.tireForceOHs[wheelId]); //Point the vehicle object at the wheel attachment object. - addObjectHandleToSet(ow, ch, objHands->vehicleOH, ah.vehicle.wheelAttachmentSetAH, oh); + addObjectHandleToUniqueList(ow, ch, objHands.vehicleOH, ah.vehicle.wheelAttachmentSetAH, oh); } } } @@ -600,10 +586,8 @@ void PxVehiclePvdWheelAttachmentsWrite const PxVehicleArrayData& tireCamberStates, const PxVehicleArrayData& tireForces, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdWheelAttachmentsWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - const OmniPvdContextHandle ch = oh.contextHandle; for(PxU32 i = 0; i < axleDesc.nbWheels; i++) @@ -716,56 +700,54 @@ void PxVehiclePvdDirectDrivetrainRegister const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, const PxVehicleArrayData& directDriveThrottleResponseState, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdDirectDrivetrainRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; if(commandState) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->directDriveCommandStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.directDriveCommandStateOH); createPvdObject(ow, ch, ah.directDriveCommandState.CH, oh, "DirectDriveCommandState"); - objHands->directDriveCommandStateOH = oh; + objHands.directDriveCommandStateOH = oh; } if(transmissionState) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->directDriveTransmissionCommandStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.directDriveTransmissionCommandStateOH); createPvdObject(ow, ch, ah.directDriveTransmissionCommandState.CH, oh, "DirectDriveTransmissionCommandState"); - objHands->directDriveTransmissionCommandStateOH = oh; + objHands.directDriveTransmissionCommandStateOH = oh; } if(directDriveThrottleResponseParams) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->directDriveThrottleResponseParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.directDriveThrottleResponseParamsOH); createPvdObject(ow, ch, ah.directDriveThrottleCommandResponseParams.CH, oh, "DirectDriveThrottleResponseParams"); - objHands->directDriveThrottleResponseParamsOH = oh; + objHands.directDriveThrottleResponseParamsOH = oh; } if(!directDriveThrottleResponseState.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->directDriveThrottleResponseStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.directDriveThrottleResponseStateOH); createPvdObject(ow, ch, ah.directDriveThrottleCommandResponseState.CH, oh, "DirectDriveThrottleResponseState"); - objHands->directDriveThrottleResponseStateOH = oh; + objHands.directDriveThrottleResponseStateOH = oh; } { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->directDrivetrainOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.directDrivetrainOH); createPvdObject(ow, ch, ah.directDrivetrain.CH, oh, "DirectDrivetrain"); - objHands->directDrivetrainOH = oh; + objHands.directDrivetrainOH = oh; writeObjectHandleAttribute( - ow, ch, oh, ah.directDrivetrain.commandStateAH, objHands->directDriveCommandStateOH); + ow, ch, oh, ah.directDrivetrain.commandStateAH, objHands.directDriveCommandStateOH); writeObjectHandleAttribute( - ow, ch, oh, ah.directDrivetrain.throttleResponseParamsAH, objHands->directDriveThrottleResponseParamsOH); + ow, ch, oh, ah.directDrivetrain.throttleResponseParamsAH, objHands.directDriveThrottleResponseParamsOH); writeObjectHandleAttribute( - ow, ch, oh, ah.directDrivetrain.throttleResponseStateAH, objHands->directDriveThrottleResponseStateOH); + ow, ch, oh, ah.directDrivetrain.throttleResponseStateAH, objHands.directDriveThrottleResponseStateOH); - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.directDrivetrainAH, oh); + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.directDrivetrainAH, oh); } } @@ -775,10 +757,8 @@ void PxVehiclePvdDirectDrivetrainWrite const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, const PxVehicleArrayData& directDriveThrottleResponseState, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdDirectDrivetrainWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - const OmniPvdContextHandle ch = oh.contextHandle; if(oh.directDriveCommandStateOH && commandState) @@ -819,167 +799,166 @@ void PxVehiclePvdEngineDrivetrainRegister const PxVehicleDifferentialState* diffState, const PxVehicleClutchSlipState* clutchSlipState, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdEngineDrivetrainRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; if(commandState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->engineDriveCommandStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.engineDriveCommandStateOH); createPvdObject(ow, ch, ah.engineDriveCommandState.CH, oh, "EngineDriveCommandState"); - objHands->engineDriveCommandStateOH = oh; + objHands.engineDriveCommandStateOH = oh; } if(transmissionCommandState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->engineDriveTransmissionCommandStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.engineDriveTransmissionCommandStateOH); createPvdObject(ow, ch, ah.engineDriveTransmissionCommandState.CH, oh, "EngineDriveTransmissionCommandState"); - objHands->engineDriveTransmissionCommandStateOH = oh; + objHands.engineDriveTransmissionCommandStateOH = oh; } if(clutchResponseParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->clutchResponseParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.clutchResponseParamsOH); createPvdObject(ow, ch, ah.clutchCommandResponseParams.CH, oh, "ClutchResponseParams"); - objHands->clutchResponseParamsOH = oh; + objHands.clutchResponseParamsOH = oh; } if(clutchParms) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->clutchParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.clutchParamsOH); createPvdObject(ow, ch, ah.clutchParams.CH, oh, "ClutchParams"); - objHands->clutchParamsOH = oh; + objHands.clutchParamsOH = oh; } if(engineParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->engineParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.engineParamsOH); createPvdObject(ow, ch, ah.engineParams.CH, oh, "EngineParams"); - objHands->engineParamsOH = oh; + objHands.engineParamsOH = oh; } if(gearboxParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->gearboxParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.gearboxParamsOH); createPvdObject(ow, ch, ah.gearboxParams.CH, oh, "GearboxParams"); - objHands->gearboxParamsOH = oh; + objHands.gearboxParamsOH = oh; } if(autoboxParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->autoboxParamsOH); - createPvdObject(ow, objHands->contextHandle, ah.autoboxParams.CH, oh, "AutoboxParams"); - objHands->autoboxParamsOH = oh; + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.autoboxParamsOH); + createPvdObject(ow, objHands.contextHandle, ah.autoboxParams.CH, oh, "AutoboxParams"); + objHands.autoboxParamsOH = oh; } if(multiWheelDiffParams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->multiWheelDiffParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.multiWheelDiffParamsOH); createPvdObject(ow, ch, ah.multiwheelDiffParams.CH, oh, "MultiWheelDiffParams"); - objHands->multiWheelDiffParamsOH = oh; + objHands.multiWheelDiffParamsOH = oh; } if(fourWheelDiffPrams) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->fourWheelDiffParamsOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.fourWheelDiffParamsOH); createPvdObject(ow, ch, ah.fourwheelDiffParams.CH, oh, "FourWheelDiffParams"); - objHands->fourWheelDiffParamsOH = oh; + objHands.fourWheelDiffParamsOH = oh; } if(clutchResponseState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->clutchResponseStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.clutchResponseStateOH); createPvdObject(ow, ch, ah.clutchResponseState.CH, oh, "ClutchResponseState"); - objHands->clutchResponseStateOH = oh; + objHands.clutchResponseStateOH = oh; } if(throttleResponseState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->engineDriveThrottleResponseStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.engineDriveThrottleResponseStateOH); createPvdObject(ow, ch, ah.throttleResponseState.CH, oh, "ThrottleResponseState"); - objHands->engineDriveThrottleResponseStateOH = oh; + objHands.engineDriveThrottleResponseStateOH = oh; } if(engineState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->engineStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.engineStateOH); createPvdObject(ow, ch, ah.engineState.CH, oh, "EngineState"); - objHands->engineStateOH = oh; + objHands.engineStateOH = oh; } if(gearboxState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->gearboxStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.gearboxStateOH); createPvdObject(ow, ch, ah.gearboxState.CH, oh, "GearboxState"); - objHands->gearboxStateOH = oh; + objHands.gearboxStateOH = oh; } if(autoboxState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->autoboxStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.autoboxStateOH); createPvdObject(ow, ch, ah.autoboxState.CH, oh, "AutoboxState"); - objHands->autoboxStateOH = oh; + objHands.autoboxStateOH = oh; } if(diffState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->diffStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.diffStateOH); createPvdObject(ow, ch, ah.diffState.CH, oh, "DiffState"); - objHands->diffStateOH = oh; + objHands.diffStateOH = oh; } if(clutchSlipState) { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->clutchSlipStateOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.clutchSlipStateOH); createPvdObject(ow, ch, ah.clutchSlipState.CH, oh, "ClutchSlipState"); - objHands->clutchSlipStateOH = oh; + objHands.clutchSlipStateOH = oh; } //Engine drivetrain { //Get a unique id from a memory address in objectHandles. - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->engineDrivetrainOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.engineDrivetrainOH); createPvdObject(ow, ch, ah.engineDrivetrain.CH, oh, "EngineDrivetrain"); - objHands->engineDrivetrainOH = oh; - - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.commandStateAH, objHands->engineDriveCommandStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchResponseParamsAH, objHands->clutchResponseParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchParamsAH, objHands->clutchParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.engineParamsAH, objHands->engineParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.gearboxParamsAH, objHands->gearboxParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.autoboxParamsAH, objHands->autoboxParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.multiWheelDiffParamsAH, objHands->multiWheelDiffParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.fourWheelDiffParamsAH, objHands->fourWheelDiffParamsOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchResponseStateAH, objHands->clutchResponseStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.throttleResponseStateAH, objHands->engineDriveThrottleResponseStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.engineStateAH, objHands->engineStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.gearboxStateAH, objHands->gearboxStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.autoboxStateAH, objHands->autoboxStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.diffStateAH, objHands->diffStateOH); - writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchSlipStateAH, objHands->clutchSlipStateOH); - - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.engineDriveTrainAH, oh); + objHands.engineDrivetrainOH = oh; + + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.commandStateAH, objHands.engineDriveCommandStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.transmissionCommandStateAH, objHands.engineDriveTransmissionCommandStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchResponseParamsAH, objHands.clutchResponseParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchParamsAH, objHands.clutchParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.engineParamsAH, objHands.engineParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.gearboxParamsAH, objHands.gearboxParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.autoboxParamsAH, objHands.autoboxParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.multiWheelDiffParamsAH, objHands.multiWheelDiffParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.fourWheelDiffParamsAH, objHands.fourWheelDiffParamsOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchResponseStateAH, objHands.clutchResponseStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.throttleResponseStateAH, objHands.engineDriveThrottleResponseStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.engineStateAH, objHands.engineStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.gearboxStateAH, objHands.gearboxStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.autoboxStateAH, objHands.autoboxStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.diffStateAH, objHands.diffStateOH); + writeObjectHandleAttribute(ow, ch, oh, ah.engineDrivetrain.clutchSlipStateAH, objHands.clutchSlipStateOH); + + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.engineDriveTrainAH, oh); } } @@ -1000,10 +979,8 @@ void PxVehiclePvdEngineDrivetrainWrite const PxVehicleDifferentialState* diffState, const PxVehicleClutchSlipState* clutchSlipState, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* omniWriter) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& omniWriter) { - PX_CHECK_AND_RETURN(omniWriter, "PxVehiclePvdEngineDrivetrainWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - const OmniPvdContextHandle ch = oh.contextHandle; if(oh.engineDriveCommandStateOH && commandState) @@ -1091,38 +1068,36 @@ void PxVehiclePvdAntiRollsRegister (const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdAntiRollsRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - PX_CHECK_AND_RETURN( - antiRollForceParams.size <= objHands->nbAntirolls, + antiRollForceParams.size <= objHands.nbAntirolls, "PxVehiclePvdAntiRollsRegister - antiRollForceParams.size must be less than or equal to vallue of nbAntirolls argument in the function PxVehiclePvdObjectCreate"); // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; // Register the antiroll params. for(PxU32 i = 0; i < antiRollForceParams.size; i++) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->antiRollParamOHs[i]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.antiRollParamOHs[i]); char objectName[32] = "AntiRollParams"; appendWithInt(objectName, i); createPvdObject(ow, ch, ah.antiRollParams.CH, oh, objectName); - objHands->antiRollParamOHs[i] = oh; - addObjectHandleToSet(ow, ch, objHands->vehicleOH, ah.vehicle.antiRollSetAH, oh); + objHands.antiRollParamOHs[i] = oh; + addObjectHandleToUniqueList(ow, ch, objHands.vehicleOH, ah.vehicle.antiRollSetAH, oh); } // Register the antiroll force. if(antiRollTorque) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->antiRollTorqueOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.antiRollTorqueOH); const char objectName[32] = "AntiRollTorque"; createPvdObject(ow, ch, ah.antiRollForce.CH, oh, objectName); - objHands->antiRollTorqueOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.antiRollForceAH, oh); + objHands.antiRollTorqueOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.antiRollForceAH, oh); } } @@ -1130,10 +1105,8 @@ void PxVehiclePvdAntiRollsWrite (const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdAntiRollsWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - PX_CHECK_AND_RETURN( antiRollForceParams.size <= oh.nbAntirolls, "PxVehiclePvdAntiRollsWrite - antiRollForceParams.size must be less than or equal to vallue of nbAntirolls argument in the function PxVehiclePvdObjectCreate"); @@ -1162,10 +1135,8 @@ void PxVehiclePvdPhysXWheelAttachmentRegister const PxVehicleArrayData& physxRoadGeomState, const PxVehicleArrayData& physxConstraintStates, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdPhysXWheelAttachmentRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - PX_UNUSED(physxMaterialFrictionParams); PX_UNUSED(physxRoadGeomState); PX_UNUSED(physxConstraintStates); @@ -1173,7 +1144,7 @@ void PxVehiclePvdPhysXWheelAttachmentRegister // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; // Register the wheel attachments for(PxU32 i = 0; i < axleDesc.nbWheels; i++) @@ -1181,85 +1152,85 @@ void PxVehiclePvdPhysXWheelAttachmentRegister const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i]; PX_CHECK_AND_RETURN( - wheelId < objHands->nbWheels, + wheelId < objHands.nbWheels, "PxVehiclePvdPhysXWheelAttachmentRegister - axleDesc.axleToWheelIds[i] must be less than the value of the nbWheels argument in the function PxVehiclePvdObjectCreate()"); if(!physxSuspLimitConstraintParams.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxConstraintParamOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxConstraintParamOHs[wheelId]); char objectName[32] = "PhysXSuspLimtConstraintParams"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.physxSuspLimitConstraintParams.CH, oh, objectName); - objHands->physxConstraintParamOHs[wheelId] = oh; + objHands.physxConstraintParamOHs[wheelId] = oh; } if(physxActor && physxActor->wheelShapes[wheelId]) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxWheelShapeOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxWheelShapeOHs[wheelId]); char objectName[32] = "PhysXWheelShape"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.physxWheelShape.CH, oh, objectName); - objHands->physxWheelShapeOHs[wheelId] = oh; + objHands.physxWheelShapeOHs[wheelId] = oh; } if(!physxConstraintStates.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxConstraintStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxConstraintStateOHs[wheelId]); char objectName[32] = "PhysXConstraintState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.physxConstraintState.CH, oh, objectName); - objHands->physxConstraintStateOHs[wheelId] = oh; + objHands.physxConstraintStateOHs[wheelId] = oh; } if(!physxRoadGeomState.isEmpty()) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxRoadGeomStateOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxRoadGeomStateOHs[wheelId]); char objectName[32] = "PhysXRoadGeomState"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.physxRoadGeomState.CH, oh, objectName); - objHands->physxRoadGeomStateOHs[wheelId] = oh; + objHands.physxRoadGeomStateOHs[wheelId] = oh; } { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxWheelAttachmentOHs[wheelId]); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxWheelAttachmentOHs[wheelId]); char objectName[32] = "PhysxWheelAttachment"; appendWithInt(objectName, wheelId); createPvdObject(ow, ch, ah.physxWheelAttachment.CH, oh, objectName); - objHands->physxWheelAttachmentOHs[wheelId] = oh; + objHands.physxWheelAttachmentOHs[wheelId] = oh; - writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxConstraintParamsAH, objHands->physxConstraintParamOHs[wheelId]); - writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxWeelShapeAH, objHands->physxWheelShapeOHs[wheelId]); - writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxRoadGeometryStateAH, objHands->physxRoadGeomStateOHs[wheelId]); - writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxConstraintStateAH, objHands->physxConstraintStateOHs[wheelId]); + writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxConstraintParamsAH, objHands.physxConstraintParamOHs[wheelId]); + writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxWeelShapeAH, objHands.physxWheelShapeOHs[wheelId]); + writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxRoadGeometryStateAH, objHands.physxRoadGeomStateOHs[wheelId]); + writeObjectHandleAttribute(ow, ch, oh, ah.physxWheelAttachment.physxConstraintStateAH, objHands.physxConstraintStateOHs[wheelId]); - addObjectHandleToSet(ow, ch, objHands->vehicleOH, ah.vehicle.physxWheelAttachmentSetAH, oh); + addObjectHandleToUniqueList(ow, ch, objHands.vehicleOH, ah.vehicle.physxWheelAttachmentSetAH, oh); } if(!physxMaterialFrictionParams.isEmpty()) { - for(PxU32 j = 0; j < objHands->nbPhysXMaterialFrictions; j++) + for(PxU32 j = 0; j < objHands.nbPhysXMaterialFrictions; j++) { - const PxU32 id = wheelId*objHands->nbPhysXMaterialFrictions + j; - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxMaterialFrictionOHs[id]); + const PxU32 id = wheelId*objHands.nbPhysXMaterialFrictions + j; + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxMaterialFrictionOHs[id]); char objectName[32] = "PhysxMaterialFriction"; appendWithInt(objectName, wheelId); strcat(objectName, "_"); appendWithInt(objectName, j); createPvdObject(ow, ch, ah.physxMaterialFriction.CH, oh, objectName); - objHands->physxMaterialFrictionOHs[id] = oh; - addObjectHandleToSet(ow, ch, objHands->physxWheelAttachmentOHs[wheelId], ah.physxWheelAttachment.physxMaterialFrictionSetAH, oh); + objHands.physxMaterialFrictionOHs[id] = oh; + addObjectHandleToUniqueList(ow, ch, objHands.physxWheelAttachmentOHs[wheelId], ah.physxWheelAttachment.physxMaterialFrictionSetAH, oh); } } } if(physxRoadGeomQryParams) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxRoadGeomQueryParamOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxRoadGeomQueryParamOH); char objectName[32] = "PhysxRoadGeomQryParams"; createPvdObject(ow, ch, ah.physxRoadGeometryQueryParams.CH, oh, objectName); - objHands->physxRoadGeomQueryParamOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.physxRoadGeometryQueryParamsAH, oh); + objHands.physxRoadGeomQueryParamOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.physxRoadGeometryQueryParamsAH, oh); } } @@ -1271,10 +1242,8 @@ void PxVehiclePvdPhysXWheelAttachmentWrite const PxVehicleArrayData& physxRoadGeomStates, const PxVehicleArrayData& physxConstraintStates, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdPhysXWheelAttachmentWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - PX_UNUSED(physxMaterialFrictionParams); PX_UNUSED(physxRoadGeomStates); PX_UNUSED(physxConstraintStates); @@ -1343,31 +1312,27 @@ void PxVehiclePvdPhysXWheelAttachmentWrite void PxVehiclePvdPhysXRigidActorRegister (const PxVehiclePhysXActor* physxActor, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdPhysXRigidActorRegister: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - // Register the top-level vehicle object if this hasn't already been done. createVehicleObject(ah, objHands, ow); - const OmniPvdContextHandle ch = objHands->contextHandle; + const OmniPvdContextHandle ch = objHands.contextHandle; if(physxActor && physxActor->rigidBody) { - const OmniPvdObjectHandle oh = reinterpret_cast(&objHands->physxRigidActorOH); + const OmniPvdObjectHandle oh = reinterpret_cast(&objHands.physxRigidActorOH); createPvdObject(ow, ch, ah.physxRigidActor.CH, oh, "PhysXRigidActor"); - objHands->physxRigidActorOH = oh; - writeObjectHandleAttribute(ow, ch, objHands->vehicleOH, ah.vehicle.physxRigidActorAH, oh); + objHands.physxRigidActorOH = oh; + writeObjectHandleAttribute(ow, ch, objHands.vehicleOH, ah.vehicle.physxRigidActorAH, oh); } } void PxVehiclePvdPhysXRigidActorWrite (const PxVehiclePhysXActor* physxActor, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdPhysXRigidActorWrite: omniWriter must be a pointer to a valid OmniPvdWriter intance"); - if(oh.physxRigidActorOH && physxActor) { writePhysXRigidActor(physxActor->rigidBody, oh.physxRigidActorOH, ah.physxRigidActor, ow, oh.contextHandle); @@ -1379,7 +1344,7 @@ void PxVehiclePvdPhysXRigidActorWrite void PxVehiclePvdRigidBodyRegister (const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(rbodyParams); PX_UNUSED(rbodyState); @@ -1391,7 +1356,7 @@ void PxVehiclePvdRigidBodyRegister void PxVehiclePvdRigidBodyWrite (const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(rbodyParams); PX_UNUSED(rbodyState); @@ -1403,7 +1368,7 @@ void PxVehiclePvdRigidBodyWrite void PxVehiclePvdSuspensionStateCalculationParamsRegister (const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(suspStateCalcParams); PX_UNUSED(ah); @@ -1414,7 +1379,7 @@ void PxVehiclePvdSuspensionStateCalculationParamsRegister void PxVehiclePvdSuspensionStateCalculationParamsWrite (const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(suspStateCalcParams); PX_UNUSED(ah); @@ -1428,7 +1393,7 @@ void PxVehiclePvdCommandResponseRegister const PxVehicleArrayData& brakeResponseStates, const PxVehicleArrayData& steerResponseStates, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(steerResponseParams); PX_UNUSED(brakeResponseParams); @@ -1446,7 +1411,7 @@ void PxVehiclePvdCommandResponseWrite const PxVehicleArrayData& brakeResponseStates, const PxVehicleArrayData& steerResponseStates, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(axleDesc); PX_UNUSED(steerResponseParams); @@ -1480,7 +1445,7 @@ void PxVehiclePvdWheelAttachmentsRegister const PxVehicleArrayData& tireCamberStates, const PxVehicleArrayData& tireForces, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(axleDesc); PX_UNUSED(wheelParams); @@ -1529,7 +1494,7 @@ void PxVehiclePvdWheelAttachmentsWrite const PxVehicleArrayData& tireCamberStates, const PxVehicleArrayData& tireForces, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(axleDesc); PX_UNUSED(wheelParams); @@ -1561,7 +1526,7 @@ void PxVehiclePvdDirectDrivetrainRegister const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, const PxVehicleArrayData& directDriveThrottleResponseState, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(commandState); PX_UNUSED(transmissionState); @@ -1578,7 +1543,7 @@ void PxVehiclePvdDirectDrivetrainWrite const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, const PxVehicleArrayData& directDriveThrottleResponseState, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(axleDesc); PX_UNUSED(commandState); @@ -1607,7 +1572,7 @@ void PxVehiclePvdEngineDrivetrainRegister const PxVehicleDifferentialState* diffState, const PxVehicleClutchSlipState* clutchSlipState, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(commandState); PX_UNUSED(transmissionCommandState); @@ -1647,7 +1612,7 @@ void PxVehiclePvdEngineDrivetrainWrite const PxVehicleDifferentialState* diffState, const PxVehicleClutchSlipState* clutchSlipState, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* omniWriter) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& omniWriter) { PX_UNUSED(commandState); PX_UNUSED(transmissionCommandState); @@ -1674,7 +1639,7 @@ void PxVehiclePvdAntiRollsRegister (const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(antiRollForceParams); PX_UNUSED(antiRollTorque); @@ -1687,7 +1652,7 @@ void PxVehiclePvdAntiRollsWrite (const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(antiRollForceParams); PX_UNUSED(antiRollTorque); @@ -1704,7 +1669,7 @@ void PxVehiclePvdPhysXWheelAttachmentRegister const PxVehicleArrayData& physxRoadGeomState, const PxVehicleArrayData& physxConstraintStates, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(axleDesc); PX_UNUSED(physxSuspLimitConstraintParams); @@ -1726,7 +1691,7 @@ void PxVehiclePvdPhysXWheelAttachmentWrite const PxVehicleArrayData& physxRoadGeomStates, const PxVehicleArrayData& physxConstraintStates, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(axleDesc); PX_UNUSED(physxSuspLimitConstraintParams); @@ -1743,7 +1708,7 @@ void PxVehiclePvdPhysXWheelAttachmentWrite void PxVehiclePvdPhysXRigidActorRegister (const PxVehiclePhysXActor* physxActor, const PxVehiclePvdAttributeHandles& ah, - PxVehiclePvdObjectHandles* objHands, OmniPvdWriter* ow) + PxVehiclePvdObjectHandles& objHands, OmniPvdWriter& ow) { PX_UNUSED(physxActor); PX_UNUSED(ah); @@ -1754,7 +1719,7 @@ void PxVehiclePvdPhysXRigidActorRegister void PxVehiclePvdPhysXRigidActorWrite (const PxVehiclePhysXActor* physxActor, const PxVehiclePvdAttributeHandles& ah, - const PxVehiclePvdObjectHandles& oh, OmniPvdWriter* ow) + const PxVehiclePvdObjectHandles& oh, OmniPvdWriter& ow) { PX_UNUSED(physxActor); PX_UNUSED(ah); diff --git a/physx/source/physxvehicle2/src/pvd/VhPvdHelpers.cpp b/physx/source/physxvehicle2/src/pvd/VhPvdHelpers.cpp index 7180504e4..a183b42cc 100644 --- a/physx/source/physxvehicle2/src/pvd/VhPvdHelpers.cpp +++ b/physx/source/physxvehicle2/src/pvd/VhPvdHelpers.cpp @@ -42,10 +42,8 @@ namespace vehicle2 //ATTRIBUTE REGISTRATION /////////////////////////////// -PxVehiclePvdAttributeHandles* PxVehiclePvdAttributesCreate(PxAllocatorCallback& allocator, OmniPvdWriter* omniWriter) +PxVehiclePvdAttributeHandles* PxVehiclePvdAttributesCreate(PxAllocatorCallback& allocator, OmniPvdWriter& omniWriter) { - PX_CHECK_AND_RETURN_NULL(omniWriter, "PxVehiclePvdAttributesCreate: omniWriter must be a pointer to a valid OmniPvdWriter instance"); - PxVehiclePvdAttributeHandles* attributeHandles = reinterpret_cast( allocator.allocate(sizeof(PxVehiclePvdAttributeHandles), "PxVehiclePvdAttributeHandles", __FILE__, __LINE__)); @@ -138,12 +136,9 @@ PxVehiclePvdAttributeHandles* PxVehiclePvdAttributesCreate(PxAllocatorCallback& //ATTRIBUTE DESTRUCTION /////////////////////////////// -void PxVehiclePvdAttributesRelease(PxAllocatorCallback& allocator, OmniPvdWriter* omniWriter, PxVehiclePvdAttributeHandles* attributeHandles) +void PxVehiclePvdAttributesRelease(PxAllocatorCallback& allocator, PxVehiclePvdAttributeHandles& attributeHandles) { - PX_CHECK_AND_RETURN(omniWriter, "PxVehiclePvdAttributesRelease: omniWriter must be a pointer to a valid OmniPvdWriter instance"); - PX_CHECK_AND_RETURN(attributeHandles, "PxVehiclePvdAttributesRelease: attributeHandles must be a pointer to a valid PxVehiclePvdAttributeHandles instance"); - PX_UNUSED(omniWriter); - allocator.deallocate(attributeHandles); + allocator.deallocate(&attributeHandles); } //////////////////////////////////////// @@ -152,14 +147,9 @@ void PxVehiclePvdAttributesRelease(PxAllocatorCallback& allocator, OmniPvdWriter PxVehiclePvdObjectHandles* PxVehiclePvdObjectCreate (const PxU32 nbWheels, const PxU32 nbAntirolls, const PxU32 maxNbPhysXMaterialFrictions, - const OmniPvdContextHandle contextHandle, const PxVehiclePvdAttributeHandles& attributeHandles, OmniPvdWriter* omniWriter, + const OmniPvdContextHandle contextHandle, PxAllocatorCallback& allocator) { - PX_CHECK_AND_RETURN_NULL(omniWriter, "PxVehiclePvdObjectCreate: omniWriter must be a pointer to a valid OmniPvdWriter instance"); - - PX_UNUSED(omniWriter); - PX_UNUSED(attributeHandles); - const PxU32 byteSize = sizeof(PxVehiclePvdObjectHandles) + sizeof(OmniPvdObjectHandle)*nbWheels*( @@ -286,169 +276,148 @@ PxVehiclePvdObjectHandles* PxVehiclePvdObjectCreate //////////////////////////////////// PX_FORCE_INLINE void destroyObject -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh) { + // note: "0" needs to be replaced with a marker for invalid object handle as soon as PVD + // provides it (and PxVehiclePvdObjectCreate needs to initialize accordingly or + // compile time assert that the value is 0 for now) if(oh != 0) - omniWriter->destroyObject(ch, oh); -} - -PX_FORCE_INLINE void removeFromSet -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, - OmniPvdObjectHandle setOwnerOH, OmniPvdAttributeHandle setAH, OmniPvdObjectHandle ohToRemove) -{ - if(ohToRemove != 0 && setOwnerOH != 0) - omniWriter->removeFromSetAttributeShallow(ch, setOwnerOH, setAH, reinterpret_cast(&ohToRemove), sizeof(OmniPvdObjectHandle)); + omniWriter.destroyObject(ch, oh); } void PxVehiclePvdObjectRelease -(const PxVehiclePvdAttributeHandles& ah, - OmniPvdWriter* ow, PxAllocatorCallback& allocator, PxVehiclePvdObjectHandles* oh) +(OmniPvdWriter& ow, PxAllocatorCallback& allocator, PxVehiclePvdObjectHandles& oh) { - PX_CHECK_AND_RETURN(ow, "PxVehiclePvdObjectRelease: omniWriter must be a pointer to a valid OmniPvdWriter instance"); - PX_CHECK_AND_RETURN(oh, "PxVehiclePvdObjectRelease: objectHandles must be a pointer to a valid PxVehiclePvdObjectHandles instance"); - - const OmniPvdContextHandle ch = oh->contextHandle; + const OmniPvdContextHandle ch = oh.contextHandle; //rigid body - destroyObject(ow, ch, oh->rigidBodyParamsOH); - destroyObject(ow, ch, oh->rigidBodyStateOH); + destroyObject(ow, ch, oh.rigidBodyParamsOH); + destroyObject(ow, ch, oh.rigidBodyStateOH); //susp state calc params - destroyObject(ow, ch, oh->suspStateCalcParamsOH); + destroyObject(ow, ch, oh.suspStateCalcParamsOH); //controls for(PxU32 i = 0; i < 2; i++) { - removeFromSet(ow, ch, oh->vehicleOH, ah.vehicle.brakeResponseParamsSetAH, oh->brakeResponseParamOHs[i]); - destroyObject(ow, ch, oh->brakeResponseParamOHs[i]); + destroyObject(ow, ch, oh.brakeResponseParamOHs[i]); } - destroyObject(ow, ch, oh->steerResponseParamsOH); - destroyObject(ow, ch, oh->brakeResponseStateOH); - destroyObject(ow, ch, oh->steerResponseStateOH); + destroyObject(ow, ch, oh.steerResponseParamsOH); + destroyObject(ow, ch, oh.brakeResponseStateOH); + destroyObject(ow, ch, oh.steerResponseStateOH); //Wheel attachments - for(PxU32 i = 0; i < oh->nbWheels; i++) + for(PxU32 i = 0; i < oh.nbWheels; i++) { - destroyObject(ow, ch, oh->wheelParamsOHs[i]); - destroyObject(ow, ch, oh->wheelActuationStateOHs[i]); - destroyObject(ow, ch, oh->wheelRigidBody1dStateOHs[i]); - destroyObject(ow, ch, oh->wheelLocalPoseStateOHs[i]); - destroyObject(ow, ch, oh->suspParamsOHs[i]); - destroyObject(ow, ch, oh->suspCompParamsOHs[i]); - destroyObject(ow, ch, oh->suspForceParamsOHs[i]); - destroyObject(ow, ch, oh->suspStateOHs[i]); - destroyObject(ow, ch, oh->suspCompStateOHs[i]); - destroyObject(ow, ch, oh->suspForceOHs[i]); - destroyObject(ow, ch, oh->tireParamsOHs[i]); - destroyObject(ow, ch, oh->tireDirectionStateOHs[i]); - destroyObject(ow, ch, oh->tireSpeedStateOHs[i]); - destroyObject(ow, ch, oh->tireSlipStateOHs[i]); - destroyObject(ow, ch, oh->tireStickyStateOHs[i]); - destroyObject(ow, ch, oh->tireGripStateOHs[i]); - destroyObject(ow, ch, oh->tireCamberStateOHs[i]); - destroyObject(ow, ch, oh->tireForceOHs[i]); - removeFromSet(ow, oh->vehicleOH, ch, ah.vehicle.wheelAttachmentSetAH, oh->wheelAttachmentOHs[i]); - destroyObject(ow, ch, oh->wheelAttachmentOHs[i]); + destroyObject(ow, ch, oh.wheelParamsOHs[i]); + destroyObject(ow, ch, oh.wheelActuationStateOHs[i]); + destroyObject(ow, ch, oh.wheelRigidBody1dStateOHs[i]); + destroyObject(ow, ch, oh.wheelLocalPoseStateOHs[i]); + destroyObject(ow, ch, oh.suspParamsOHs[i]); + destroyObject(ow, ch, oh.suspCompParamsOHs[i]); + destroyObject(ow, ch, oh.suspForceParamsOHs[i]); + destroyObject(ow, ch, oh.suspStateOHs[i]); + destroyObject(ow, ch, oh.suspCompStateOHs[i]); + destroyObject(ow, ch, oh.suspForceOHs[i]); + destroyObject(ow, ch, oh.tireParamsOHs[i]); + destroyObject(ow, ch, oh.tireDirectionStateOHs[i]); + destroyObject(ow, ch, oh.tireSpeedStateOHs[i]); + destroyObject(ow, ch, oh.tireSlipStateOHs[i]); + destroyObject(ow, ch, oh.tireStickyStateOHs[i]); + destroyObject(ow, ch, oh.tireGripStateOHs[i]); + destroyObject(ow, ch, oh.tireCamberStateOHs[i]); + destroyObject(ow, ch, oh.tireForceOHs[i]); + destroyObject(ow, ch, oh.wheelAttachmentOHs[i]); } //Antiroll - for(PxU32 i = 0; i < oh->nbAntirolls; i++) + for(PxU32 i = 0; i < oh.nbAntirolls; i++) { - removeFromSet(ow, ch, oh->vehicleOH, ah.vehicle.antiRollSetAH, oh->antiRollParamOHs[i]); - destroyObject(ow, ch, oh->antiRollParamOHs[i]); + destroyObject(ow, ch, oh.antiRollParamOHs[i]); } - destroyObject(ow, ch, oh->antiRollTorqueOH); + destroyObject(ow, ch, oh.antiRollTorqueOH); //direct drive - destroyObject(ow, ch, oh->directDriveCommandStateOH); - destroyObject(ow, ch, oh->directDriveTransmissionCommandStateOH); - destroyObject(ow, ch, oh->directDriveThrottleResponseParamsOH); - destroyObject(ow, ch, oh->directDriveThrottleResponseStateOH); - destroyObject(ow, ch, oh->directDrivetrainOH); + destroyObject(ow, ch, oh.directDriveCommandStateOH); + destroyObject(ow, ch, oh.directDriveTransmissionCommandStateOH); + destroyObject(ow, ch, oh.directDriveThrottleResponseParamsOH); + destroyObject(ow, ch, oh.directDriveThrottleResponseStateOH); + destroyObject(ow, ch, oh.directDrivetrainOH); //engine drive - destroyObject(ow, ch, oh->engineDriveCommandStateOH); - destroyObject(ow, ch, oh->engineDriveTransmissionCommandStateOH); - destroyObject(ow, ch, oh->clutchResponseParamsOH); - destroyObject(ow, ch, oh->clutchParamsOH); - destroyObject(ow, ch, oh->engineParamsOH); - destroyObject(ow, ch, oh->gearboxParamsOH); - destroyObject(ow, ch, oh->autoboxParamsOH); - destroyObject(ow, ch, oh->multiWheelDiffParamsOH); - destroyObject(ow, ch, oh->fourWheelDiffParamsOH); - destroyObject(ow, ch, oh->clutchResponseStateOH); - destroyObject(ow, ch, oh->engineDriveThrottleResponseStateOH); - destroyObject(ow, ch, oh->engineStateOH); - destroyObject(ow, ch, oh->gearboxStateOH); - destroyObject(ow, ch, oh->autoboxStateOH); - destroyObject(ow, ch, oh->diffStateOH); - destroyObject(ow, ch, oh->clutchSlipStateOH); - destroyObject(ow, ch, oh->engineDrivetrainOH); + destroyObject(ow, ch, oh.engineDriveCommandStateOH); + destroyObject(ow, ch, oh.engineDriveTransmissionCommandStateOH); + destroyObject(ow, ch, oh.clutchResponseParamsOH); + destroyObject(ow, ch, oh.clutchParamsOH); + destroyObject(ow, ch, oh.engineParamsOH); + destroyObject(ow, ch, oh.gearboxParamsOH); + destroyObject(ow, ch, oh.autoboxParamsOH); + destroyObject(ow, ch, oh.multiWheelDiffParamsOH); + destroyObject(ow, ch, oh.fourWheelDiffParamsOH); + destroyObject(ow, ch, oh.clutchResponseStateOH); + destroyObject(ow, ch, oh.engineDriveThrottleResponseStateOH); + destroyObject(ow, ch, oh.engineStateOH); + destroyObject(ow, ch, oh.gearboxStateOH); + destroyObject(ow, ch, oh.autoboxStateOH); + destroyObject(ow, ch, oh.diffStateOH); + destroyObject(ow, ch, oh.clutchSlipStateOH); + destroyObject(ow, ch, oh.engineDrivetrainOH); //PhysX Wheel attachments - for(PxU32 i = 0; i < oh->nbWheels; i++) + for(PxU32 i = 0; i < oh.nbWheels; i++) { - destroyObject(ow, ch, oh->physxConstraintParamOHs[i]); - destroyObject(ow, ch, oh->physxWheelShapeOHs[i]); - destroyObject(ow, ch, oh->physxRoadGeomStateOHs[i]); - destroyObject(ow, ch, oh->physxConstraintStateOHs[i]); - for(PxU32 j = 0; j < oh->nbPhysXMaterialFrictions; j++) + destroyObject(ow, ch, oh.physxConstraintParamOHs[i]); + destroyObject(ow, ch, oh.physxWheelShapeOHs[i]); + destroyObject(ow, ch, oh.physxRoadGeomStateOHs[i]); + destroyObject(ow, ch, oh.physxConstraintStateOHs[i]); + for(PxU32 j = 0; j < oh.nbPhysXMaterialFrictions; j++) { - const PxU32 id = i*oh->nbPhysXMaterialFrictions + j; - removeFromSet(ow, ch, - oh->physxWheelAttachmentOHs[i], ah.physxWheelAttachment.physxMaterialFrictionSetAH, - oh->physxMaterialFrictionOHs[id]); - destroyObject(ow, ch, oh->physxMaterialFrictionOHs[id]); + const PxU32 id = i*oh.nbPhysXMaterialFrictions + j; + destroyObject(ow, ch, oh.physxMaterialFrictionOHs[id]); } - removeFromSet(ow, ch, oh->vehicleOH, ah.vehicle.physxWheelAttachmentSetAH, oh->physxWheelAttachmentOHs[i]); - destroyObject(ow, ch, oh->physxWheelAttachmentOHs[i]); + destroyObject(ow, ch, oh.physxWheelAttachmentOHs[i]); } //Physx rigid actor - destroyObject(ow, ch, oh->physxRoadGeomQueryParamOH); - destroyObject(ow, ch, oh->physxRigidActorOH); + destroyObject(ow, ch, oh.physxRoadGeomQueryParamOH); + destroyObject(ow, ch, oh.physxRigidActorOH); //Free the memory. - allocator.deallocate(oh); + allocator.deallocate(&oh); } #else //#if PX_SUPPORT_OMNI_PVD -PxVehiclePvdAttributeHandles* PxVehiclePvdAttributesCreate(PxAllocatorCallback& allocator, OmniPvdWriter* omniWriter) +PxVehiclePvdAttributeHandles* PxVehiclePvdAttributesCreate(PxAllocatorCallback& allocator, OmniPvdWriter& omniWriter) { PX_UNUSED(allocator); PX_UNUSED(omniWriter); return NULL; } -void PxVehiclePvdAttributesRelease(PxAllocatorCallback& allocator, OmniPvdWriter* omniWriter, PxVehiclePvdAttributeHandles* attributeHandles) +void PxVehiclePvdAttributesRelease(PxAllocatorCallback& allocator, PxVehiclePvdAttributeHandles& attributeHandles) { PX_UNUSED(allocator); - PX_UNUSED(omniWriter); PX_UNUSED(attributeHandles); } PxVehiclePvdObjectHandles* PxVehiclePvdObjectCreate (const PxU32 nbWheels, const PxU32 nbAntirolls, const PxU32 maxNbPhysXMaterialFrictions, - const PxU64 contextHandle, const PxVehiclePvdAttributeHandles& attributeHandles, OmniPvdWriter* omniWriter, + const PxU64 contextHandle, PxAllocatorCallback& allocator) { PX_UNUSED(nbWheels); PX_UNUSED(nbAntirolls); PX_UNUSED(maxNbPhysXMaterialFrictions); PX_UNUSED(contextHandle); - PX_UNUSED(attributeHandles); - PX_UNUSED(omniWriter); PX_UNUSED(allocator); return NULL; } void PxVehiclePvdObjectRelease -(const PxVehiclePvdAttributeHandles& ah, - OmniPvdWriter* ow, PxAllocatorCallback& allocator, PxVehiclePvdObjectHandles* oh) +(OmniPvdWriter& ow, PxAllocatorCallback& allocator, PxVehiclePvdObjectHandles& oh) { - PX_UNUSED(ah); PX_UNUSED(ow); PX_UNUSED(allocator); PX_UNUSED(oh); diff --git a/physx/source/physxvehicle2/src/pvd/VhPvdWriter.cpp b/physx/source/physxvehicle2/src/pvd/VhPvdWriter.cpp index 2f3214dbc..6461590ae 100644 --- a/physx/source/physxvehicle2/src/pvd/VhPvdWriter.cpp +++ b/physx/source/physxvehicle2/src/pvd/VhPvdWriter.cpp @@ -36,64 +36,64 @@ namespace vehicle2 #if PX_SUPPORT_OMNI_PVD PX_FORCE_INLINE void writeFloatAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, float val) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, float val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(float)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(float)); } PX_FORCE_INLINE void writeFloatArrayAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const float* val, const PxU32 nbVals) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const float* val, const PxU32 nbVals) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(val), sizeof(float) * nbVals); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(val), sizeof(float) * nbVals); } PX_FORCE_INLINE void writeUInt32ArrayAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const uint32_t* val, const PxU32 nbVals) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const uint32_t* val, const PxU32 nbVals) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(val), sizeof(uint32_t) * nbVals); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(val), sizeof(uint32_t) * nbVals); } PX_FORCE_INLINE void writeVec3Attribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const PxVec3& val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(PxVec3)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(PxVec3)); } PX_FORCE_INLINE void writePlaneAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const PxPlane& val) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const PxPlane& val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(PxPlane)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(PxPlane)); } PX_FORCE_INLINE void writeQuatAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const PxQuat& val) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const PxQuat& val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(PxQuat)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(PxQuat)); } PX_FORCE_INLINE void writeUInt8Attribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, uint8_t val) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, uint8_t val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(uint8_t)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(uint8_t)); } PX_FORCE_INLINE void writeUInt32Attribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, uint32_t val) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, uint32_t val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(uint32_t)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(uint32_t)); } PX_FORCE_INLINE void writeFlagAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, uint32_t val) +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, uint32_t val) { writeUInt32Attribute(omniWriter, ch, oh, ah, val); } PX_FORCE_INLINE void writeLookupTableAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, PxVehicleFixedSizeLookupTable val) { float buffer[6] = { -1.0f, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f }; @@ -102,11 +102,11 @@ PX_FORCE_INLINE void writeLookupTableAttribute buffer[2 * i + 0] = val.xVals[i]; buffer[2 * i + 1] = val.yVals[i]; } - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(buffer), sizeof(buffer)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(buffer), sizeof(buffer)); } PX_FORCE_INLINE void writeLookupTableAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, PxVehicleFixedSizeLookupTable val) { float buffer[12] = { -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f }; @@ -117,55 +117,55 @@ PX_FORCE_INLINE void writeLookupTableAttribute buffer[4 * i + 2] = val.yVals[i].y; buffer[4 * i + 3] = val.yVals[i].z; } - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(buffer), sizeof(buffer)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(buffer), sizeof(buffer)); } void writePtrAttribute -(OmniPvdWriter* omniWriter, OmniPvdContextHandle ch, +(OmniPvdWriter& omniWriter, OmniPvdContextHandle ch, OmniPvdObjectHandle oh, OmniPvdAttributeHandle ah, const void* val) { - omniWriter->setAttributeShallow(ch, oh, ah, reinterpret_cast(&val), sizeof(val)); + omniWriter.setAttribute(ch, oh, ah, reinterpret_cast(&val), sizeof(val)); } //////////////////////////////// //RIGID BODY //////////////////////////////// -RigidBodyParams registerRigidBodyParams(OmniPvdWriter* omniWriter) +RigidBodyParams registerRigidBodyParams(OmniPvdWriter& omniWriter) { RigidBodyParams r; - r.CH = omniWriter->registerClass("RigidBodyParams"); - r.massAH = omniWriter->registerAttribute(r.CH, "mass", OmniPvdDataTypeEnum::eFLOAT32, 1); - r.moiAH = omniWriter->registerAttribute(r.CH, "moi", OmniPvdDataTypeEnum::eFLOAT32, 3); + r.CH = omniWriter.registerClass("RigidBodyParams"); + r.massAH = omniWriter.registerAttribute(r.CH, "mass", OmniPvdDataType::eFLOAT32, 1); + r.moiAH = omniWriter.registerAttribute(r.CH, "moi", OmniPvdDataType::eFLOAT32, 3); return r; } void writeRigidBodyParams (const PxVehicleRigidBodyParams& rbodyParams, - const OmniPvdObjectHandle oh, const RigidBodyParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const RigidBodyParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.massAH, rbodyParams.mass); writeVec3Attribute(omniWriter, ch, oh, ah.moiAH, rbodyParams.moi); } -RigidBodyState registerRigidBodyState(OmniPvdWriter* omniWriter) +RigidBodyState registerRigidBodyState(OmniPvdWriter& omniWriter) { RigidBodyState r; - r.CH = omniWriter->registerClass("RigidBodyState"); - r.posAH = omniWriter->registerAttribute(r.CH, "pos", OmniPvdDataTypeEnum::eFLOAT32, 3); - r.quatAH = omniWriter->registerAttribute(r.CH, "quat", OmniPvdDataTypeEnum::eFLOAT32, 4); - r.linearVelocityAH = omniWriter->registerAttribute(r.CH, "linvel", OmniPvdDataTypeEnum::eFLOAT32, 3); - r.angularVelocityAH = omniWriter->registerAttribute(r.CH, "angvel", OmniPvdDataTypeEnum::eFLOAT32, 3); - r.previousLinearVelocityAH = omniWriter->registerAttribute(r.CH, "prevLinvel", OmniPvdDataTypeEnum::eFLOAT32, 3); - r.previousAngularVelocityAH = omniWriter->registerAttribute(r.CH, "prevAngvel", OmniPvdDataTypeEnum::eFLOAT32, 3); - r.externalForceAH = omniWriter->registerAttribute(r.CH, "extForce", OmniPvdDataTypeEnum::eFLOAT32, 3); - r.externalTorqueAH = omniWriter->registerAttribute(r.CH, "extTorque", OmniPvdDataTypeEnum::eFLOAT32, 3); + r.CH = omniWriter.registerClass("RigidBodyState"); + r.posAH = omniWriter.registerAttribute(r.CH, "pos", OmniPvdDataType::eFLOAT32, 3); + r.quatAH = omniWriter.registerAttribute(r.CH, "quat", OmniPvdDataType::eFLOAT32, 4); + r.linearVelocityAH = omniWriter.registerAttribute(r.CH, "linvel", OmniPvdDataType::eFLOAT32, 3); + r.angularVelocityAH = omniWriter.registerAttribute(r.CH, "angvel", OmniPvdDataType::eFLOAT32, 3); + r.previousLinearVelocityAH = omniWriter.registerAttribute(r.CH, "prevLinvel", OmniPvdDataType::eFLOAT32, 3); + r.previousAngularVelocityAH = omniWriter.registerAttribute(r.CH, "prevAngvel", OmniPvdDataType::eFLOAT32, 3); + r.externalForceAH = omniWriter.registerAttribute(r.CH, "extForce", OmniPvdDataType::eFLOAT32, 3); + r.externalTorqueAH = omniWriter.registerAttribute(r.CH, "extTorque", OmniPvdDataType::eFLOAT32, 3); return r; } void writeRigidBodyState (const PxVehicleRigidBodyState& rbodyState, - const OmniPvdObjectHandle oh, const RigidBodyState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const RigidBodyState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.posAH, rbodyState.pose.p); writeQuatAttribute(omniWriter, ch, oh, ah.quatAH, rbodyState.pose.q); @@ -184,54 +184,54 @@ void writeRigidBodyState //CONTROLS ///////////////////////////////// -WheelResponseParams registerWheelResponseParams(const char* name, OmniPvdWriter* omniWriter) +WheelResponseParams registerWheelResponseParams(const char* name, OmniPvdWriter& omniWriter) { WheelResponseParams w; - w.CH = omniWriter->registerClass(name); - w.maxResponseAH = omniWriter->registerAttribute(w.CH, "maxResponse", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.responseMultipliers0To3AH = omniWriter->registerAttribute(w.CH, "wheelMultipliers0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseMultipliers4To7AH = omniWriter->registerAttribute(w.CH, "wheelMultipliers4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseMultipliers8To11AH = omniWriter->registerAttribute(w.CH, "wheelMultipliers8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseMultipliers12To15AH = omniWriter->registerAttribute(w.CH, "wheelMultipliers12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseMultipliers16To19AH = omniWriter->registerAttribute(w.CH, "wheelMultipliers16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); + w.CH = omniWriter.registerClass(name); + w.maxResponseAH = omniWriter.registerAttribute(w.CH, "maxResponse", OmniPvdDataType::eFLOAT32, 1); + w.responseMultipliers0To3AH = omniWriter.registerAttribute(w.CH, "wheelMultipliers0To3", OmniPvdDataType::eFLOAT32, 4); + w.responseMultipliers4To7AH = omniWriter.registerAttribute(w.CH, "wheelMultipliers4To7", OmniPvdDataType::eFLOAT32, 4); + w.responseMultipliers8To11AH = omniWriter.registerAttribute(w.CH, "wheelMultipliers8To11", OmniPvdDataType::eFLOAT32, 4); + w.responseMultipliers12To15AH = omniWriter.registerAttribute(w.CH, "wheelMultipliers12To15", OmniPvdDataType::eFLOAT32, 4); + w.responseMultipliers16To19AH = omniWriter.registerAttribute(w.CH, "wheelMultipliers16To19", OmniPvdDataType::eFLOAT32, 4); return w; } -WheelResponseParams registerSteerResponseParams(OmniPvdWriter* omniWriter) +WheelResponseParams registerSteerResponseParams(OmniPvdWriter& omniWriter) { return registerWheelResponseParams("SteerResponseParams", omniWriter); } -WheelResponseParams registerBrakeResponseParams(OmniPvdWriter* omniWriter) +WheelResponseParams registerBrakeResponseParams(OmniPvdWriter& omniWriter) { return registerWheelResponseParams("BrakeResponseParams", omniWriter); } -WheelResponseStates registerWheelResponseStates(const char* name, OmniPvdWriter* omniWriter) +WheelResponseStates registerWheelResponseStates(const char* name, OmniPvdWriter& omniWriter) { WheelResponseStates w; - w.CH = omniWriter->registerClass(name); - w.responseStates0To3AH = omniWriter->registerAttribute(w.CH, "wheelStates0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseStates4To7AH = omniWriter->registerAttribute(w.CH, "wheelStatess4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseStates8To11AH = omniWriter->registerAttribute(w.CH, "wheelStates8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseStates12To15AH = omniWriter->registerAttribute(w.CH, "wheelStates12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - w.responseStates16To19AH = omniWriter->registerAttribute(w.CH, "wheelStates16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); + w.CH = omniWriter.registerClass(name); + w.responseStates0To3AH = omniWriter.registerAttribute(w.CH, "wheelStates0To3", OmniPvdDataType::eFLOAT32, 4); + w.responseStates4To7AH = omniWriter.registerAttribute(w.CH, "wheelStatess4To7", OmniPvdDataType::eFLOAT32, 4); + w.responseStates8To11AH = omniWriter.registerAttribute(w.CH, "wheelStates8To11", OmniPvdDataType::eFLOAT32, 4); + w.responseStates12To15AH = omniWriter.registerAttribute(w.CH, "wheelStates12To15", OmniPvdDataType::eFLOAT32, 4); + w.responseStates16To19AH = omniWriter.registerAttribute(w.CH, "wheelStates16To19", OmniPvdDataType::eFLOAT32, 4); return w; } -WheelResponseStates registerSteerResponseStates(OmniPvdWriter* omniWriter) +WheelResponseStates registerSteerResponseStates(OmniPvdWriter& omniWriter) { return registerWheelResponseStates("SteerResponseState", omniWriter); } -WheelResponseStates registerBrakeResponseStates(OmniPvdWriter* omniWriter) +WheelResponseStates registerBrakeResponseStates(OmniPvdWriter& omniWriter) { return registerWheelResponseStates("BrakeResponseState", omniWriter); } void writeWheelResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleCommandResponseParams& responseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.maxResponseAH, responseParams.maxResponse); @@ -255,7 +255,7 @@ void writeWheelResponseParams void writeSteerResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleSteerCommandResponseParams& steerResponseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeWheelResponseParams(axleDesc, steerResponseParams, oh, ah, omniWriter, ch); } @@ -263,14 +263,14 @@ void writeSteerResponseParams void writeBrakeResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleBrakeCommandResponseParams& brakeResponseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeWheelResponseParams(axleDesc, brakeResponseParams, oh, ah, omniWriter, ch); } void writeWheelResponseStates (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& responseState, - const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { float responseStates[PxVehicleLimits::eMAX_NB_WHEELS]; PxMemZero(responseStates, sizeof(responseStates)); @@ -289,7 +289,7 @@ void writeWheelResponseStates void writeSteerResponseStates (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& steerResponseStates, - const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeWheelResponseStates(axleDesc, steerResponseStates, oh, ah, omniWriter, ch); } @@ -297,7 +297,7 @@ void writeSteerResponseStates void writeBrakeResponseStates (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& brakeResponseStates, - const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeWheelResponseStates(axleDesc, brakeResponseStates, oh, ah, omniWriter, ch); } @@ -305,7 +305,7 @@ void writeBrakeResponseStates void writeClutchResponseParams (const PxVehicleClutchCommandResponseParams& clutchResponseParams, - const OmniPvdObjectHandle oh, const ClutchResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const ClutchResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.maxResponseAH, clutchResponseParams.maxResponse); } @@ -314,21 +314,21 @@ void writeClutchResponseParams //WHEEL ATTACHMENTS ////////////////////////////// -WheelParams registerWheelParams(OmniPvdWriter* omniWriter) +WheelParams registerWheelParams(OmniPvdWriter& omniWriter) { WheelParams w; - w.CH = omniWriter->registerClass("WheelParams"); - w.wheelRadiusAH = omniWriter->registerAttribute(w.CH, "radius", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.halfWidthAH = omniWriter->registerAttribute(w.CH, "halfWidth", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.massAH = omniWriter->registerAttribute(w.CH, "mass", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.moiAH = omniWriter->registerAttribute(w.CH, "moi", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.dampingRateAH = omniWriter->registerAttribute(w.CH, "dampingRate", OmniPvdDataTypeEnum::eFLOAT32, 1); + w.CH = omniWriter.registerClass("WheelParams"); + w.wheelRadiusAH = omniWriter.registerAttribute(w.CH, "radius", OmniPvdDataType::eFLOAT32, 1); + w.halfWidthAH = omniWriter.registerAttribute(w.CH, "halfWidth", OmniPvdDataType::eFLOAT32, 1); + w.massAH = omniWriter.registerAttribute(w.CH, "mass", OmniPvdDataType::eFLOAT32, 1); + w.moiAH = omniWriter.registerAttribute(w.CH, "moi", OmniPvdDataType::eFLOAT32, 1); + w.dampingRateAH = omniWriter.registerAttribute(w.CH, "dampingRate", OmniPvdDataType::eFLOAT32, 1); return w; } void writeWheelParams (const PxVehicleWheelParams& params, - const OmniPvdObjectHandle oh, const WheelParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.dampingRateAH, params.dampingRate); writeFloatAttribute(omniWriter, ch, oh, ah.halfWidthAH, params.halfWidth); @@ -337,7 +337,7 @@ void writeWheelParams writeFloatAttribute(omniWriter, ch, oh, ah.wheelRadiusAH, params.radius); } -WheelActuationState registerWheelActuationState(OmniPvdWriter* omniWriter) +WheelActuationState registerWheelActuationState(OmniPvdWriter& omniWriter) { struct BoolAsEnum { @@ -346,64 +346,64 @@ WheelActuationState registerWheelActuationState(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle trueAH; }; BoolAsEnum boolAsEnum; - boolAsEnum.CH = omniWriter->registerClass("WheelStateBool"); - boolAsEnum.falseAH = omniWriter->registerEnumValue(boolAsEnum.CH, "False", 0); - boolAsEnum.trueAH = omniWriter->registerEnumValue(boolAsEnum.CH, "True", 1); + boolAsEnum.CH = omniWriter.registerClass("WheelStateBool"); + boolAsEnum.falseAH = omniWriter.registerEnumValue(boolAsEnum.CH, "False", 0); + boolAsEnum.trueAH = omniWriter.registerEnumValue(boolAsEnum.CH, "True", 1); WheelActuationState w; - w.CH = omniWriter->registerClass("WheelActuationState"); - w.isBrakeAppliedAH = omniWriter->registerFlagsAttribute(w.CH, boolAsEnum.CH, "isBrakeApplied"); - w.isDriveAppliedAH = omniWriter->registerFlagsAttribute(w.CH, boolAsEnum.CH, "isDriveApplied"); + w.CH = omniWriter.registerClass("WheelActuationState"); + w.isBrakeAppliedAH = omniWriter.registerFlagsAttribute(w.CH, "isBrakeApplied", boolAsEnum.CH); + w.isDriveAppliedAH = omniWriter.registerFlagsAttribute(w.CH, "isDriveApplied", boolAsEnum.CH); return w; } void writeWheelActuationState (const PxVehicleWheelActuationState& actState, - const OmniPvdObjectHandle oh, const WheelActuationState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelActuationState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.isBrakeAppliedAH, actState.isBrakeApplied ? 1 : 0); writeFlagAttribute(omniWriter, ch, oh, ah.isDriveAppliedAH, actState.isDriveApplied ? 1 : 0); } -WheelRigidBody1dState registerWheelRigidBody1dState(OmniPvdWriter* omniWriter) +WheelRigidBody1dState registerWheelRigidBody1dState(OmniPvdWriter& omniWriter) { WheelRigidBody1dState w; - w.CH = omniWriter->registerClass("WheelRigidBodyState"); - w.rotationSpeedAH = omniWriter->registerAttribute(w.CH, "rotationSpeed", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.correctedRotationSpeedAH = omniWriter->registerAttribute(w.CH, "correctedRotationSpeed", OmniPvdDataTypeEnum::eFLOAT32, 1); - w.rotationAngleAH = omniWriter->registerAttribute(w.CH, "rotationAngle", OmniPvdDataTypeEnum::eFLOAT32, 1); + w.CH = omniWriter.registerClass("WheelRigidBodyState"); + w.rotationSpeedAH = omniWriter.registerAttribute(w.CH, "rotationSpeed", OmniPvdDataType::eFLOAT32, 1); + w.correctedRotationSpeedAH = omniWriter.registerAttribute(w.CH, "correctedRotationSpeed", OmniPvdDataType::eFLOAT32, 1); + w.rotationAngleAH = omniWriter.registerAttribute(w.CH, "rotationAngle", OmniPvdDataType::eFLOAT32, 1); return w; } void writeWheelRigidBody1dState (const PxVehicleWheelRigidBody1dState& rigidBodyState, - const OmniPvdObjectHandle oh, const WheelRigidBody1dState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelRigidBody1dState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.rotationSpeedAH, rigidBodyState.rotationSpeed); writeFloatAttribute(omniWriter, ch, oh, ah.correctedRotationSpeedAH, rigidBodyState.correctedRotationSpeed); writeFloatAttribute(omniWriter, ch, oh, ah.rotationAngleAH, rigidBodyState.rotationAngle); } -WheelLocalPoseState registerWheelLocalPoseState(OmniPvdWriter* omniWriter) +WheelLocalPoseState registerWheelLocalPoseState(OmniPvdWriter& omniWriter) { WheelLocalPoseState w; - w.CH = omniWriter->registerClass("WheelLocalPoseState"); - w.posAH = omniWriter->registerAttribute(w.CH, "posInRbodyFrame", OmniPvdDataTypeEnum::eFLOAT32, 3); - w.quatAH = omniWriter->registerAttribute(w.CH, "quatInRbodyFrame", OmniPvdDataTypeEnum::eFLOAT32, 4); + w.CH = omniWriter.registerClass("WheelLocalPoseState"); + w.posAH = omniWriter.registerAttribute(w.CH, "posInRbodyFrame", OmniPvdDataType::eFLOAT32, 3); + w.quatAH = omniWriter.registerAttribute(w.CH, "quatInRbodyFrame", OmniPvdDataType::eFLOAT32, 4); return w; } void writeWheelLocalPoseState (const PxVehicleWheelLocalPose& pose, - const OmniPvdObjectHandle oh, const WheelLocalPoseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelLocalPoseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.posAH, pose.localPose.p); writeQuatAttribute(omniWriter, ch, oh, ah.quatAH, pose.localPose.q); } -RoadGeometryState registerRoadGeomState(OmniPvdWriter* omniWriter) +RoadGeometryState registerRoadGeomState(OmniPvdWriter& omniWriter) { struct BoolAsEnum { @@ -412,22 +412,22 @@ RoadGeometryState registerRoadGeomState(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle trueAH; }; BoolAsEnum boolAsEnum; - boolAsEnum.CH = omniWriter->registerClass("RoadGeomStateBool"); - boolAsEnum.falseAH = omniWriter->registerEnumValue(boolAsEnum.CH, "False", 0); - boolAsEnum.trueAH = omniWriter->registerEnumValue(boolAsEnum.CH, "True", 1); + boolAsEnum.CH = omniWriter.registerClass("RoadGeomStateBool"); + boolAsEnum.falseAH = omniWriter.registerEnumValue(boolAsEnum.CH, "False", 0); + boolAsEnum.trueAH = omniWriter.registerEnumValue(boolAsEnum.CH, "True", 1); RoadGeometryState r; - r.CH = omniWriter->registerClass("RoadGeometryState"); - r.planeAH = omniWriter->registerAttribute(r.CH, "plane", OmniPvdDataTypeEnum::eFLOAT32, 4); - r.frictionAH = omniWriter->registerAttribute(r.CH, "friction", OmniPvdDataTypeEnum::eFLOAT32, 1); - r.hitStateAH = omniWriter->registerFlagsAttribute(r.CH, boolAsEnum.CH, "hitState"); - r.velocityAH = omniWriter->registerAttribute(r.CH, "hitVelocity", OmniPvdDataTypeEnum::eFLOAT32, 3); + r.CH = omniWriter.registerClass("RoadGeometryState"); + r.planeAH = omniWriter.registerAttribute(r.CH, "plane", OmniPvdDataType::eFLOAT32, 4); + r.frictionAH = omniWriter.registerAttribute(r.CH, "friction", OmniPvdDataType::eFLOAT32, 1); + r.hitStateAH = omniWriter.registerFlagsAttribute(r.CH, "hitState", boolAsEnum.CH); + r.velocityAH = omniWriter.registerAttribute(r.CH, "hitVelocity", OmniPvdDataType::eFLOAT32, 3); return r; } void writeRoadGeomState (const PxVehicleRoadGeometryState& roadGeometryState, - const OmniPvdObjectHandle oh, const RoadGeometryState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const RoadGeometryState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writePlaneAttribute(omniWriter, ch, oh, ah.planeAH, roadGeometryState.plane); writeFloatAttribute(omniWriter, ch, oh, ah.frictionAH, roadGeometryState.friction); @@ -435,22 +435,22 @@ void writeRoadGeomState writeVec3Attribute(omniWriter, ch, oh, ah.velocityAH, roadGeometryState.velocity); } -SuspParams registerSuspParams(OmniPvdWriter* omniWriter) +SuspParams registerSuspParams(OmniPvdWriter& omniWriter) { SuspParams s; - s.CH = omniWriter->registerClass("SuspensionParams"); - s.suspAttachmentPosAH = omniWriter->registerAttribute(s.CH, "suspAttachmentPos", OmniPvdDataTypeEnum::eFLOAT32, 3); - s.suspAttachmentQuatAH = omniWriter->registerAttribute(s.CH, "suspAttachmentQuat", OmniPvdDataTypeEnum::eFLOAT32, 4); - s.suspDirAH = omniWriter->registerAttribute(s.CH, "suspDir", OmniPvdDataTypeEnum::eFLOAT32, 3); - s.suspTravleDistAH = omniWriter->registerAttribute(s.CH, "suspTravelDist", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.wheelAttachmentPosAH = omniWriter->registerAttribute(s.CH, "wheelAttachmentPos", OmniPvdDataTypeEnum::eFLOAT32, 3); - s.wheelAttachmentQuatAH = omniWriter->registerAttribute(s.CH, "wheelAttachmentQuat", OmniPvdDataTypeEnum::eFLOAT32, 3); + s.CH = omniWriter.registerClass("SuspensionParams"); + s.suspAttachmentPosAH = omniWriter.registerAttribute(s.CH, "suspAttachmentPos", OmniPvdDataType::eFLOAT32, 3); + s.suspAttachmentQuatAH = omniWriter.registerAttribute(s.CH, "suspAttachmentQuat", OmniPvdDataType::eFLOAT32, 4); + s.suspDirAH = omniWriter.registerAttribute(s.CH, "suspDir", OmniPvdDataType::eFLOAT32, 3); + s.suspTravleDistAH = omniWriter.registerAttribute(s.CH, "suspTravelDist", OmniPvdDataType::eFLOAT32, 1); + s.wheelAttachmentPosAH = omniWriter.registerAttribute(s.CH, "wheelAttachmentPos", OmniPvdDataType::eFLOAT32, 3); + s.wheelAttachmentQuatAH = omniWriter.registerAttribute(s.CH, "wheelAttachmentQuat", OmniPvdDataType::eFLOAT32, 3); return s; } void writeSuspParams (const PxVehicleSuspensionParams& suspParams, - const OmniPvdObjectHandle oh, const SuspParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.suspAttachmentPosAH, suspParams.suspensionAttachment.p); writeQuatAttribute(omniWriter, ch, oh, ah.suspAttachmentQuatAH, suspParams.suspensionAttachment.q); @@ -461,20 +461,20 @@ void writeSuspParams } -SuspCompParams registerSuspComplianceParams(OmniPvdWriter* omniWriter) +SuspCompParams registerSuspComplianceParams(OmniPvdWriter& omniWriter) { SuspCompParams s; - s.CH = omniWriter->registerClass("SuspensionComplianceParams"); - s.toeAngleAH = omniWriter->registerAttribute(s.CH, "toeAngle", OmniPvdDataTypeEnum::eFLOAT32, 6); - s.camberAngleAH = omniWriter->registerAttribute(s.CH, "camberAngle", OmniPvdDataTypeEnum::eFLOAT32, 6); - s.suspForceAppPointAH = omniWriter->registerAttribute(s.CH, "suspForceAppPoint", OmniPvdDataTypeEnum::eFLOAT32, 12); - s.tireForceAppPointAH = omniWriter->registerAttribute(s.CH, "tireForceAppPoint", OmniPvdDataTypeEnum::eFLOAT32, 12); + s.CH = omniWriter.registerClass("SuspensionComplianceParams"); + s.toeAngleAH = omniWriter.registerAttribute(s.CH, "toeAngle", OmniPvdDataType::eFLOAT32, 6); + s.camberAngleAH = omniWriter.registerAttribute(s.CH, "camberAngle", OmniPvdDataType::eFLOAT32, 6); + s.suspForceAppPointAH = omniWriter.registerAttribute(s.CH, "suspForceAppPoint", OmniPvdDataType::eFLOAT32, 12); + s.tireForceAppPointAH = omniWriter.registerAttribute(s.CH, "tireForceAppPoint", OmniPvdDataType::eFLOAT32, 12); return s; } void writeSuspComplianceParams (const PxVehicleSuspensionComplianceParams& compParams, - const OmniPvdObjectHandle oh, const SuspCompParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspCompParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeLookupTableAttribute(omniWriter, ch, oh, ah.camberAngleAH, compParams.wheelCamberAngle); writeLookupTableAttribute(omniWriter, ch, oh, ah.toeAngleAH, compParams.wheelToeAngle); @@ -482,58 +482,58 @@ void writeSuspComplianceParams writeLookupTableAttribute(omniWriter, ch, oh, ah.tireForceAppPointAH, compParams.tireForceAppPoint); } -SuspForceParams registerSuspForceParams(OmniPvdWriter* omniWriter) +SuspForceParams registerSuspForceParams(OmniPvdWriter& omniWriter) { SuspForceParams s; - s.CH = omniWriter->registerClass("SuspensionForceParams"); - s.stiffnessAH = omniWriter->registerAttribute(s.CH, "stiffness", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.dampingAH = omniWriter->registerAttribute(s.CH, "damping", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.sprungMassAH = omniWriter->registerAttribute(s.CH, "sprungMass", OmniPvdDataTypeEnum::eFLOAT32, 1); + s.CH = omniWriter.registerClass("SuspensionForceParams"); + s.stiffnessAH = omniWriter.registerAttribute(s.CH, "stiffness", OmniPvdDataType::eFLOAT32, 1); + s.dampingAH = omniWriter.registerAttribute(s.CH, "damping", OmniPvdDataType::eFLOAT32, 1); + s.sprungMassAH = omniWriter.registerAttribute(s.CH, "sprungMass", OmniPvdDataType::eFLOAT32, 1); return s; } void writeSuspForceParams (const PxVehicleSuspensionForceParams& forceParams, - const OmniPvdObjectHandle oh, const SuspForceParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspForceParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.dampingAH, forceParams.damping); writeFloatAttribute(omniWriter, ch, oh, ah.sprungMassAH, forceParams.sprungMass); writeFloatAttribute(omniWriter, ch, oh, ah.stiffnessAH, forceParams.stiffness); } -SuspState registerSuspState(OmniPvdWriter* omniWriter) +SuspState registerSuspState(OmniPvdWriter& omniWriter) { SuspState s; - s.CH = omniWriter->registerClass("SuspensionState"); - s.jounceAH = omniWriter->registerAttribute(s.CH, "jounce", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.jounceSpeedAH = omniWriter->registerAttribute(s.CH, "jounceSpeed", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.separationAH = omniWriter->registerAttribute(s.CH, "separation", OmniPvdDataTypeEnum::eFLOAT32, 1); + s.CH = omniWriter.registerClass("SuspensionState"); + s.jounceAH = omniWriter.registerAttribute(s.CH, "jounce", OmniPvdDataType::eFLOAT32, 1); + s.jounceSpeedAH = omniWriter.registerAttribute(s.CH, "jounceSpeed", OmniPvdDataType::eFLOAT32, 1); + s.separationAH = omniWriter.registerAttribute(s.CH, "separation", OmniPvdDataType::eFLOAT32, 1); return s; } void writeSuspState (const PxVehicleSuspensionState& suspState, - const OmniPvdObjectHandle oh, const SuspState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.jounceAH, suspState.jounce); writeFloatAttribute(omniWriter, ch, oh, ah.jounceSpeedAH, suspState.jounceSpeed); writeFloatAttribute(omniWriter, ch, oh, ah.separationAH, suspState.separation); } -SuspCompState registerSuspComplianceState(OmniPvdWriter* omniWriter) +SuspCompState registerSuspComplianceState(OmniPvdWriter& omniWriter) { SuspCompState s; - s.CH = omniWriter->registerClass("SuspensionComplianceState"); - s.toeAH = omniWriter->registerAttribute(s.CH, "toe", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.camberAH = omniWriter->registerAttribute(s.CH, "camber", OmniPvdDataTypeEnum::eFLOAT32, 1); - s.tireForceAppPointAH = omniWriter->registerAttribute(s.CH, "tireForceAppPoint", OmniPvdDataTypeEnum::eFLOAT32, 3); - s.suspForceAppPointAH = omniWriter->registerAttribute(s.CH, "suspForceAppPoint", OmniPvdDataTypeEnum::eFLOAT32, 3); + s.CH = omniWriter.registerClass("SuspensionComplianceState"); + s.toeAH = omniWriter.registerAttribute(s.CH, "toe", OmniPvdDataType::eFLOAT32, 1); + s.camberAH = omniWriter.registerAttribute(s.CH, "camber", OmniPvdDataType::eFLOAT32, 1); + s.tireForceAppPointAH = omniWriter.registerAttribute(s.CH, "tireForceAppPoint", OmniPvdDataType::eFLOAT32, 3); + s.suspForceAppPointAH = omniWriter.registerAttribute(s.CH, "suspForceAppPoint", OmniPvdDataType::eFLOAT32, 3); return s; } void writeSuspComplianceState (const PxVehicleSuspensionComplianceState& suspCompState, - const OmniPvdObjectHandle oh, const SuspCompState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspCompState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.camberAH, suspCompState.camber); writeFloatAttribute(omniWriter, ch, oh, ah.toeAH, suspCompState.toe); @@ -541,42 +541,42 @@ void writeSuspComplianceState writeVec3Attribute(omniWriter, ch, oh, ah.tireForceAppPointAH, suspCompState.tireForceAppPoint); } -SuspForce registerSuspForce(OmniPvdWriter* omniWriter) +SuspForce registerSuspForce(OmniPvdWriter& omniWriter) { SuspForce s; - s.CH = omniWriter->registerClass("SuspensionForce"); - s.forceAH = omniWriter->registerAttribute(s.CH, "force", OmniPvdDataTypeEnum::eFLOAT32, 3); - s.torqueAH = omniWriter->registerAttribute(s.CH, "torque", OmniPvdDataTypeEnum::eFLOAT32, 3); - s.normalForceAH = omniWriter->registerAttribute(s.CH, "normalForce", OmniPvdDataTypeEnum::eFLOAT32, 3); + s.CH = omniWriter.registerClass("SuspensionForce"); + s.forceAH = omniWriter.registerAttribute(s.CH, "force", OmniPvdDataType::eFLOAT32, 3); + s.torqueAH = omniWriter.registerAttribute(s.CH, "torque", OmniPvdDataType::eFLOAT32, 3); + s.normalForceAH = omniWriter.registerAttribute(s.CH, "normalForce", OmniPvdDataType::eFLOAT32, 3); return s; } void writeSuspForce (const PxVehicleSuspensionForce& suspForce, - const OmniPvdObjectHandle oh, const SuspForce& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspForce& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.forceAH, suspForce.force); writeVec3Attribute(omniWriter, ch, oh, ah.torqueAH, suspForce.torque); writeFloatAttribute(omniWriter, ch, oh, ah.normalForceAH, suspForce.normalForce); } -TireParams registerTireParams(OmniPvdWriter* omniWriter) +TireParams registerTireParams(OmniPvdWriter& omniWriter) { TireParams t; - t.CH = omniWriter->registerClass("TireParams"); - t.latStiffXAH = omniWriter->registerAttribute(t.CH, "latStiffX", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.latStiffYAH = omniWriter->registerAttribute(t.CH, "latStiffY", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.longStiffAH = omniWriter->registerAttribute(t.CH, "longStiff", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.camberStiffAH = omniWriter->registerAttribute(t.CH, "camberStiff", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.frictionVsSlipAH = omniWriter->registerAttribute(t.CH, "frictionVsSlip", OmniPvdDataTypeEnum::eFLOAT32, 6); - t.restLoadAH = omniWriter->registerAttribute(t.CH, "restLoad", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.loadFilterAH = omniWriter->registerAttribute(t.CH, "loadFilter", OmniPvdDataTypeEnum::eFLOAT32, 4); + t.CH = omniWriter.registerClass("TireParams"); + t.latStiffXAH = omniWriter.registerAttribute(t.CH, "latStiffX", OmniPvdDataType::eFLOAT32, 1); + t.latStiffYAH = omniWriter.registerAttribute(t.CH, "latStiffY", OmniPvdDataType::eFLOAT32, 1); + t.longStiffAH = omniWriter.registerAttribute(t.CH, "longStiff", OmniPvdDataType::eFLOAT32, 1); + t.camberStiffAH = omniWriter.registerAttribute(t.CH, "camberStiff", OmniPvdDataType::eFLOAT32, 1); + t.frictionVsSlipAH = omniWriter.registerAttribute(t.CH, "frictionVsSlip", OmniPvdDataType::eFLOAT32, 6); + t.restLoadAH = omniWriter.registerAttribute(t.CH, "restLoad", OmniPvdDataType::eFLOAT32, 1); + t.loadFilterAH = omniWriter.registerAttribute(t.CH, "loadFilter", OmniPvdDataType::eFLOAT32, 4); return t; } void writeTireParams (const PxVehicleTireForceParams& tireParams, - const OmniPvdObjectHandle oh, const TireParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.latStiffXAH, tireParams.latStiffX); writeFloatAttribute(omniWriter, ch, oh, ah.latStiffYAH, tireParams.latStiffY); @@ -597,58 +597,58 @@ void writeTireParams writeFloatArrayAttribute(omniWriter, ch, oh, ah.loadFilterAH, loadFilter, 4); } -TireDirectionState registerTireDirectionState(OmniPvdWriter* omniWriter) +TireDirectionState registerTireDirectionState(OmniPvdWriter& omniWriter) { TireDirectionState t; - t.CH = omniWriter->registerClass("TireDirectionState"); - t.lngDirectionAH = omniWriter->registerAttribute(t.CH, "lngDir", OmniPvdDataTypeEnum::eFLOAT32, 3); - t.latDirectionAH = omniWriter->registerAttribute(t.CH, "latDir", OmniPvdDataTypeEnum::eFLOAT32, 3); + t.CH = omniWriter.registerClass("TireDirectionState"); + t.lngDirectionAH = omniWriter.registerAttribute(t.CH, "lngDir", OmniPvdDataType::eFLOAT32, 3); + t.latDirectionAH = omniWriter.registerAttribute(t.CH, "latDir", OmniPvdDataType::eFLOAT32, 3); return t; } void writeTireDirectionState (const PxVehicleTireDirectionState& tireDirState, - const OmniPvdObjectHandle oh, const TireDirectionState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireDirectionState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.lngDirectionAH, tireDirState.directions[PxVehicleTireDirectionModes::eLONGITUDINAL]); writeVec3Attribute(omniWriter, ch, oh, ah.latDirectionAH, tireDirState.directions[PxVehicleTireDirectionModes::eLATERAL]); } -TireSpeedState registerTireSpeedState(OmniPvdWriter* omniWriter) +TireSpeedState registerTireSpeedState(OmniPvdWriter& omniWriter) { TireSpeedState t; - t.CH = omniWriter->registerClass("TireSpeedState"); - t.lngSpeedAH = omniWriter->registerAttribute(t.CH, "lngSpeed", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.latSpeedAH = omniWriter->registerAttribute(t.CH, "latSpeed", OmniPvdDataTypeEnum::eFLOAT32, 1); + t.CH = omniWriter.registerClass("TireSpeedState"); + t.lngSpeedAH = omniWriter.registerAttribute(t.CH, "lngSpeed", OmniPvdDataType::eFLOAT32, 1); + t.latSpeedAH = omniWriter.registerAttribute(t.CH, "latSpeed", OmniPvdDataType::eFLOAT32, 1); return t; } void writeTireSpeedState (const PxVehicleTireSpeedState& tireSpeedState, - const OmniPvdObjectHandle oh, const TireSpeedState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireSpeedState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.lngSpeedAH, tireSpeedState.speedStates[PxVehicleTireDirectionModes::eLONGITUDINAL]); writeFloatAttribute(omniWriter, ch, oh, ah.latSpeedAH, tireSpeedState.speedStates[PxVehicleTireDirectionModes::eLATERAL]); } -TireSlipState registerTireSlipState(OmniPvdWriter* omniWriter) +TireSlipState registerTireSlipState(OmniPvdWriter& omniWriter) { TireSlipState t; - t.CH = omniWriter->registerClass("TireSlipState"); - t.lngSlipAH = omniWriter->registerAttribute(t.CH, "lngSlip", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.latSlipAH = omniWriter->registerAttribute(t.CH, "latSlip", OmniPvdDataTypeEnum::eFLOAT32, 1); + t.CH = omniWriter.registerClass("TireSlipState"); + t.lngSlipAH = omniWriter.registerAttribute(t.CH, "lngSlip", OmniPvdDataType::eFLOAT32, 1); + t.latSlipAH = omniWriter.registerAttribute(t.CH, "latSlip", OmniPvdDataType::eFLOAT32, 1); return t; } void writeTireSlipState (const PxVehicleTireSlipState& tireSlipState, - const OmniPvdObjectHandle oh, const TireSlipState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireSlipState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.lngSlipAH, tireSlipState.slips[PxVehicleTireDirectionModes::eLONGITUDINAL]); writeFloatAttribute(omniWriter, ch, oh, ah.latSlipAH, tireSlipState.slips[PxVehicleTireDirectionModes::eLATERAL]); } -TireStickyState registerTireStickyState(OmniPvdWriter* omniWriter) +TireStickyState registerTireStickyState(OmniPvdWriter& omniWriter) { struct BoolAsEnum { @@ -657,22 +657,22 @@ TireStickyState registerTireStickyState(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle trueAH; }; BoolAsEnum boolAsEnum; - boolAsEnum.CH = omniWriter->registerClass("StickyTireBool"); - boolAsEnum.falseAH = omniWriter->registerEnumValue(boolAsEnum.CH, "False", 0); - boolAsEnum.trueAH = omniWriter->registerEnumValue(boolAsEnum.CH, "True", 1); + boolAsEnum.CH = omniWriter.registerClass("StickyTireBool"); + boolAsEnum.falseAH = omniWriter.registerEnumValue(boolAsEnum.CH, "False", 0); + boolAsEnum.trueAH = omniWriter.registerEnumValue(boolAsEnum.CH, "True", 1); TireStickyState t; - t.CH = omniWriter->registerClass("TireStickyState"); - t.lngStickyStateTimer = omniWriter->registerAttribute(t.CH, "lngStickyTimer", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.lngStickyStateStatus = omniWriter->registerFlagsAttribute(t.CH, boolAsEnum.CH, "lngStickyStatus"); - t.latStickyStateTimer = omniWriter->registerAttribute(t.CH, "latStickyTimer", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.latStickyStateStatus = omniWriter->registerFlagsAttribute(t.CH, boolAsEnum.CH, "latStickyStatus"); + t.CH = omniWriter.registerClass("TireStickyState"); + t.lngStickyStateTimer = omniWriter.registerAttribute(t.CH, "lngStickyTimer", OmniPvdDataType::eFLOAT32, 1); + t.lngStickyStateStatus = omniWriter.registerFlagsAttribute(t.CH, "lngStickyStatus", boolAsEnum.CH); + t.latStickyStateTimer = omniWriter.registerAttribute(t.CH, "latStickyTimer", OmniPvdDataType::eFLOAT32, 1); + t.latStickyStateStatus = omniWriter.registerFlagsAttribute(t.CH, "latStickyStatus", boolAsEnum.CH); return t; } void writeTireStickyState (const PxVehicleTireStickyState& tireStickyState, - const OmniPvdObjectHandle oh, const TireStickyState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireStickyState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.latStickyStateStatus, tireStickyState.activeStatus[PxVehicleTireDirectionModes::eLATERAL] ? 1 : 0); writeFlagAttribute(omniWriter, ch, oh, ah.lngStickyStateStatus, tireStickyState.activeStatus[PxVehicleTireDirectionModes::eLONGITUDINAL] ? 1 : 0); @@ -680,58 +680,58 @@ void writeTireStickyState writeFloatAttribute(omniWriter, ch, oh, ah.lngStickyStateTimer, tireStickyState.lowSpeedTime[PxVehicleTireDirectionModes::eLONGITUDINAL]); } -TireGripState registerTireGripState(OmniPvdWriter* omniWriter) +TireGripState registerTireGripState(OmniPvdWriter& omniWriter) { TireGripState t; - t.CH = omniWriter->registerClass("TireGripState"); - t.loadAH = omniWriter->registerAttribute(t.CH, "load", OmniPvdDataTypeEnum::eFLOAT32, 1); - t.frictionAH = omniWriter->registerAttribute(t.CH, "friction", OmniPvdDataTypeEnum::eFLOAT32, 1); + t.CH = omniWriter.registerClass("TireGripState"); + t.loadAH = omniWriter.registerAttribute(t.CH, "load", OmniPvdDataType::eFLOAT32, 1); + t.frictionAH = omniWriter.registerAttribute(t.CH, "friction", OmniPvdDataType::eFLOAT32, 1); return t; } void writeTireGripState (const PxVehicleTireGripState& tireGripState, - const OmniPvdObjectHandle oh, const TireGripState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireGripState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.frictionAH, tireGripState.friction); writeFloatAttribute(omniWriter, ch, oh, ah.loadAH, tireGripState.load); } -TireCamberState registerTireCamberState(OmniPvdWriter* omniWriter) +TireCamberState registerTireCamberState(OmniPvdWriter& omniWriter) { TireCamberState t; - t.CH = omniWriter->registerClass("TireCamberState"); - t.camberAngleAH = omniWriter->registerAttribute(t.CH, "camberAngle", OmniPvdDataTypeEnum::eFLOAT32, 1); + t.CH = omniWriter.registerClass("TireCamberState"); + t.camberAngleAH = omniWriter.registerAttribute(t.CH, "camberAngle", OmniPvdDataType::eFLOAT32, 1); return t; } void writeTireCamberState (const PxVehicleTireCamberAngleState& tireCamberState, - const OmniPvdObjectHandle oh, const TireCamberState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireCamberState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.camberAngleAH, tireCamberState.camberAngle); } -TireForce registerTireForce(OmniPvdWriter* omniWriter) +TireForce registerTireForce(OmniPvdWriter& omniWriter) { TireForce t; - t.CH = omniWriter->registerClass("TireForce"); + t.CH = omniWriter.registerClass("TireForce"); - t.lngForceAH = omniWriter->registerAttribute(t.CH, "lngForce", OmniPvdDataTypeEnum::eFLOAT32, 3); - t.lngTorqueAH = omniWriter->registerAttribute(t.CH, "lngTorque", OmniPvdDataTypeEnum::eFLOAT32, 3); + t.lngForceAH = omniWriter.registerAttribute(t.CH, "lngForce", OmniPvdDataType::eFLOAT32, 3); + t.lngTorqueAH = omniWriter.registerAttribute(t.CH, "lngTorque", OmniPvdDataType::eFLOAT32, 3); - t.latForceAH = omniWriter->registerAttribute(t.CH, "latForce", OmniPvdDataTypeEnum::eFLOAT32, 3); - t.latTorqueAH = omniWriter->registerAttribute(t.CH, "latTorque", OmniPvdDataTypeEnum::eFLOAT32, 3); + t.latForceAH = omniWriter.registerAttribute(t.CH, "latForce", OmniPvdDataType::eFLOAT32, 3); + t.latTorqueAH = omniWriter.registerAttribute(t.CH, "latTorque", OmniPvdDataType::eFLOAT32, 3); - t.aligningMomentAH = omniWriter->registerAttribute(t.CH, "aligningMoment", OmniPvdDataTypeEnum::eFLOAT32, 3); - t.wheelTorqueAH = omniWriter->registerAttribute(t.CH, "wheelTorque", OmniPvdDataTypeEnum::eFLOAT32, 3); + t.aligningMomentAH = omniWriter.registerAttribute(t.CH, "aligningMoment", OmniPvdDataType::eFLOAT32, 3); + t.wheelTorqueAH = omniWriter.registerAttribute(t.CH, "wheelTorque", OmniPvdDataType::eFLOAT32, 3); return t; } void writeTireForce (const PxVehicleTireForce& tireForce, - const OmniPvdObjectHandle oh, const TireForce& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const TireForce& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.lngForceAH, tireForce.forces[PxVehicleTireDirectionModes::eLONGITUDINAL]); writeVec3Attribute(omniWriter, ch, oh, ah.lngTorqueAH, tireForce.torques[PxVehicleTireDirectionModes::eLONGITUDINAL]); @@ -741,29 +741,29 @@ void writeTireForce writeFloatAttribute(omniWriter, ch, oh, ah.wheelTorqueAH, tireForce.wheelTorque); } -WheelAttachment registerWheelAttachment(OmniPvdWriter* omniWriter) +WheelAttachment registerWheelAttachment(OmniPvdWriter& omniWriter) { WheelAttachment w; - w.CH = omniWriter->registerClass("WheelAttachment"); - w.wheelParamsAH = omniWriter->registerAttribute(w.CH, "wheelParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.wheelActuationStateAH = omniWriter->registerAttribute(w.CH, "wheelActuationState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.wheelRigidBody1dStateAH = omniWriter->registerAttribute(w.CH, "wheelRigidBody1dState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.wheelLocalPoseStateAH = omniWriter->registerAttribute(w.CH, "wheelLocalPosetate", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.roadGeomStateAH = omniWriter->registerAttribute(w.CH, "roadGeomState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.suspParamsAH = omniWriter->registerAttribute(w.CH, "suspParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.suspCompParamsAH = omniWriter->registerAttribute(w.CH, "suspComplianceParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.suspForceParamsAH = omniWriter->registerAttribute(w.CH, "suspForceParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.suspStateAH = omniWriter->registerAttribute(w.CH, "suspState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.suspCompStateAH = omniWriter->registerAttribute(w.CH, "suspComplianceState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.suspForceAH = omniWriter->registerAttribute(w.CH, "suspForce", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireParamsAH = omniWriter->registerAttribute(w.CH, "tireParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireDirectionStateAH = omniWriter->registerAttribute(w.CH, "tireDirectionState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireSpeedStateAH = omniWriter->registerAttribute(w.CH, "tireSpeedState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireSlipStateAH = omniWriter->registerAttribute(w.CH, "tireSlipState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireStickyStateAH = omniWriter->registerAttribute(w.CH, "tireStickyState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireGripStateAH = omniWriter->registerAttribute(w.CH, "tireGripState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireCamberStateAH = omniWriter->registerAttribute(w.CH, "tireCamberState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.tireForceAH = omniWriter->registerAttribute(w.CH, "tireForce", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + w.CH = omniWriter.registerClass("WheelAttachment"); + w.wheelParamsAH = omniWriter.registerAttribute(w.CH, "wheelParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.wheelActuationStateAH = omniWriter.registerAttribute(w.CH, "wheelActuationState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.wheelRigidBody1dStateAH = omniWriter.registerAttribute(w.CH, "wheelRigidBody1dState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.wheelLocalPoseStateAH = omniWriter.registerAttribute(w.CH, "wheelLocalPosetate", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.roadGeomStateAH = omniWriter.registerAttribute(w.CH, "roadGeomState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.suspParamsAH = omniWriter.registerAttribute(w.CH, "suspParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.suspCompParamsAH = omniWriter.registerAttribute(w.CH, "suspComplianceParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.suspForceParamsAH = omniWriter.registerAttribute(w.CH, "suspForceParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.suspStateAH = omniWriter.registerAttribute(w.CH, "suspState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.suspCompStateAH = omniWriter.registerAttribute(w.CH, "suspComplianceState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.suspForceAH = omniWriter.registerAttribute(w.CH, "suspForce", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireParamsAH = omniWriter.registerAttribute(w.CH, "tireParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireDirectionStateAH = omniWriter.registerAttribute(w.CH, "tireDirectionState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireSpeedStateAH = omniWriter.registerAttribute(w.CH, "tireSpeedState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireSlipStateAH = omniWriter.registerAttribute(w.CH, "tireSlipState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireStickyStateAH = omniWriter.registerAttribute(w.CH, "tireStickyState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireGripStateAH = omniWriter.registerAttribute(w.CH, "tireGripState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireCamberStateAH = omniWriter.registerAttribute(w.CH, "tireCamberState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.tireForceAH = omniWriter.registerAttribute(w.CH, "tireForce", OmniPvdDataType::eOBJECT_HANDLE, 1); return w; } @@ -771,36 +771,36 @@ WheelAttachment registerWheelAttachment(OmniPvdWriter* omniWriter) //ANTIROLL ////////////////////////// -AntiRollParams registerAntiRollParams(OmniPvdWriter* omniWriter) +AntiRollParams registerAntiRollParams(OmniPvdWriter& omniWriter) { AntiRollParams a; - a.CH = omniWriter->registerClass("AntiRollParams"); - a.wheel0AH = omniWriter->registerAttribute(a.CH, "wheel0", OmniPvdDataTypeEnum::eUINT32, 1); - a.wheel1AH = omniWriter->registerAttribute(a.CH, "wheel1", OmniPvdDataTypeEnum::eUINT32, 1); - a.stiffnessAH = omniWriter->registerAttribute(a.CH, "stiffness", OmniPvdDataTypeEnum::eFLOAT32, 1); + a.CH = omniWriter.registerClass("AntiRollParams"); + a.wheel0AH = omniWriter.registerAttribute(a.CH, "wheel0", OmniPvdDataType::eUINT32, 1); + a.wheel1AH = omniWriter.registerAttribute(a.CH, "wheel1", OmniPvdDataType::eUINT32, 1); + a.stiffnessAH = omniWriter.registerAttribute(a.CH, "stiffness", OmniPvdDataType::eFLOAT32, 1); return a; } void writeAntiRollParams (const PxVehicleAntiRollForceParams& antiRollParams, - const OmniPvdObjectHandle oh, const AntiRollParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const AntiRollParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeUInt32Attribute(omniWriter, ch, oh, ah.wheel0AH, antiRollParams.wheel0); writeUInt32Attribute(omniWriter, ch, oh, ah.wheel1AH, antiRollParams.wheel1); writeFloatAttribute(omniWriter, ch, oh, ah.stiffnessAH, antiRollParams.stiffness); } -AntiRollForce registerAntiRollForce(OmniPvdWriter* omniWriter) +AntiRollForce registerAntiRollForce(OmniPvdWriter& omniWriter) { AntiRollForce a; - a.CH = omniWriter->registerClass("AntiRollForce"); - a.torqueAH = omniWriter->registerAttribute(a.CH, "torque", OmniPvdDataTypeEnum::eFLOAT32, 3); + a.CH = omniWriter.registerClass("AntiRollForce"); + a.torqueAH = omniWriter.registerAttribute(a.CH, "torque", OmniPvdDataType::eFLOAT32, 3); return a; } void writeAntiRollForce (const PxVehicleAntiRollTorque& antiRollForce, - const OmniPvdObjectHandle oh, const AntiRollForce& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const AntiRollForce& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.torqueAH, antiRollForce.antiRollTorque); } @@ -810,7 +810,7 @@ void writeAntiRollForce //SUSPENSION STATE CALCULATION ////////////////////////////////// -SuspStateCalcParams registerSuspStateCalcParams(OmniPvdWriter* omniWriter) +SuspStateCalcParams registerSuspStateCalcParams(OmniPvdWriter& omniWriter) { struct SuspJounceCalcType { @@ -820,10 +820,10 @@ SuspStateCalcParams registerSuspStateCalcParams(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle noneAH; }; SuspJounceCalcType jounceCalcType; - jounceCalcType.CH = omniWriter->registerClass("SuspJounceCalculationType"); - jounceCalcType.raycastAH = omniWriter->registerEnumValue(jounceCalcType.CH, "raycast", PxVehicleSuspensionJounceCalculationType::eRAYCAST); - jounceCalcType.sweepAH = omniWriter->registerEnumValue(jounceCalcType.CH, "sweep", PxVehicleSuspensionJounceCalculationType::eSWEEP); - jounceCalcType.noneAH = omniWriter->registerEnumValue(jounceCalcType.CH, "none", PxVehicleSuspensionJounceCalculationType::eMAX_NB); + jounceCalcType.CH = omniWriter.registerClass("SuspJounceCalculationType"); + jounceCalcType.raycastAH = omniWriter.registerEnumValue(jounceCalcType.CH, "raycast", PxVehicleSuspensionJounceCalculationType::eRAYCAST); + jounceCalcType.sweepAH = omniWriter.registerEnumValue(jounceCalcType.CH, "sweep", PxVehicleSuspensionJounceCalculationType::eSWEEP); + jounceCalcType.noneAH = omniWriter.registerEnumValue(jounceCalcType.CH, "none", PxVehicleSuspensionJounceCalculationType::eMAX_NB); struct BoolAsEnum { @@ -832,20 +832,20 @@ SuspStateCalcParams registerSuspStateCalcParams(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle trueAH; }; BoolAsEnum boolAsEnum; - boolAsEnum.CH = omniWriter->registerClass("SuspStateCalcParamsBool"); - boolAsEnum.falseAH = omniWriter->registerEnumValue(boolAsEnum.CH, "False", 0); - boolAsEnum.trueAH = omniWriter->registerEnumValue(boolAsEnum.CH, "True", 1); + boolAsEnum.CH = omniWriter.registerClass("SuspStateCalcParamsBool"); + boolAsEnum.falseAH = omniWriter.registerEnumValue(boolAsEnum.CH, "False", 0); + boolAsEnum.trueAH = omniWriter.registerEnumValue(boolAsEnum.CH, "True", 1); SuspStateCalcParams s; - s.CH = omniWriter->registerClass("SuspStateCalculationParams"); - s.calcTypeAH = omniWriter->registerFlagsAttribute(s.CH, jounceCalcType.CH, "suspJounceCalculationType"); - s.limitExpansionValAH = omniWriter->registerFlagsAttribute(s.CH, boolAsEnum.CH, "limitSuspensionExpansionVelocity"); + s.CH = omniWriter.registerClass("SuspStateCalculationParams"); + s.calcTypeAH = omniWriter.registerFlagsAttribute(s.CH, "suspJounceCalculationType", jounceCalcType.CH); + s.limitExpansionValAH = omniWriter.registerFlagsAttribute(s.CH, "limitSuspensionExpansionVelocity", boolAsEnum.CH); return s; } void writeSuspStateCalcParams (const PxVehicleSuspensionStateCalculationParams& suspStateCalcParams, - const OmniPvdObjectHandle oh, const SuspStateCalcParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const SuspStateCalcParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.limitExpansionValAH, suspStateCalcParams.limitSuspensionExpansionVelocity ? 1 : 0); writeFlagAttribute(omniWriter, ch, oh, ah.calcTypeAH, suspStateCalcParams.suspensionJounceCalculationType); @@ -855,19 +855,19 @@ void writeSuspStateCalcParams //DIRECT DRIVETRAIN ////////////////////////////////////// -DirectDriveCommandState registerDirectDriveCommandState(OmniPvdWriter* omniWriter) +DirectDriveCommandState registerDirectDriveCommandState(OmniPvdWriter& omniWriter) { DirectDriveCommandState c; - c.CH = omniWriter->registerClass("DirectDriveCommandState"); - c.brakesAH= omniWriter->registerAttribute(c.CH, "brakes", OmniPvdDataTypeEnum::eFLOAT32, 2); - c.throttleAH= omniWriter->registerAttribute(c.CH, "throttle", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.steerAH= omniWriter->registerAttribute(c.CH, "steer", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("DirectDriveCommandState"); + c.brakesAH= omniWriter.registerAttribute(c.CH, "brakes", OmniPvdDataType::eFLOAT32, 2); + c.throttleAH= omniWriter.registerAttribute(c.CH, "throttle", OmniPvdDataType::eFLOAT32, 1); + c.steerAH= omniWriter.registerAttribute(c.CH, "steer", OmniPvdDataType::eFLOAT32, 1); return c; } void writeDirectDriveCommandState (const PxVehicleCommandState& commands, - const OmniPvdObjectHandle oh, const DirectDriveCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const DirectDriveCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { float brakes[2]; for(PxU32 i = 0; i < commands.nbBrakes; i++) @@ -883,7 +883,7 @@ void writeDirectDriveCommandState writeFloatAttribute(omniWriter, ch, oh, ah.steerAH, commands.steer); } -DirectDriveTransmissionCommandState registerDirectDriveTransmissionCommandState(OmniPvdWriter* omniWriter) +DirectDriveTransmissionCommandState registerDirectDriveTransmissionCommandState(OmniPvdWriter& omniWriter) { struct DirectDriveGear { @@ -894,25 +894,25 @@ DirectDriveTransmissionCommandState registerDirectDriveTransmissionCommandState( }; DirectDriveGear g; - g.CH = omniWriter->registerClass("DirectDriveGear"); - g.reverse = omniWriter->registerEnumValue(g.CH, "reverse", PxVehicleDirectDriveTransmissionCommandState::eREVERSE); - g.neutral = omniWriter->registerEnumValue(g.CH, "neutral", PxVehicleDirectDriveTransmissionCommandState::eNEUTRAL); - g.forward = omniWriter->registerEnumValue(g.CH, "forward", PxVehicleDirectDriveTransmissionCommandState::eFORWARD); + g.CH = omniWriter.registerClass("DirectDriveGear"); + g.reverse = omniWriter.registerEnumValue(g.CH, "reverse", PxVehicleDirectDriveTransmissionCommandState::eREVERSE); + g.neutral = omniWriter.registerEnumValue(g.CH, "neutral", PxVehicleDirectDriveTransmissionCommandState::eNEUTRAL); + g.forward = omniWriter.registerEnumValue(g.CH, "forward", PxVehicleDirectDriveTransmissionCommandState::eFORWARD); DirectDriveTransmissionCommandState c; - c.CH = omniWriter->registerClass("DirectDriveTransmissionCommandState"); - c.gearAH = omniWriter->registerFlagsAttribute(c.CH, g.CH, "gear"); + c.CH = omniWriter.registerClass("DirectDriveTransmissionCommandState"); + c.gearAH = omniWriter.registerFlagsAttribute(c.CH, "gear", g.CH); return c; } void writeDirectDriveTransmissionCommandState (const PxVehicleDirectDriveTransmissionCommandState& transmission, - const OmniPvdObjectHandle oh, const DirectDriveTransmissionCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const DirectDriveTransmissionCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.gearAH, transmission.gear); } -WheelResponseParams registerDirectDriveThrottleResponseParams(OmniPvdWriter* omniWriter) +WheelResponseParams registerDirectDriveThrottleResponseParams(OmniPvdWriter& omniWriter) { return registerWheelResponseParams("DirectDriveThrottleResponseParams", omniWriter); } @@ -920,26 +920,26 @@ WheelResponseParams registerDirectDriveThrottleResponseParams(OmniPvdWriter* omn void writeDirectDriveThrottleResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleDirectDriveThrottleCommandResponseParams& directDriveThrottleResponseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeWheelResponseParams(axleDesc, directDriveThrottleResponseParams, oh, ah, omniWriter, ch); } -DirectDriveThrottleResponseState registerDirectDriveThrottleResponseState(OmniPvdWriter* omniWriter) +DirectDriveThrottleResponseState registerDirectDriveThrottleResponseState(OmniPvdWriter& omniWriter) { DirectDriveThrottleResponseState d; - d.CH = omniWriter->registerClass("DirectDriveThrottleResponseState"); - d.states0To3AH = omniWriter->registerAttribute(d.CH, "responseState0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.states4To7AH = omniWriter->registerAttribute(d.CH, "responseState4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.states8To11AH = omniWriter->registerAttribute(d.CH, "responseState8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.states12To15AH = omniWriter->registerAttribute(d.CH, "responseState12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.states16To19AH = omniWriter->registerAttribute(d.CH, "responseState16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); + d.CH = omniWriter.registerClass("DirectDriveThrottleResponseState"); + d.states0To3AH = omniWriter.registerAttribute(d.CH, "responseState0To3", OmniPvdDataType::eFLOAT32, 4); + d.states4To7AH = omniWriter.registerAttribute(d.CH, "responseState4To7", OmniPvdDataType::eFLOAT32, 4); + d.states8To11AH = omniWriter.registerAttribute(d.CH, "responseState8To11", OmniPvdDataType::eFLOAT32, 4); + d.states12To15AH = omniWriter.registerAttribute(d.CH, "responseState12To15", OmniPvdDataType::eFLOAT32, 4); + d.states16To19AH = omniWriter.registerAttribute(d.CH, "responseState16To19", OmniPvdDataType::eFLOAT32, 4); return d; } void writeDirectDriveThrottleResponseState (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& throttleResponseState, - const OmniPvdObjectHandle oh, const DirectDriveThrottleResponseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const DirectDriveThrottleResponseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { //States are always in setToDefault() state as default. PxF32 states[PxVehicleLimits::eMAX_NB_WHEELS]; @@ -961,13 +961,13 @@ void writeDirectDriveThrottleResponseState writeFloatArrayAttribute(omniWriter, ch, oh, ah.states16To19AH, states + 16, 4); } -DirectDrivetrain registerDirectDrivetrain(OmniPvdWriter* omniWriter) +DirectDrivetrain registerDirectDrivetrain(OmniPvdWriter& omniWriter) { DirectDrivetrain d; - d.CH = omniWriter->registerClass("DirectDrivetrain"); - d.throttleResponseParamsAH = omniWriter->registerAttribute(d.CH, "throttleResponseParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - d.commandStateAH = omniWriter->registerAttribute(d.CH, "directDriveCommandState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - d.throttleResponseStateAH = omniWriter->registerAttribute(d.CH, "throttleResponseState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + d.CH = omniWriter.registerClass("DirectDrivetrain"); + d.throttleResponseParamsAH = omniWriter.registerAttribute(d.CH, "throttleResponseParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + d.commandStateAH = omniWriter.registerAttribute(d.CH, "directDriveCommandState", OmniPvdDataType::eOBJECT_HANDLE, 1); + d.throttleResponseStateAH = omniWriter.registerAttribute(d.CH, "throttleResponseState", OmniPvdDataType::eOBJECT_HANDLE, 1); return d; } @@ -976,20 +976,20 @@ DirectDrivetrain registerDirectDrivetrain(OmniPvdWriter* omniWriter) //ENGINE DRIVETRAIN ////////////////////////////// -EngineDriveCommandState registerEngineDriveCommandState(OmniPvdWriter* omniWriter) +EngineDriveCommandState registerEngineDriveCommandState(OmniPvdWriter& omniWriter) { EngineDriveCommandState c; - c.CH = omniWriter->registerClass("EngineDriveCommandState"); - c.brakes= omniWriter->registerAttribute(c.CH, "brakes", OmniPvdDataTypeEnum::eFLOAT32, 2); - c.throttle= omniWriter->registerAttribute(c.CH, "throttle", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.steer= omniWriter->registerAttribute(c.CH, "steer", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("EngineDriveCommandState"); + c.brakesAH = omniWriter.registerAttribute(c.CH, "brakes", OmniPvdDataType::eFLOAT32, 2); + c.throttleAH = omniWriter.registerAttribute(c.CH, "throttle", OmniPvdDataType::eFLOAT32, 1); + c.steerAH = omniWriter.registerAttribute(c.CH, "steer", OmniPvdDataType::eFLOAT32, 1); return c; } void writeEngineDriveCommandState (const PxVehicleCommandState& commands, - const OmniPvdObjectHandle oh, const EngineDriveCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const EngineDriveCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { float brakes[2]; for(PxU32 i = 0; i < commands.nbBrakes; i++) @@ -1000,37 +1000,37 @@ void writeEngineDriveCommandState { brakes[i] = PX_MAX_F32; } - writeFloatArrayAttribute(omniWriter, ch, oh, ah.brakes, brakes, 2); - writeFloatAttribute(omniWriter, ch, oh, ah.throttle, commands.throttle); - writeFloatAttribute(omniWriter, ch, oh, ah.steer, commands.steer); + writeFloatArrayAttribute(omniWriter, ch, oh, ah.brakesAH, brakes, 2); + writeFloatAttribute(omniWriter, ch, oh, ah.throttleAH, commands.throttle); + writeFloatAttribute(omniWriter, ch, oh, ah.steerAH, commands.steer); } -EngineDriveTransmissionCommandState registerEngineDriveTransmissionCommandState(OmniPvdWriter* omniWriter) +EngineDriveTransmissionCommandState registerEngineDriveTransmissionCommandState(OmniPvdWriter& omniWriter) { EngineDriveTransmissionCommandState c; - c.CH = omniWriter->registerClass("EngineDriveTranmissionCommandState"); - c.gearAH = omniWriter->registerAttribute(c.CH, "targetGear", OmniPvdDataTypeEnum::eUINT32, 1); - c.clutchAH = omniWriter->registerAttribute(c.CH, "clutch", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("EngineDriveTransmissionCommandState"); + c.gearAH = omniWriter.registerAttribute(c.CH, "targetGear", OmniPvdDataType::eUINT32, 1); + c.clutchAH = omniWriter.registerAttribute(c.CH, "clutch", OmniPvdDataType::eFLOAT32, 1); return c; } void writeEngineDriveTransmissionCommandState (const PxVehicleEngineDriveTransmissionCommandState& transmission, - const OmniPvdObjectHandle oh, const EngineDriveTransmissionCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const EngineDriveTransmissionCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeUInt32Attribute(omniWriter, ch, oh, ah.gearAH, transmission.targetGear); writeFloatAttribute(omniWriter, ch, oh, ah.clutchAH, transmission.clutch); } -ClutchResponseParams registerClutchResponseParams(OmniPvdWriter* omniWriter) +ClutchResponseParams registerClutchResponseParams(OmniPvdWriter& omniWriter) { ClutchResponseParams c; - c.CH = omniWriter->registerClass("ClutchResponseParams"); - c.maxResponseAH = omniWriter->registerAttribute(c.CH, "MaxResponse", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("ClutchResponseParams"); + c.maxResponseAH = omniWriter.registerAttribute(c.CH, "MaxResponse", OmniPvdDataType::eFLOAT32, 1); return c; } -ClutchParams registerClutchParams(OmniPvdWriter* omniWriter) +ClutchParams registerClutchParams(OmniPvdWriter& omniWriter) { struct VehicleClutchAccuracyMode { @@ -1039,43 +1039,43 @@ ClutchParams registerClutchParams(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle bestPossibleAH; }; VehicleClutchAccuracyMode mode; - mode.CH = omniWriter->registerClass("ClutchAccuracyMode"); - mode.estimateAH = omniWriter->registerEnumValue(mode.CH, "estimate", PxVehicleClutchAccuracyMode::eESTIMATE); - mode.bestPossibleAH = omniWriter->registerEnumValue(mode.CH, "bestPossible", PxVehicleClutchAccuracyMode::eBEST_POSSIBLE); + mode.CH = omniWriter.registerClass("ClutchAccuracyMode"); + mode.estimateAH = omniWriter.registerEnumValue(mode.CH, "estimate", PxVehicleClutchAccuracyMode::eESTIMATE); + mode.bestPossibleAH = omniWriter.registerEnumValue(mode.CH, "bestPossible", PxVehicleClutchAccuracyMode::eBEST_POSSIBLE); ClutchParams v; - v.CH = omniWriter->registerClass("ClutchParams"); - v.accuracyAH = omniWriter->registerFlagsAttribute(v.CH, mode.CH, "accuracyMode"); - v.iterationsAH = omniWriter->registerAttribute(v.CH, "iterations", OmniPvdDataTypeEnum::eUINT32, 1); + v.CH = omniWriter.registerClass("ClutchParams"); + v.accuracyAH = omniWriter.registerFlagsAttribute(v.CH, "accuracyMode", mode.CH); + v.iterationsAH = omniWriter.registerAttribute(v.CH, "iterations", OmniPvdDataType::eUINT32, 1); return v; } void writeClutchParams (const PxVehicleClutchParams& clutchParams, - const OmniPvdObjectHandle oh, const ClutchParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const ClutchParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.accuracyAH, clutchParams.accuracyMode); writeUInt32Attribute(omniWriter, ch, oh, ah.iterationsAH, clutchParams.estimateIterations); } -EngineParams registerEngineParams(OmniPvdWriter* omniWriter) +EngineParams registerEngineParams(OmniPvdWriter& omniWriter) { EngineParams e; - e.CH = omniWriter->registerClass("EngineParams"); - e.torqueCurveAH = omniWriter->registerAttribute(e.CH, "torqueCurve", OmniPvdDataTypeEnum::eFLOAT32, PxVehicleEngineParams::eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES*2); - e.peakTorqueAH = omniWriter->registerAttribute(e.CH, "peakTorque", OmniPvdDataTypeEnum::eFLOAT32, 1); - e.moiAH = omniWriter->registerAttribute(e.CH, "moi", OmniPvdDataTypeEnum::eFLOAT32, 1); - e.idleOmegaAH = omniWriter->registerAttribute(e.CH, "idleOmega", OmniPvdDataTypeEnum::eFLOAT32, 1); - e.maxOmegaAH = omniWriter->registerAttribute(e.CH, "maxOmega", OmniPvdDataTypeEnum::eFLOAT32, 1); - e.dampingRateFullThrottleAH = omniWriter->registerAttribute(e.CH, "dampingRateFullThrottleAH", OmniPvdDataTypeEnum::eFLOAT32, 1); - e.dampingRateZeroThrottleClutchDisengagedAH = omniWriter->registerAttribute(e.CH, "dampingRateZeroThrottleClutchDisengaged", OmniPvdDataTypeEnum::eFLOAT32, 1); - e.dampingRateZeroThrottleClutchEngagedAH = omniWriter->registerAttribute(e.CH, "dampingRateZeroThrottleClutchEngaged", OmniPvdDataTypeEnum::eFLOAT32, 1); + e.CH = omniWriter.registerClass("EngineParams"); + e.torqueCurveAH = omniWriter.registerAttribute(e.CH, "torqueCurve", OmniPvdDataType::eFLOAT32, PxVehicleEngineParams::eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES*2); + e.peakTorqueAH = omniWriter.registerAttribute(e.CH, "peakTorque", OmniPvdDataType::eFLOAT32, 1); + e.moiAH = omniWriter.registerAttribute(e.CH, "moi", OmniPvdDataType::eFLOAT32, 1); + e.idleOmegaAH = omniWriter.registerAttribute(e.CH, "idleOmega", OmniPvdDataType::eFLOAT32, 1); + e.maxOmegaAH = omniWriter.registerAttribute(e.CH, "maxOmega", OmniPvdDataType::eFLOAT32, 1); + e.dampingRateFullThrottleAH = omniWriter.registerAttribute(e.CH, "dampingRateFullThrottleAH", OmniPvdDataType::eFLOAT32, 1); + e.dampingRateZeroThrottleClutchDisengagedAH = omniWriter.registerAttribute(e.CH, "dampingRateZeroThrottleClutchDisengaged", OmniPvdDataType::eFLOAT32, 1); + e.dampingRateZeroThrottleClutchEngagedAH = omniWriter.registerAttribute(e.CH, "dampingRateZeroThrottleClutchEngaged", OmniPvdDataType::eFLOAT32, 1); return e; } void writeEngineParams (const PxVehicleEngineParams& engineParams, - const OmniPvdObjectHandle oh, const EngineParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const EngineParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { float torqueCurve[PxVehicleEngineParams::eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES*2]; for(PxU32 i = 0; i < engineParams.torqueCurve.nbDataPairs; i++) @@ -1099,21 +1099,21 @@ void writeEngineParams writeFloatAttribute(omniWriter, ch, oh, ah.dampingRateZeroThrottleClutchEngagedAH, engineParams.dampingRateZeroThrottleClutchEngaged); } -GearboxParams registerGearboxParams(OmniPvdWriter* omniWriter) +GearboxParams registerGearboxParams(OmniPvdWriter& omniWriter) { GearboxParams g; - g.CH = omniWriter->registerClass("GearboxParams"); - g.ratiosAH = omniWriter->registerAttribute(g.CH, "ratios", OmniPvdDataTypeEnum::eFLOAT32, PxVehicleGearboxParams::eMAX_NB_GEARS); - g.nbRatiosAH = omniWriter->registerAttribute(g.CH, "nbRatios", OmniPvdDataTypeEnum::eUINT32, 1); - g.neutralGearAH = omniWriter->registerAttribute(g.CH, "neutralGear", OmniPvdDataTypeEnum::eUINT32, 1); - g.finalRatioAH = omniWriter->registerAttribute(g.CH, "finalRatio", OmniPvdDataTypeEnum::eFLOAT32, 1); - g.switchTimeAH = omniWriter->registerAttribute(g.CH, "switchTime", OmniPvdDataTypeEnum::eFLOAT32, 1); + g.CH = omniWriter.registerClass("GearboxParams"); + g.ratiosAH = omniWriter.registerAttribute(g.CH, "ratios", OmniPvdDataType::eFLOAT32, PxVehicleGearboxParams::eMAX_NB_GEARS); + g.nbRatiosAH = omniWriter.registerAttribute(g.CH, "nbRatios", OmniPvdDataType::eUINT32, 1); + g.neutralGearAH = omniWriter.registerAttribute(g.CH, "neutralGear", OmniPvdDataType::eUINT32, 1); + g.finalRatioAH = omniWriter.registerAttribute(g.CH, "finalRatio", OmniPvdDataType::eFLOAT32, 1); + g.switchTimeAH = omniWriter.registerAttribute(g.CH, "switchTime", OmniPvdDataType::eFLOAT32, 1); return g; } void writeGearboxParams (const PxVehicleGearboxParams& gearboxParams, - const OmniPvdObjectHandle oh, const GearboxParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const GearboxParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { float ratios[PxVehicleGearboxParams::eMAX_NB_GEARS]; PxMemCopy(ratios, gearboxParams.ratios, sizeof(float)*gearboxParams.nbRatios); @@ -1128,65 +1128,65 @@ void writeGearboxParams writeFloatAttribute(omniWriter, ch, oh, ah.switchTimeAH, gearboxParams.switchTime); } -AutoboxParams registerAutoboxParams(OmniPvdWriter* omniWriter) +AutoboxParams registerAutoboxParams(OmniPvdWriter& omniWriter) { AutoboxParams a; - a.CH = omniWriter->registerClass("AutoboxParams"); - a.upRatiosAH = omniWriter->registerAttribute(a.CH, "upRatios", OmniPvdDataTypeEnum::eFLOAT32, PxVehicleGearboxParams::eMAX_NB_GEARS); - a.downRatiosAH = omniWriter->registerAttribute(a.CH, "downRatios", OmniPvdDataTypeEnum::eFLOAT32, PxVehicleGearboxParams::eMAX_NB_GEARS); - a.latencyAH = omniWriter->registerAttribute(a.CH, "latency", OmniPvdDataTypeEnum::eFLOAT32, 1); + a.CH = omniWriter.registerClass("AutoboxParams"); + a.upRatiosAH = omniWriter.registerAttribute(a.CH, "upRatios", OmniPvdDataType::eFLOAT32, PxVehicleGearboxParams::eMAX_NB_GEARS); + a.downRatiosAH = omniWriter.registerAttribute(a.CH, "downRatios", OmniPvdDataType::eFLOAT32, PxVehicleGearboxParams::eMAX_NB_GEARS); + a.latencyAH = omniWriter.registerAttribute(a.CH, "latency", OmniPvdDataType::eFLOAT32, 1); return a; } void writeAutoboxParams (const PxVehicleAutoboxParams& autoboxParams, - const OmniPvdObjectHandle oh, const AutoboxParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const AutoboxParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatArrayAttribute(omniWriter, ch, oh, ah.upRatiosAH, autoboxParams.upRatios, PxVehicleGearboxParams::eMAX_NB_GEARS); writeFloatArrayAttribute(omniWriter, ch, oh, ah.downRatiosAH, autoboxParams.downRatios, PxVehicleGearboxParams::eMAX_NB_GEARS); writeFloatAttribute(omniWriter, ch, oh, ah.latencyAH, autoboxParams.latency); } -MultiWheelDiffParams registerMultiWheelDiffParams(const char* name, OmniPvdWriter* omniWriter) +MultiWheelDiffParams registerMultiWheelDiffParams(const char* name, OmniPvdWriter& omniWriter) { MultiWheelDiffParams m; - m.CH = omniWriter->registerClass(name); - m.torqueRatios0To3AH = omniWriter->registerAttribute(m.CH, "torqueRatios0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.torqueRatios4To7AH = omniWriter->registerAttribute(m.CH, "torqueRatios4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.torqueRatios8To11AH = omniWriter->registerAttribute(m.CH, "torqueRatios8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.torqueRatios12To15AH = omniWriter->registerAttribute(m.CH, "torqueRatios12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.torqueRatios16To19AH = omniWriter->registerAttribute(m.CH, "torqueRatios16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.aveWheelSpeedRatios0To3AH = omniWriter->registerAttribute(m.CH, "aveWheelSpeedRatios0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.aveWheelSpeedRatios4To7AH = omniWriter->registerAttribute(m.CH, "aveWheelSpeedRatios4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.aveWheelSpeedRatios8To11AH = omniWriter->registerAttribute(m.CH, "aveWheelSpeedRatios8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.aveWheelSpeedRatios12To15AH = omniWriter->registerAttribute(m.CH, "aveWheelSpeedRatios12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - m.aveWheelSpeedRatios16To19AH = omniWriter->registerAttribute(m.CH, "aveWheelSpeedRatios16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); + m.CH = omniWriter.registerClass(name); + m.torqueRatios0To3AH = omniWriter.registerAttribute(m.CH, "torqueRatios0To3", OmniPvdDataType::eFLOAT32, 4); + m.torqueRatios4To7AH = omniWriter.registerAttribute(m.CH, "torqueRatios4To7", OmniPvdDataType::eFLOAT32, 4); + m.torqueRatios8To11AH = omniWriter.registerAttribute(m.CH, "torqueRatios8To11", OmniPvdDataType::eFLOAT32, 4); + m.torqueRatios12To15AH = omniWriter.registerAttribute(m.CH, "torqueRatios12To15", OmniPvdDataType::eFLOAT32, 4); + m.torqueRatios16To19AH = omniWriter.registerAttribute(m.CH, "torqueRatios16To19", OmniPvdDataType::eFLOAT32, 4); + m.aveWheelSpeedRatios0To3AH = omniWriter.registerAttribute(m.CH, "aveWheelSpeedRatios0To3", OmniPvdDataType::eFLOAT32, 4); + m.aveWheelSpeedRatios4To7AH = omniWriter.registerAttribute(m.CH, "aveWheelSpeedRatios4To7", OmniPvdDataType::eFLOAT32, 4); + m.aveWheelSpeedRatios8To11AH = omniWriter.registerAttribute(m.CH, "aveWheelSpeedRatios8To11", OmniPvdDataType::eFLOAT32, 4); + m.aveWheelSpeedRatios12To15AH = omniWriter.registerAttribute(m.CH, "aveWheelSpeedRatios12To15", OmniPvdDataType::eFLOAT32, 4); + m.aveWheelSpeedRatios16To19AH = omniWriter.registerAttribute(m.CH, "aveWheelSpeedRatios16To19", OmniPvdDataType::eFLOAT32, 4); return m; } -MultiWheelDiffParams registerMultiWheelDiffParams(OmniPvdWriter* omniWriter) +MultiWheelDiffParams registerMultiWheelDiffParams(OmniPvdWriter& omniWriter) { return registerMultiWheelDiffParams("MultiWheelDiffParams", omniWriter); } -FourWheelDiffParams registerFourWheelDiffParams(OmniPvdWriter* omniWriter) +FourWheelDiffParams registerFourWheelDiffParams(OmniPvdWriter& omniWriter) { FourWheelDiffParams m; static_cast(m) = registerMultiWheelDiffParams("FourWheelDiffParams", omniWriter); - m.frontBiasAH = omniWriter->registerAttribute(m.CH, "frontBias", OmniPvdDataTypeEnum::eFLOAT32, 1); - m.frontTargetAH = omniWriter->registerAttribute(m.CH, "frontTarget", OmniPvdDataTypeEnum::eFLOAT32, 1); - m.rearBiasAH = omniWriter->registerAttribute(m.CH, "rearBias", OmniPvdDataTypeEnum::eFLOAT32, 1); - m.rearTargetAH = omniWriter->registerAttribute(m.CH, "rearTarget", OmniPvdDataTypeEnum::eFLOAT32, 1); - m.centreBiasAH = omniWriter->registerAttribute(m.CH, "centerBias", OmniPvdDataTypeEnum::eFLOAT32, 1); - m.centreTargetAH = omniWriter->registerAttribute(m.CH, "centerTarget", OmniPvdDataTypeEnum::eFLOAT32, 1); - m.frontWheelsAH = omniWriter->registerAttribute(m.CH, "frontWheels", OmniPvdDataTypeEnum::eUINT32, 2); - m.rearWheelsAH = omniWriter->registerAttribute(m.CH, "rearWheels", OmniPvdDataTypeEnum::eUINT32, 2); + m.frontBiasAH = omniWriter.registerAttribute(m.CH, "frontBias", OmniPvdDataType::eFLOAT32, 1); + m.frontTargetAH = omniWriter.registerAttribute(m.CH, "frontTarget", OmniPvdDataType::eFLOAT32, 1); + m.rearBiasAH = omniWriter.registerAttribute(m.CH, "rearBias", OmniPvdDataType::eFLOAT32, 1); + m.rearTargetAH = omniWriter.registerAttribute(m.CH, "rearTarget", OmniPvdDataType::eFLOAT32, 1); + m.centreBiasAH = omniWriter.registerAttribute(m.CH, "centerBias", OmniPvdDataType::eFLOAT32, 1); + m.centreTargetAH = omniWriter.registerAttribute(m.CH, "centerTarget", OmniPvdDataType::eFLOAT32, 1); + m.frontWheelsAH = omniWriter.registerAttribute(m.CH, "frontWheels", OmniPvdDataType::eUINT32, 2); + m.rearWheelsAH = omniWriter.registerAttribute(m.CH, "rearWheels", OmniPvdDataType::eUINT32, 2); return m; } void writeMultiWheelDiffParams (const PxVehicleMultiWheelDriveDifferentialParams& diffParams, - const OmniPvdObjectHandle oh, const MultiWheelDiffParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const MultiWheelDiffParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatArrayAttribute(omniWriter, ch, oh, ah.aveWheelSpeedRatios0To3AH, diffParams.aveWheelSpeedRatios + 0, 4); writeFloatArrayAttribute(omniWriter, ch, oh, ah.aveWheelSpeedRatios4To7AH, diffParams.aveWheelSpeedRatios + 4, 4); @@ -1203,7 +1203,7 @@ void writeMultiWheelDiffParams void writeFourWheelDiffParams (const PxVehicleFourWheelDriveDifferentialParams& diffParams, - const OmniPvdObjectHandle oh, const FourWheelDiffParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const FourWheelDiffParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeMultiWheelDiffParams(diffParams, oh, ah, omniWriter, ch); writeFloatAttribute(omniWriter, ch, oh, ah.frontBiasAH, diffParams.frontBias); @@ -1216,73 +1216,73 @@ void writeFourWheelDiffParams writeUInt32ArrayAttribute(omniWriter, ch, oh, ah.rearWheelsAH, diffParams.rearWheelIds, 2); } -ClutchResponseState registerClutchResponseState(OmniPvdWriter* omniWriter) +ClutchResponseState registerClutchResponseState(OmniPvdWriter& omniWriter) { ClutchResponseState c; - c.CH = omniWriter->registerClass("ClutchResponseState"); - c.normalisedResponseAH = omniWriter->registerAttribute(c.CH, "normalisedResponse", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.responseAH = omniWriter->registerAttribute(c.CH, "response", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("ClutchResponseState"); + c.normalisedResponseAH = omniWriter.registerAttribute(c.CH, "normalisedResponse", OmniPvdDataType::eFLOAT32, 1); + c.responseAH = omniWriter.registerAttribute(c.CH, "response", OmniPvdDataType::eFLOAT32, 1); return c; } void writeClutchResponseState (const PxVehicleClutchCommandResponseState& clutchResponseState, - const OmniPvdObjectHandle oh, const ClutchResponseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const ClutchResponseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.normalisedResponseAH, clutchResponseState.normalisedCommandResponse); writeFloatAttribute(omniWriter, ch, oh, ah.responseAH, clutchResponseState.commandResponse); } -ThrottleResponseState registerThrottleResponseState(OmniPvdWriter* omniWriter) +ThrottleResponseState registerThrottleResponseState(OmniPvdWriter& omniWriter) { ThrottleResponseState t; - t.CH = omniWriter->registerClass("ThrottleResponseState"); - t.responseAH = omniWriter->registerAttribute(t.CH, "response", OmniPvdDataTypeEnum::eFLOAT32, 1); + t.CH = omniWriter.registerClass("ThrottleResponseState"); + t.responseAH = omniWriter.registerAttribute(t.CH, "response", OmniPvdDataType::eFLOAT32, 1); return t; } void writeThrottleResponseState (const PxVehicleEngineDriveThrottleCommandResponseState& throttleResponseState, - const OmniPvdObjectHandle oh, const ThrottleResponseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const ThrottleResponseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.responseAH, throttleResponseState.commandResponse); } -EngineState registerEngineState(OmniPvdWriter* omniWriter) +EngineState registerEngineState(OmniPvdWriter& omniWriter) { EngineState e; - e.CH = omniWriter->registerClass("EngineState"); - e.rotationSpeedAH = omniWriter->registerAttribute(e.CH, "rotationSpeed", OmniPvdDataTypeEnum::eFLOAT32, 1); + e.CH = omniWriter.registerClass("EngineState"); + e.rotationSpeedAH = omniWriter.registerAttribute(e.CH, "rotationSpeed", OmniPvdDataType::eFLOAT32, 1); return e; } void writeEngineState (const PxVehicleEngineState& engineState, - const OmniPvdObjectHandle oh, const EngineState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const EngineState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.rotationSpeedAH, engineState.rotationSpeed); } -GearboxState registerGearboxState(OmniPvdWriter* omniWriter) +GearboxState registerGearboxState(OmniPvdWriter& omniWriter) { GearboxState g; - g.CH = omniWriter->registerClass("GearboxState"); - g.currentGearAH = omniWriter->registerAttribute(g.CH, "currentGear", OmniPvdDataTypeEnum::eUINT32, 1); - g.targetGearAH = omniWriter->registerAttribute(g.CH, "targetGear", OmniPvdDataTypeEnum::eUINT32, 1); - g.switchTimeAH = omniWriter->registerAttribute(g.CH, "switchTime", OmniPvdDataTypeEnum::eFLOAT32, 1); + g.CH = omniWriter.registerClass("GearboxState"); + g.currentGearAH = omniWriter.registerAttribute(g.CH, "currentGear", OmniPvdDataType::eUINT32, 1); + g.targetGearAH = omniWriter.registerAttribute(g.CH, "targetGear", OmniPvdDataType::eUINT32, 1); + g.switchTimeAH = omniWriter.registerAttribute(g.CH, "switchTime", OmniPvdDataType::eFLOAT32, 1); return g; } void writeGearboxState (const PxVehicleGearboxState& gearboxState, - const OmniPvdObjectHandle oh, const GearboxState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const GearboxState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeUInt32Attribute(omniWriter, ch, oh, ah.currentGearAH, gearboxState.currentGear); writeUInt32Attribute(omniWriter, ch, oh, ah.targetGearAH, gearboxState.targetGear); writeFloatAttribute(omniWriter, ch, oh, ah.switchTimeAH, gearboxState.gearSwitchTime); } -AutoboxState registerAutoboxState(OmniPvdWriter* omniWriter) +AutoboxState registerAutoboxState(OmniPvdWriter& omniWriter) { struct BoolAsEnum { @@ -1291,45 +1291,45 @@ AutoboxState registerAutoboxState(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle trueAH; }; BoolAsEnum boolAsEnum; - boolAsEnum.CH = omniWriter->registerClass("AutoboxStateBool"); - boolAsEnum.falseAH = omniWriter->registerEnumValue(boolAsEnum.CH, "False", 0); - boolAsEnum.trueAH = omniWriter->registerEnumValue(boolAsEnum.CH, "True", 1); + boolAsEnum.CH = omniWriter.registerClass("AutoboxStateBool"); + boolAsEnum.falseAH = omniWriter.registerEnumValue(boolAsEnum.CH, "False", 0); + boolAsEnum.trueAH = omniWriter.registerEnumValue(boolAsEnum.CH, "True", 1); AutoboxState a; - a.CH = omniWriter->registerClass("GearboxState"); - a.timeSinceLastShiftAH = omniWriter->registerAttribute(a.CH, "timeSinceLastShift", OmniPvdDataTypeEnum::eFLOAT32, 1); - a.activeAutoboxGearShiftAH = omniWriter->registerFlagsAttribute(a.CH, boolAsEnum.CH, "activeAutoboxShift"); + a.CH = omniWriter.registerClass("AutoboxState"); + a.timeSinceLastShiftAH = omniWriter.registerAttribute(a.CH, "timeSinceLastShift", OmniPvdDataType::eFLOAT32, 1); + a.activeAutoboxGearShiftAH = omniWriter.registerFlagsAttribute(a.CH, "activeAutoboxShift", boolAsEnum.CH); return a; } void writeAutoboxState (const PxVehicleAutoboxState& autoboxState, - const OmniPvdObjectHandle oh, const AutoboxState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const AutoboxState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.timeSinceLastShiftAH, autoboxState.timeSinceLastShift); writeFlagAttribute(omniWriter, ch, oh, ah.activeAutoboxGearShiftAH, autoboxState.activeAutoboxGearShift ? 1: 0); } -DiffState registerDiffState(OmniPvdWriter* omniWriter) +DiffState registerDiffState(OmniPvdWriter& omniWriter) { DiffState d; - d.CH = omniWriter->registerClass("DifferentialState"); - d.torqueRatios0To3AH = omniWriter->registerAttribute(d.CH, "torqueRatios0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.torqueRatios4To7AH = omniWriter->registerAttribute(d.CH, "torqueRatios4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.torqueRatios8To11AH = omniWriter->registerAttribute(d.CH, "torqueRatios8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.torqueRatios12To15AH = omniWriter->registerAttribute(d.CH, "torqueRatios12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.torqueRatios16To19AH = omniWriter->registerAttribute(d.CH, "torqueRatios16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.aveWheelSpeedRatios0To3AH = omniWriter->registerAttribute(d.CH, "aveWheelSpeedRatios0To3", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.aveWheelSpeedRatios4To7AH = omniWriter->registerAttribute(d.CH, "aveWheelSpeedRatios4To7", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.aveWheelSpeedRatios8To11AH = omniWriter->registerAttribute(d.CH, "aveWheelSpeedRatios8To11", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.aveWheelSpeedRatios12To15AH = omniWriter->registerAttribute(d.CH, "aveWheelSpeedRatios12To15", OmniPvdDataTypeEnum::eFLOAT32, 4); - d.aveWheelSpeedRatios16To19AH = omniWriter->registerAttribute(d.CH, "aveWheelSpeedRatios16To19", OmniPvdDataTypeEnum::eFLOAT32, 4); + d.CH = omniWriter.registerClass("DifferentialState"); + d.torqueRatios0To3AH = omniWriter.registerAttribute(d.CH, "torqueRatios0To3", OmniPvdDataType::eFLOAT32, 4); + d.torqueRatios4To7AH = omniWriter.registerAttribute(d.CH, "torqueRatios4To7", OmniPvdDataType::eFLOAT32, 4); + d.torqueRatios8To11AH = omniWriter.registerAttribute(d.CH, "torqueRatios8To11", OmniPvdDataType::eFLOAT32, 4); + d.torqueRatios12To15AH = omniWriter.registerAttribute(d.CH, "torqueRatios12To15", OmniPvdDataType::eFLOAT32, 4); + d.torqueRatios16To19AH = omniWriter.registerAttribute(d.CH, "torqueRatios16To19", OmniPvdDataType::eFLOAT32, 4); + d.aveWheelSpeedRatios0To3AH = omniWriter.registerAttribute(d.CH, "aveWheelSpeedRatios0To3", OmniPvdDataType::eFLOAT32, 4); + d.aveWheelSpeedRatios4To7AH = omniWriter.registerAttribute(d.CH, "aveWheelSpeedRatios4To7", OmniPvdDataType::eFLOAT32, 4); + d.aveWheelSpeedRatios8To11AH = omniWriter.registerAttribute(d.CH, "aveWheelSpeedRatios8To11", OmniPvdDataType::eFLOAT32, 4); + d.aveWheelSpeedRatios12To15AH = omniWriter.registerAttribute(d.CH, "aveWheelSpeedRatios12To15", OmniPvdDataType::eFLOAT32, 4); + d.aveWheelSpeedRatios16To19AH = omniWriter.registerAttribute(d.CH, "aveWheelSpeedRatios16To19", OmniPvdDataType::eFLOAT32, 4); return d; } void writeDiffState (const PxVehicleDifferentialState& diffState, - const OmniPvdObjectHandle oh, const DiffState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const DiffState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatArrayAttribute(omniWriter, ch, oh, ah.aveWheelSpeedRatios0To3AH, diffState.aveWheelSpeedContributionAllWheels + 0, 4); writeFloatArrayAttribute(omniWriter, ch, oh, ah.aveWheelSpeedRatios4To7AH, diffState.aveWheelSpeedContributionAllWheels + 4, 4); @@ -1344,41 +1344,41 @@ void writeDiffState writeFloatArrayAttribute(omniWriter, ch, oh, ah.torqueRatios16To19AH, diffState.torqueRatiosAllWheels + 16, 4); } -ClutchSlipState registerClutchSlipState(OmniPvdWriter* omniWriter) +ClutchSlipState registerClutchSlipState(OmniPvdWriter& omniWriter) { ClutchSlipState c; - c.CH = omniWriter->registerClass("ClutchSlipState"); - c.slipAH = omniWriter->registerAttribute(c.CH, "clutchSlip", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("ClutchSlipState"); + c.slipAH = omniWriter.registerAttribute(c.CH, "clutchSlip", OmniPvdDataType::eFLOAT32, 1); return c; } void writeClutchSlipState (const PxVehicleClutchSlipState& clutchSlipState, - const OmniPvdObjectHandle oh, const ClutchSlipState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const ClutchSlipState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.slipAH, clutchSlipState.clutchSlip); } -EngineDrivetrain registerEngineDrivetrain(OmniPvdWriter* omniWriter) +EngineDrivetrain registerEngineDrivetrain(OmniPvdWriter& omniWriter) { EngineDrivetrain e; - e.CH = omniWriter->registerClass("EngineDrivetrain"); - e.commandStateAH = omniWriter->registerAttribute(e.CH, "engineDriveCommandState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.transmissionCommandStateAH = omniWriter->registerAttribute(e.CH, "engineDriveTransmissionCommandState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.clutchResponseParamsAH = omniWriter->registerAttribute(e.CH, "clutchResponseParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.clutchParamsAH = omniWriter->registerAttribute(e.CH, "elutchParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.engineParamsAH = omniWriter->registerAttribute(e.CH, "engineParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.gearboxParamsAH = omniWriter->registerAttribute(e.CH, "gearboxParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.autoboxParamsAH = omniWriter->registerAttribute(e.CH, "autoboxParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.multiWheelDiffParamsAH = omniWriter->registerAttribute(e.CH, "multiWheelDiffParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.fourWheelDiffParamsAH = omniWriter->registerAttribute(e.CH, "fourWheelDiffParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.clutchResponseStateAH= omniWriter->registerAttribute(e.CH, "clutchResponseState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.throttleResponseStateAH= omniWriter->registerAttribute(e.CH, "throttleResponseState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.engineStateAH = omniWriter->registerAttribute(e.CH, "engineState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.gearboxStateAH = omniWriter->registerAttribute(e.CH, "gearboxState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.autoboxStateAH = omniWriter->registerAttribute(e.CH, "autoboxState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.diffStateAH = omniWriter->registerAttribute(e.CH, "diffState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - e.clutchSlipStateAH = omniWriter->registerAttribute(e.CH, "clutchSlipState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + e.CH = omniWriter.registerClass("EngineDrivetrain"); + e.commandStateAH = omniWriter.registerAttribute(e.CH, "engineDriveCommandState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.transmissionCommandStateAH = omniWriter.registerAttribute(e.CH, "engineDriveTransmissionCommandState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.clutchResponseParamsAH = omniWriter.registerAttribute(e.CH, "clutchResponseParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.clutchParamsAH = omniWriter.registerAttribute(e.CH, "clutchParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.engineParamsAH = omniWriter.registerAttribute(e.CH, "engineParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.gearboxParamsAH = omniWriter.registerAttribute(e.CH, "gearboxParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.autoboxParamsAH = omniWriter.registerAttribute(e.CH, "autoboxParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.multiWheelDiffParamsAH = omniWriter.registerAttribute(e.CH, "multiWheelDiffParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.fourWheelDiffParamsAH = omniWriter.registerAttribute(e.CH, "fourWheelDiffParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.clutchResponseStateAH= omniWriter.registerAttribute(e.CH, "clutchResponseState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.throttleResponseStateAH= omniWriter.registerAttribute(e.CH, "throttleResponseState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.engineStateAH = omniWriter.registerAttribute(e.CH, "engineState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.gearboxStateAH = omniWriter.registerAttribute(e.CH, "gearboxState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.autoboxStateAH = omniWriter.registerAttribute(e.CH, "autoboxState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.diffStateAH = omniWriter.registerAttribute(e.CH, "diffState", OmniPvdDataType::eOBJECT_HANDLE, 1); + e.clutchSlipStateAH = omniWriter.registerAttribute(e.CH, "clutchSlipState", OmniPvdDataType::eOBJECT_HANDLE, 1); return e; } @@ -1387,7 +1387,7 @@ EngineDrivetrain registerEngineDrivetrain(OmniPvdWriter* omniWriter) //PHYSX WHEEL ATTACHMENT //////////////////////////// -PhysXSuspensionLimitConstraintParams registerSuspLimitConstraintParams(OmniPvdWriter* omniWriter) +PhysXSuspensionLimitConstraintParams registerSuspLimitConstraintParams(OmniPvdWriter& omniWriter) { struct DirSpecifier { @@ -1397,59 +1397,59 @@ PhysXSuspensionLimitConstraintParams registerSuspLimitConstraintParams(OmniPvdWr OmniPvdAttributeHandle noneAH; }; DirSpecifier s; - s.CH = omniWriter->registerClass("DirectionSpecifier"); - s.suspensionAH = omniWriter->registerEnumValue(s.CH, "suspensionDir", + s.CH = omniWriter.registerClass("DirectionSpecifier"); + s.suspensionAH = omniWriter.registerEnumValue(s.CH, "suspensionDir", PxVehiclePhysXSuspensionLimitConstraintParams::DirectionSpecifier::eSUSPENSION); - s.geomNormalAH = omniWriter->registerEnumValue(s.CH, "geomNormalDir", + s.geomNormalAH = omniWriter.registerEnumValue(s.CH, "geomNormalDir", PxVehiclePhysXSuspensionLimitConstraintParams::DirectionSpecifier::eROAD_GEOMETRY_NORMAL); - s.noneAH = omniWriter->registerEnumValue(s.CH, "geomNormalDir", + s.noneAH = omniWriter.registerEnumValue(s.CH, "geomNormalDir", PxVehiclePhysXSuspensionLimitConstraintParams::DirectionSpecifier::eNONE); PhysXSuspensionLimitConstraintParams c; - c.CH = omniWriter->registerClass("PhysXSuspLimitConstraintParams"); - c.restitutionAH = omniWriter->registerAttribute(c.CH, "restitution", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.directionForSuspensionLimitConstraintAH = omniWriter->registerFlagsAttribute(c.CH, s.CH, "directionMode"); + c.CH = omniWriter.registerClass("PhysXSuspLimitConstraintParams"); + c.restitutionAH = omniWriter.registerAttribute(c.CH, "restitution", OmniPvdDataType::eFLOAT32, 1); + c.directionForSuspensionLimitConstraintAH = omniWriter.registerFlagsAttribute(c.CH, "directionMode", s.CH); return c; } void writePhysXSuspLimitConstraintParams (const PxVehiclePhysXSuspensionLimitConstraintParams& params, - const OmniPvdObjectHandle oh, const PhysXSuspensionLimitConstraintParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const PhysXSuspensionLimitConstraintParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.directionForSuspensionLimitConstraintAH, params.directionForSuspensionLimitConstraint); writeFloatAttribute(omniWriter, ch, oh, ah.restitutionAH, params.restitution); } -PhysXWheelShape registerPhysXWheelShape(OmniPvdWriter* omniWriter) +PhysXWheelShape registerPhysXWheelShape(OmniPvdWriter& omniWriter) { PhysXWheelShape w; - w.CH = omniWriter->registerClass("PhysXWheelShape"); - w.shapePtrAH = omniWriter->registerAttribute(w.CH, "pxShapePtr", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + w.CH = omniWriter.registerClass("PhysXWheelShape"); + w.shapePtrAH = omniWriter.registerAttribute(w.CH, "pxShapePtr", OmniPvdDataType::eOBJECT_HANDLE, 1); return w; } void writePhysXWheelShape (const PxShape* wheelShape, - const OmniPvdObjectHandle oh, const PhysXWheelShape& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const PhysXWheelShape& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writePtrAttribute(omniWriter, ch, oh, ah.shapePtrAH, wheelShape); } -PhysXRoadGeomState registerPhysXRoadGeomState(OmniPvdWriter* omniWriter) +PhysXRoadGeomState registerPhysXRoadGeomState(OmniPvdWriter& omniWriter) { PhysXRoadGeomState g; - g.CH = omniWriter->registerClass("PhysXRoadGeomState"); - g.hitPositionAH = omniWriter->registerAttribute(g.CH, "hitPosition", OmniPvdDataTypeEnum::eFLOAT32, 3); - g.hitActorPtrAH = omniWriter->registerAttribute(g.CH, "PxActor", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - g.hitShapePtrAH = omniWriter->registerAttribute(g.CH, "PxShape", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - g.hitMaterialPtrAH = omniWriter->registerAttribute(g.CH, "PxMaterial", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + g.CH = omniWriter.registerClass("PhysXRoadGeomState"); + g.hitPositionAH = omniWriter.registerAttribute(g.CH, "hitPosition", OmniPvdDataType::eFLOAT32, 3); + g.hitActorPtrAH = omniWriter.registerAttribute(g.CH, "PxActor", OmniPvdDataType::eOBJECT_HANDLE, 1); + g.hitShapePtrAH = omniWriter.registerAttribute(g.CH, "PxShape", OmniPvdDataType::eOBJECT_HANDLE, 1); + g.hitMaterialPtrAH = omniWriter.registerAttribute(g.CH, "PxMaterial", OmniPvdDataType::eOBJECT_HANDLE, 1); return g; } void writePhysXRoadGeomState (const PxVehiclePhysXRoadGeometryQueryState& roadGeomState, -const OmniPvdObjectHandle oh, const PhysXRoadGeomState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) +const OmniPvdObjectHandle oh, const PhysXRoadGeomState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeVec3Attribute(omniWriter, ch, oh, ah.hitPositionAH, roadGeomState.hitPosition); writePtrAttribute(omniWriter, ch, oh, ah.hitActorPtrAH, roadGeomState.actor); @@ -1457,7 +1457,7 @@ const OmniPvdObjectHandle oh, const PhysXRoadGeomState& ah, OmniPvdWriter* omniW writePtrAttribute(omniWriter, ch, oh, ah.hitShapePtrAH, roadGeomState.shape); } -PhysXConstraintState registerPhysXConstraintState(OmniPvdWriter* omniWriter) +PhysXConstraintState registerPhysXConstraintState(OmniPvdWriter& omniWriter) { struct BoolAsEnum { @@ -1466,31 +1466,31 @@ PhysXConstraintState registerPhysXConstraintState(OmniPvdWriter* omniWriter) OmniPvdAttributeHandle trueAH; }; BoolAsEnum boolAsEnum; - boolAsEnum.CH = omniWriter->registerClass("PhysXConstraintStateBool"); - boolAsEnum.falseAH = omniWriter->registerEnumValue(boolAsEnum.CH, "False", 0); - boolAsEnum.trueAH = omniWriter->registerEnumValue(boolAsEnum.CH, "True", 1); + boolAsEnum.CH = omniWriter.registerClass("PhysXConstraintStateBool"); + boolAsEnum.falseAH = omniWriter.registerEnumValue(boolAsEnum.CH, "False", 0); + boolAsEnum.trueAH = omniWriter.registerEnumValue(boolAsEnum.CH, "True", 1); PhysXConstraintState c; - c.CH = omniWriter->registerClass("PhysXConstraintState"); - c.tireLongActiveStatusAH = omniWriter->registerFlagsAttribute(c.CH, boolAsEnum.CH, "tireLongitudinalActiveStatus"); - c.tireLongLinearAH = omniWriter->registerAttribute(c.CH, "tireLongitudinalLinear", OmniPvdDataTypeEnum::eFLOAT32, 3); - c.tireLongAngularAH = omniWriter->registerAttribute(c.CH, "tireLongitudinalAngular", OmniPvdDataTypeEnum::eFLOAT32, 3); - c.tireLongDampingAH = omniWriter->registerAttribute(c.CH, "tireLongitudinalDamping", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.tireLatActiveStatusAH = omniWriter->registerFlagsAttribute(c.CH, boolAsEnum.CH, "tireLateralActiveStatus"); - c.tireLatLinearAH = omniWriter->registerAttribute(c.CH, "tireLateralLinear", OmniPvdDataTypeEnum::eFLOAT32, 3); - c.tireLatAngularAH = omniWriter->registerAttribute(c.CH, "tireLateralAngular", OmniPvdDataTypeEnum::eFLOAT32, 3); - c.tireLatDampingAH = omniWriter->registerAttribute(c.CH, "tireLateralDamping", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.suspActiveStatusAH = omniWriter->registerFlagsAttribute(c.CH, boolAsEnum.CH, "suspActiveStatus"); - c.suspLinearAH = omniWriter->registerAttribute(c.CH, "suspLinear", OmniPvdDataTypeEnum::eFLOAT32, 3); - c.suspAngularAH = omniWriter->registerAttribute(c.CH, "suspAngular", OmniPvdDataTypeEnum::eFLOAT32, 3); - c.suspRestitutionAH = omniWriter->registerAttribute(c.CH, "suspRestitution", OmniPvdDataTypeEnum::eFLOAT32, 1); - c.suspGeometricErrorAH = omniWriter->registerAttribute(c.CH, "suspGeometricError", OmniPvdDataTypeEnum::eFLOAT32, 1); + c.CH = omniWriter.registerClass("PhysXConstraintState"); + c.tireLongActiveStatusAH = omniWriter.registerFlagsAttribute(c.CH, "tireLongitudinalActiveStatus", boolAsEnum.CH); + c.tireLongLinearAH = omniWriter.registerAttribute(c.CH, "tireLongitudinalLinear", OmniPvdDataType::eFLOAT32, 3); + c.tireLongAngularAH = omniWriter.registerAttribute(c.CH, "tireLongitudinalAngular", OmniPvdDataType::eFLOAT32, 3); + c.tireLongDampingAH = omniWriter.registerAttribute(c.CH, "tireLongitudinalDamping", OmniPvdDataType::eFLOAT32, 1); + c.tireLatActiveStatusAH = omniWriter.registerFlagsAttribute(c.CH, "tireLateralActiveStatus", boolAsEnum.CH); + c.tireLatLinearAH = omniWriter.registerAttribute(c.CH, "tireLateralLinear", OmniPvdDataType::eFLOAT32, 3); + c.tireLatAngularAH = omniWriter.registerAttribute(c.CH, "tireLateralAngular", OmniPvdDataType::eFLOAT32, 3); + c.tireLatDampingAH = omniWriter.registerAttribute(c.CH, "tireLateralDamping", OmniPvdDataType::eFLOAT32, 1); + c.suspActiveStatusAH = omniWriter.registerFlagsAttribute(c.CH, "suspActiveStatus", boolAsEnum.CH); + c.suspLinearAH = omniWriter.registerAttribute(c.CH, "suspLinear", OmniPvdDataType::eFLOAT32, 3); + c.suspAngularAH = omniWriter.registerAttribute(c.CH, "suspAngular", OmniPvdDataType::eFLOAT32, 3); + c.suspRestitutionAH = omniWriter.registerAttribute(c.CH, "suspRestitution", OmniPvdDataType::eFLOAT32, 1); + c.suspGeometricErrorAH = omniWriter.registerAttribute(c.CH, "suspGeometricError", OmniPvdDataType::eFLOAT32, 1); return c; } void writePhysXConstraintState (const PxVehiclePhysXConstraintState& roadGeomState, - const OmniPvdObjectHandle oh, const PhysXConstraintState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const PhysXConstraintState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFlagAttribute(omniWriter, ch, oh, ah.suspActiveStatusAH, roadGeomState.suspActiveStatus ? 1 : 0); writeVec3Attribute(omniWriter, ch, oh, ah.suspLinearAH, roadGeomState.suspLinear); @@ -1509,32 +1509,32 @@ void writePhysXConstraintState writeFloatAttribute(omniWriter, ch, oh, ah.tireLatDampingAH, roadGeomState.tireDamping[PxVehicleTireDirectionModes::eLATERAL]); } -PhysXMaterialFriction registerPhysXMaterialFriction(OmniPvdWriter* omniWriter) +PhysXMaterialFriction registerPhysXMaterialFriction(OmniPvdWriter& omniWriter) { PhysXMaterialFriction f; - f.CH = omniWriter->registerClass("PhysXMaterialFriction"); - f.frictionAH = omniWriter->registerAttribute(f.CH, "friction", OmniPvdDataTypeEnum::eFLOAT32, 1); - f.materialPtrAH = omniWriter->registerAttribute(f.CH, "material", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + f.CH = omniWriter.registerClass("PhysXMaterialFriction"); + f.frictionAH = omniWriter.registerAttribute(f.CH, "friction", OmniPvdDataType::eFLOAT32, 1); + f.materialPtrAH = omniWriter.registerAttribute(f.CH, "material", OmniPvdDataType::eOBJECT_HANDLE, 1); return f; } void writePhysXMaterialFriction (const PxVehiclePhysXMaterialFriction& materialFriction, - const OmniPvdObjectHandle oh, const PhysXMaterialFriction& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const PhysXMaterialFriction& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writeFloatAttribute(omniWriter, ch, oh, ah.frictionAH, materialFriction.friction); writePtrAttribute(omniWriter, ch, oh, ah.materialPtrAH, materialFriction.material); } -PhysXWheelAttachment registerPhysXWheelAttachment(OmniPvdWriter* omniWriter) +PhysXWheelAttachment registerPhysXWheelAttachment(OmniPvdWriter& omniWriter) { PhysXWheelAttachment w; - w.CH = omniWriter->registerClass("PhysXWheelAttachment"); - w.physxConstraintParamsAH = omniWriter->registerAttribute(w.CH, "physxConstraintParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.physxConstraintStateAH = omniWriter->registerAttribute(w.CH, "physxConstraintState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.physxWeelShapeAH = omniWriter->registerAttribute(w.CH, "physxWheelShape", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.physxRoadGeometryStateAH = omniWriter->registerAttribute(w.CH, "physxRoadGeomState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - w.physxMaterialFrictionSetAH = omniWriter->registerSetAttribute(w.CH, "physXMaterialFrictions", OmniPvdDataTypeEnum::eOBJECT_HANDLE); + w.CH = omniWriter.registerClass("PhysXWheelAttachment"); + w.physxConstraintParamsAH = omniWriter.registerAttribute(w.CH, "physxConstraintParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.physxConstraintStateAH = omniWriter.registerAttribute(w.CH, "physxConstraintState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.physxWeelShapeAH = omniWriter.registerAttribute(w.CH, "physxWheelShape", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.physxRoadGeometryStateAH = omniWriter.registerAttribute(w.CH, "physxRoadGeomState", OmniPvdDataType::eOBJECT_HANDLE, 1); + w.physxMaterialFrictionSetAH = omniWriter.registerUniqueListAttribute(w.CH, "physXMaterialFrictions", OmniPvdDataType::eOBJECT_HANDLE); return w; } @@ -1542,22 +1542,22 @@ PhysXWheelAttachment registerPhysXWheelAttachment(OmniPvdWriter* omniWriter) //PHYSX RIGID ACTOR ////////////////////////// -PhysXRigidActor registerPhysXRigidActor(OmniPvdWriter* omniWriter) +PhysXRigidActor registerPhysXRigidActor(OmniPvdWriter& omniWriter) { PhysXRigidActor a; - a.CH = omniWriter->registerClass("PhysXRigidActor"); - a.rigidActorAH = omniWriter->registerAttribute(a.CH, "rigidActor", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + a.CH = omniWriter.registerClass("PhysXRigidActor"); + a.rigidActorAH = omniWriter.registerAttribute(a.CH, "rigidActor", OmniPvdDataType::eOBJECT_HANDLE, 1); return a; } void writePhysXRigidActor (const PxRigidActor* actor, - const OmniPvdObjectHandle oh, const PhysXRigidActor& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) + const OmniPvdObjectHandle oh, const PhysXRigidActor& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { writePtrAttribute(omniWriter, ch, oh, ah.rigidActorAH, actor); } -PhysXRoadGeometryQueryParams registerPhysXRoadGeometryQueryParams(OmniPvdWriter* omniWriter) +PhysXRoadGeometryQueryParams registerPhysXRoadGeometryQueryParams(OmniPvdWriter& omniWriter) { struct Type { @@ -1567,22 +1567,22 @@ PhysXRoadGeometryQueryParams registerPhysXRoadGeometryQueryParams(OmniPvdWriter* OmniPvdAttributeHandle noneAH; }; Type type; - type.CH = omniWriter->registerClass("PhysXRoadGeometryQueryTpe"); - type.raycastAH = omniWriter->registerEnumValue(type.CH, "raycast", PxVehicleSuspensionJounceCalculationType::eRAYCAST); - type.sweepAH = omniWriter->registerEnumValue(type.CH, "sweep", PxVehicleSuspensionJounceCalculationType::eSWEEP); - type.noneAH = omniWriter->registerEnumValue(type.CH, "none", PxVehicleSuspensionJounceCalculationType::eMAX_NB); + type.CH = omniWriter.registerClass("PhysXRoadGeometryQueryTpe"); + type.raycastAH = omniWriter.registerEnumValue(type.CH, "raycast", PxVehiclePhysXRoadGeometryQueryType::eRAYCAST); + type.sweepAH = omniWriter.registerEnumValue(type.CH, "sweep", PxVehiclePhysXRoadGeometryQueryType::eSWEEP); + type.noneAH = omniWriter.registerEnumValue(type.CH, "none", PxVehiclePhysXRoadGeometryQueryType::eNONE); PhysXRoadGeometryQueryParams a; - a.CH = omniWriter->registerClass("PhysXRoadGeomQueryParams"); - a.queryTypeAH = omniWriter->registerFlagsAttribute(a.CH, type.CH, "physxQueryType"); + a.CH = omniWriter.registerClass("PhysXRoadGeomQueryParams"); + a.queryTypeAH = omniWriter.registerFlagsAttribute(a.CH, "physxQueryType", type.CH); return a; } void writePhysXRoadGeometryQueryParams -(const PxVehiclePhysXRoadGeometryQueryParams& actor, - const OmniPvdObjectHandle oh, const PhysXRoadGeometryQueryParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch) +(const PxVehiclePhysXRoadGeometryQueryParams& queryParams, + const OmniPvdObjectHandle oh, const PhysXRoadGeometryQueryParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch) { - writeFlagAttribute(omniWriter, ch, oh, ah.queryTypeAH, actor.roadGeometryQueryType); + writeFlagAttribute(omniWriter, ch, oh, ah.queryTypeAH, queryParams.roadGeometryQueryType); } @@ -1590,33 +1590,33 @@ void writePhysXRoadGeometryQueryParams //VEHICLE ////////////////////// -Vehicle registerVehicle(OmniPvdWriter* omniWriter) +Vehicle registerVehicle(OmniPvdWriter& omniWriter) { Vehicle v; - v.CH = omniWriter->registerClass("Vehicle"); + v.CH = omniWriter.registerClass("Vehicle"); - v.rigidBodyParamsAH = omniWriter->registerAttribute(v.CH, "rigidBodyParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - v.rigidBodyStateAH = omniWriter->registerAttribute(v.CH, "rigidBodyState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + v.rigidBodyParamsAH = omniWriter.registerAttribute(v.CH, "rigidBodyParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + v.rigidBodyStateAH = omniWriter.registerAttribute(v.CH, "rigidBodyState", OmniPvdDataType::eOBJECT_HANDLE, 1); - v.suspStateCalcParamsAH = omniWriter->registerAttribute(v.CH, "suspStateCalcParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + v.suspStateCalcParamsAH = omniWriter.registerAttribute(v.CH, "suspStateCalcParams", OmniPvdDataType::eOBJECT_HANDLE, 1); - v.wheelAttachmentSetAH = omniWriter->registerSetAttribute(v.CH, "wheelAttachmentSet", OmniPvdDataTypeEnum::eOBJECT_HANDLE); + v.wheelAttachmentSetAH = omniWriter.registerUniqueListAttribute(v.CH, "wheelAttachmentSet", OmniPvdDataType::eOBJECT_HANDLE); - v.antiRollSetAH = omniWriter->registerSetAttribute(v.CH, "antiRollSet", OmniPvdDataTypeEnum::eOBJECT_HANDLE); - v.antiRollForceAH = omniWriter->registerAttribute(v.CH, "antiRollForce", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + v.antiRollSetAH = omniWriter.registerUniqueListAttribute(v.CH, "antiRollSet", OmniPvdDataType::eOBJECT_HANDLE); + v.antiRollForceAH = omniWriter.registerAttribute(v.CH, "antiRollForce", OmniPvdDataType::eOBJECT_HANDLE, 1); - v.brakeResponseParamsSetAH = omniWriter->registerSetAttribute(v.CH, "brakeResponseParamsSet", OmniPvdDataTypeEnum::eOBJECT_HANDLE); - v.steerResponseParamsAH = omniWriter->registerAttribute(v.CH, "steerResponseParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - v.brakeResponseStatesAH = omniWriter->registerAttribute(v.CH, "brakeResponseState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - v.steerResponseParamsAH = omniWriter->registerAttribute(v.CH, "steerResponseState", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + v.brakeResponseParamsSetAH = omniWriter.registerUniqueListAttribute(v.CH, "brakeResponseParamsSet", OmniPvdDataType::eOBJECT_HANDLE); + v.steerResponseParamsAH = omniWriter.registerAttribute(v.CH, "steerResponseParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + v.brakeResponseStatesAH = omniWriter.registerAttribute(v.CH, "brakeResponseState", OmniPvdDataType::eOBJECT_HANDLE, 1); + v.steerResponseStatesAH = omniWriter.registerAttribute(v.CH, "steerResponseState", OmniPvdDataType::eOBJECT_HANDLE, 1); - v.directDrivetrainAH = omniWriter->registerAttribute(v.CH, "directDrivetrain", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - v.engineDriveTrainAH = omniWriter->registerAttribute(v.CH, "engineDrivetrain", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + v.directDrivetrainAH = omniWriter.registerAttribute(v.CH, "directDrivetrain", OmniPvdDataType::eOBJECT_HANDLE, 1); + v.engineDriveTrainAH = omniWriter.registerAttribute(v.CH, "engineDrivetrain", OmniPvdDataType::eOBJECT_HANDLE, 1); - v.physxWheelAttachmentSetAH = omniWriter->registerSetAttribute(v.CH, "physXheelAttachmentSet", OmniPvdDataTypeEnum::eOBJECT_HANDLE); + v.physxWheelAttachmentSetAH = omniWriter.registerUniqueListAttribute(v.CH, "physXheelAttachmentSet", OmniPvdDataType::eOBJECT_HANDLE); - v.physxRoadGeometryQueryParamsAH = omniWriter->registerAttribute(v.CH, "physxRoadGeomQryParams", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); - v.physxRigidActorAH = omniWriter->registerAttribute(v.CH, "physxRigidActor", OmniPvdDataTypeEnum::eOBJECT_HANDLE, 1); + v.physxRoadGeometryQueryParamsAH = omniWriter.registerAttribute(v.CH, "physxRoadGeomQryParams", OmniPvdDataType::eOBJECT_HANDLE, 1); + v.physxRigidActorAH = omniWriter.registerAttribute(v.CH, "physxRigidActor", OmniPvdDataType::eOBJECT_HANDLE, 1); return v; } diff --git a/physx/source/physxvehicle2/src/pvd/VhPvdWriter.h b/physx/source/physxvehicle2/src/pvd/VhPvdWriter.h index b998edc07..bca6cc0e5 100644 --- a/physx/source/physxvehicle2/src/pvd/VhPvdWriter.h +++ b/physx/source/physxvehicle2/src/pvd/VhPvdWriter.h @@ -86,16 +86,16 @@ struct RigidBodyState OmniPvdAttributeHandle externalTorqueAH; }; -RigidBodyParams registerRigidBodyParams(OmniPvdWriter* omniWriter); -RigidBodyState registerRigidBodyState(OmniPvdWriter* omniWriter); +RigidBodyParams registerRigidBodyParams(OmniPvdWriter& omniWriter); +RigidBodyState registerRigidBodyState(OmniPvdWriter& omniWriter); void writeRigidBodyParams (const PxVehicleRigidBodyParams& rbodyParams, - const OmniPvdObjectHandle oh, const RigidBodyParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const RigidBodyParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeRigidBodyState (const PxVehicleRigidBodyState& rbodyParams, - const OmniPvdObjectHandle oh, const RigidBodyState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const RigidBodyState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ///////////////////////////////// @@ -125,30 +125,30 @@ struct WheelResponseStates -WheelResponseParams registerSteerResponseParams(OmniPvdWriter* omniWriter); -WheelResponseParams registerBrakeResponseParams(OmniPvdWriter* omniWriter); -WheelResponseStates registerSteerResponseStates(OmniPvdWriter* omniWriter); -WheelResponseStates registerBrakeResponseStates(OmniPvdWriter* omniWriter); +WheelResponseParams registerSteerResponseParams(OmniPvdWriter& omniWriter); +WheelResponseParams registerBrakeResponseParams(OmniPvdWriter& omniWriter); +WheelResponseStates registerSteerResponseStates(OmniPvdWriter& omniWriter); +WheelResponseStates registerBrakeResponseStates(OmniPvdWriter& omniWriter); void writeSteerResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleSteerCommandResponseParams& steerResponseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeBrakeResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleBrakeCommandResponseParams& brakeResponseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSteerResponseStates (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& steerResponseStates, - const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeBrakeResponseStates (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& brakeResponseStates, - const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelResponseStates& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ///////////////////////////////////////////// //WHEEL ATTACHMENTS @@ -347,102 +347,102 @@ struct WheelAttachment OmniPvdAttributeHandle tireForceAH; }; -WheelParams registerWheelParams(OmniPvdWriter* omniWriter); -WheelActuationState registerWheelActuationState(OmniPvdWriter* omniWriter); -WheelRigidBody1dState registerWheelRigidBody1dState(OmniPvdWriter* omniWriter); -WheelLocalPoseState registerWheelLocalPoseState(OmniPvdWriter* omniWriter); -RoadGeometryState registerRoadGeomState(OmniPvdWriter* omniWriter); -SuspParams registerSuspParams(OmniPvdWriter* omniWriter); -SuspCompParams registerSuspComplianceParams(OmniPvdWriter* omniWriter); -SuspForceParams registerSuspForceParams(OmniPvdWriter* omniWriter); -SuspState registerSuspState(OmniPvdWriter* omniWriter); -SuspCompState registerSuspComplianceState(OmniPvdWriter* omniWriter); -SuspForce registerSuspForce(OmniPvdWriter* omniWriter); -TireParams registerTireParams(OmniPvdWriter* omniWriter); -TireDirectionState registerTireDirectionState(OmniPvdWriter* omniWriter); -TireSpeedState registerTireSpeedState(OmniPvdWriter* omniWriter); -TireSlipState registerTireSlipState(OmniPvdWriter* omniWriter); -TireStickyState registerTireStickyState(OmniPvdWriter* omniWriter); -TireGripState registerTireGripState(OmniPvdWriter* omniWriter); -TireCamberState registerTireCamberState(OmniPvdWriter* omniWriter); -TireForce registerTireForce(OmniPvdWriter* omniWriter); -WheelAttachment registerWheelAttachment(OmniPvdWriter* omniWriter); +WheelParams registerWheelParams(OmniPvdWriter& omniWriter); +WheelActuationState registerWheelActuationState(OmniPvdWriter& omniWriter); +WheelRigidBody1dState registerWheelRigidBody1dState(OmniPvdWriter& omniWriter); +WheelLocalPoseState registerWheelLocalPoseState(OmniPvdWriter& omniWriter); +RoadGeometryState registerRoadGeomState(OmniPvdWriter& omniWriter); +SuspParams registerSuspParams(OmniPvdWriter& omniWriter); +SuspCompParams registerSuspComplianceParams(OmniPvdWriter& omniWriter); +SuspForceParams registerSuspForceParams(OmniPvdWriter& omniWriter); +SuspState registerSuspState(OmniPvdWriter& omniWriter); +SuspCompState registerSuspComplianceState(OmniPvdWriter& omniWriter); +SuspForce registerSuspForce(OmniPvdWriter& omniWriter); +TireParams registerTireParams(OmniPvdWriter& omniWriter); +TireDirectionState registerTireDirectionState(OmniPvdWriter& omniWriter); +TireSpeedState registerTireSpeedState(OmniPvdWriter& omniWriter); +TireSlipState registerTireSlipState(OmniPvdWriter& omniWriter); +TireStickyState registerTireStickyState(OmniPvdWriter& omniWriter); +TireGripState registerTireGripState(OmniPvdWriter& omniWriter); +TireCamberState registerTireCamberState(OmniPvdWriter& omniWriter); +TireForce registerTireForce(OmniPvdWriter& omniWriter); +WheelAttachment registerWheelAttachment(OmniPvdWriter& omniWriter); void writeWheelParams (const PxVehicleWheelParams& params, - const OmniPvdObjectHandle oh, const WheelParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeWheelActuationState (const PxVehicleWheelActuationState& actState, - const OmniPvdObjectHandle oh, const WheelActuationState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelActuationState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeWheelRigidBody1dState (const PxVehicleWheelRigidBody1dState& rigidBodyState, - const OmniPvdObjectHandle oh, const WheelRigidBody1dState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelRigidBody1dState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeWheelLocalPoseState (const PxVehicleWheelLocalPose& pose, - const OmniPvdObjectHandle oh, const WheelLocalPoseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelLocalPoseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeRoadGeomState (const PxVehicleRoadGeometryState& roadGeometryState, - const OmniPvdObjectHandle oh, const RoadGeometryState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const RoadGeometryState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSuspParams (const PxVehicleSuspensionParams& suspParams, - const OmniPvdObjectHandle oh, const SuspParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSuspComplianceParams (const PxVehicleSuspensionComplianceParams& compParams, - const OmniPvdObjectHandle oh, const SuspCompParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspCompParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSuspForceParams (const PxVehicleSuspensionForceParams& forceParams, - const OmniPvdObjectHandle oh, const SuspForceParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspForceParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSuspState (const PxVehicleSuspensionState& suspState, - const OmniPvdObjectHandle oh, const SuspState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSuspComplianceState (const PxVehicleSuspensionComplianceState& suspCompState, - const OmniPvdObjectHandle oh, const SuspCompState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspCompState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeSuspForce (const PxVehicleSuspensionForce& suspForce, - const OmniPvdObjectHandle oh, const SuspForce& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspForce& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireParams (const PxVehicleTireForceParams& tireParams, - const OmniPvdObjectHandle oh, const TireParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireDirectionState (const PxVehicleTireDirectionState& tireDirState, - const OmniPvdObjectHandle oh, const TireDirectionState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireDirectionState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireSpeedState (const PxVehicleTireSpeedState& tireSpeedState, - const OmniPvdObjectHandle oh, const TireSpeedState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireSpeedState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireSlipState (const PxVehicleTireSlipState& tireSlipState, - const OmniPvdObjectHandle oh, const TireSlipState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireSlipState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireStickyState (const PxVehicleTireStickyState& tireStickyState, - const OmniPvdObjectHandle oh, const TireStickyState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireStickyState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireGripState (const PxVehicleTireGripState& tireGripState, - const OmniPvdObjectHandle oh, const TireGripState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireGripState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireCamberState (const PxVehicleTireCamberAngleState& tireCamberState, - const OmniPvdObjectHandle oh, const TireCamberState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireCamberState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeTireForce (const PxVehicleTireForce& tireForce, - const OmniPvdObjectHandle oh, const TireForce& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const TireForce& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ///////////////////////////////////////// //ANTIROLL @@ -462,16 +462,16 @@ struct AntiRollForce OmniPvdAttributeHandle torqueAH; }; -AntiRollParams registerAntiRollParams(OmniPvdWriter* omniWriter); -AntiRollForce registerAntiRollForce(OmniPvdWriter* omniWriter); +AntiRollParams registerAntiRollParams(OmniPvdWriter& omniWriter); +AntiRollForce registerAntiRollForce(OmniPvdWriter& omniWriter); void writeAntiRollParams (const PxVehicleAntiRollForceParams& antiRollParams, - const OmniPvdObjectHandle oh, const AntiRollParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const AntiRollParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeAntiRollForce (const PxVehicleAntiRollTorque& antiRollForce, - const OmniPvdObjectHandle oh, const AntiRollForce& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const AntiRollForce& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); //////////////////////////////////////// //SUSPENSION STATE CALCULATION @@ -484,11 +484,11 @@ struct SuspStateCalcParams OmniPvdAttributeHandle limitExpansionValAH; }; -SuspStateCalcParams registerSuspStateCalcParams(OmniPvdWriter* omniWriter); +SuspStateCalcParams registerSuspStateCalcParams(OmniPvdWriter& omniWriter); void writeSuspStateCalcParams (const PxVehicleSuspensionStateCalculationParams& suspStateCalcParams, - const OmniPvdObjectHandle oh, const SuspStateCalcParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const SuspStateCalcParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ///////////////////////////////////////// //DIRECT DRIVETRAIN @@ -526,28 +526,28 @@ struct DirectDrivetrain OmniPvdAttributeHandle throttleResponseStateAH; }; -WheelResponseParams registerDirectDriveThrottleResponseParams(OmniPvdWriter* omniWriter); -DirectDriveCommandState registerDirectDriveCommandState(OmniPvdWriter* omniWriter); -DirectDriveTransmissionCommandState registerDirectDriveTransmissionCommandState(OmniPvdWriter* omniWriter); -DirectDriveThrottleResponseState registerDirectDriveThrottleResponseState(OmniPvdWriter* omniWriter); -DirectDrivetrain registerDirectDrivetrain(OmniPvdWriter* omniWriter); +WheelResponseParams registerDirectDriveThrottleResponseParams(OmniPvdWriter& omniWriter); +DirectDriveCommandState registerDirectDriveCommandState(OmniPvdWriter& omniWriter); +DirectDriveTransmissionCommandState registerDirectDriveTransmissionCommandState(OmniPvdWriter& omniWriter); +DirectDriveThrottleResponseState registerDirectDriveThrottleResponseState(OmniPvdWriter& omniWriter); +DirectDrivetrain registerDirectDrivetrain(OmniPvdWriter& omniWriter); void writeDirectDriveThrottleResponseParams (const PxVehicleAxleDescription& axleDesc, const PxVehicleDirectDriveThrottleCommandResponseParams& directDriveThrottleResponseParams, - const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const WheelResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeDirectDriveCommandState (const PxVehicleCommandState& commands, - const OmniPvdObjectHandle oh, const DirectDriveCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const DirectDriveCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeDirectDriveTransmissionCommandState (const PxVehicleDirectDriveTransmissionCommandState& transmission, - const OmniPvdObjectHandle oh, const DirectDriveTransmissionCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const DirectDriveTransmissionCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeDirectDriveThrottleResponseState (const PxVehicleAxleDescription& axleDesc, const PxVehicleArrayData& throttleResponseState, - const OmniPvdObjectHandle oh, const DirectDriveThrottleResponseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const DirectDriveThrottleResponseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ///////////////////////////////////////// @@ -557,9 +557,9 @@ void writeDirectDriveThrottleResponseState struct EngineDriveCommandState { OmniPvdClassHandle CH; - OmniPvdAttributeHandle brakes; - OmniPvdAttributeHandle throttle; - OmniPvdAttributeHandle steer; + OmniPvdAttributeHandle brakesAH; + OmniPvdAttributeHandle throttleAH; + OmniPvdAttributeHandle steerAH; }; struct EngineDriveTransmissionCommandState @@ -716,88 +716,88 @@ struct EngineDrivetrain OmniPvdAttributeHandle clutchSlipStateAH; }; -EngineDriveCommandState registerEngineDriveCommandState(OmniPvdWriter* omniWriter); -EngineDriveTransmissionCommandState registerEngineDriveTransmissionCommandState(OmniPvdWriter* omniWriter); -ClutchResponseParams registerClutchResponseParams(OmniPvdWriter* omniWriter); -ClutchParams registerClutchParams(OmniPvdWriter* omniWriter); -EngineParams registerEngineParams(OmniPvdWriter* omniWriter); -GearboxParams registerGearboxParams(OmniPvdWriter* omniWriter); -AutoboxParams registerAutoboxParams(OmniPvdWriter* omniWriter); -MultiWheelDiffParams registerMultiWheelDiffParams(OmniPvdWriter* omniWriter); -FourWheelDiffParams registerFourWheelDiffParams(OmniPvdWriter* omniWriter); -//TankDiffParams registerTankDiffParams(OmniPvdWriter* omniWriter); -ClutchResponseState registerClutchResponseState(OmniPvdWriter* omniWriter); -ThrottleResponseState registerThrottleResponseState(OmniPvdWriter* omniWriter); -EngineState registerEngineState(OmniPvdWriter* omniWriter); -GearboxState registerGearboxState(OmniPvdWriter* omniWriter); -AutoboxState registerAutoboxState(OmniPvdWriter* omniWriter); -DiffState registerDiffState(OmniPvdWriter* omniWriter); -ClutchSlipState registerClutchSlipState(OmniPvdWriter* omniWriter); -EngineDrivetrain registerEngineDrivetrain(OmniPvdWriter* omniWriter); +EngineDriveCommandState registerEngineDriveCommandState(OmniPvdWriter& omniWriter); +EngineDriveTransmissionCommandState registerEngineDriveTransmissionCommandState(OmniPvdWriter& omniWriter); +ClutchResponseParams registerClutchResponseParams(OmniPvdWriter& omniWriter); +ClutchParams registerClutchParams(OmniPvdWriter& omniWriter); +EngineParams registerEngineParams(OmniPvdWriter& omniWriter); +GearboxParams registerGearboxParams(OmniPvdWriter& omniWriter); +AutoboxParams registerAutoboxParams(OmniPvdWriter& omniWriter); +MultiWheelDiffParams registerMultiWheelDiffParams(OmniPvdWriter& omniWriter); +FourWheelDiffParams registerFourWheelDiffParams(OmniPvdWriter& omniWriter); +//TankDiffParams registerTankDiffParams(OmniPvdWriter& omniWriter); +ClutchResponseState registerClutchResponseState(OmniPvdWriter& omniWriter); +ThrottleResponseState registerThrottleResponseState(OmniPvdWriter& omniWriter); +EngineState registerEngineState(OmniPvdWriter& omniWriter); +GearboxState registerGearboxState(OmniPvdWriter& omniWriter); +AutoboxState registerAutoboxState(OmniPvdWriter& omniWriter); +DiffState registerDiffState(OmniPvdWriter& omniWriter); +ClutchSlipState registerClutchSlipState(OmniPvdWriter& omniWriter); +EngineDrivetrain registerEngineDrivetrain(OmniPvdWriter& omniWriter); void writeEngineDriveCommandState (const PxVehicleCommandState& commandState, - const OmniPvdObjectHandle oh, const EngineDriveCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const EngineDriveCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeEngineDriveTransmissionCommandState (const PxVehicleEngineDriveTransmissionCommandState& transmission, - const OmniPvdObjectHandle oh, const EngineDriveTransmissionCommandState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const EngineDriveTransmissionCommandState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeClutchResponseParams (const PxVehicleClutchCommandResponseParams& clutchResponseParams, - const OmniPvdObjectHandle oh, const ClutchResponseParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const ClutchResponseParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeClutchParams (const PxVehicleClutchParams& clutchParams, - const OmniPvdObjectHandle oh, const ClutchParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const ClutchParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeEngineParams (const PxVehicleEngineParams& engineParams, - const OmniPvdObjectHandle oh, const EngineParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const EngineParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeGearboxParams (const PxVehicleGearboxParams& gearboxParams, - const OmniPvdObjectHandle oh, const GearboxParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const GearboxParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeAutoboxParams (const PxVehicleAutoboxParams& gearboxParams, - const OmniPvdObjectHandle oh, const AutoboxParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const AutoboxParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeMultiWheelDiffParams (const PxVehicleMultiWheelDriveDifferentialParams& diffParams, - const OmniPvdObjectHandle oh, const MultiWheelDiffParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const MultiWheelDiffParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeFourWheelDiffParams (const PxVehicleFourWheelDriveDifferentialParams& diffParams, - const OmniPvdObjectHandle oh, const FourWheelDiffParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const FourWheelDiffParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeClutchResponseState (const PxVehicleClutchCommandResponseState& clutchResponseState, - const OmniPvdObjectHandle oh, const ClutchResponseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const ClutchResponseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeThrottleResponseState (const PxVehicleEngineDriveThrottleCommandResponseState& throttleResponseState, - const OmniPvdObjectHandle oh, const ThrottleResponseState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const ThrottleResponseState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeEngineState (const PxVehicleEngineState& engineState, - const OmniPvdObjectHandle oh, const EngineState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const EngineState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeGearboxState (const PxVehicleGearboxState& gearboxState, - const OmniPvdObjectHandle oh, const GearboxState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const GearboxState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeAutoboxState (const PxVehicleAutoboxState& gearboxState, - const OmniPvdObjectHandle oh, const AutoboxState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const AutoboxState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeDiffState (const PxVehicleDifferentialState& diffState, - const OmniPvdObjectHandle oh, const DiffState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const DiffState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writeClutchSlipState (const PxVehicleClutchSlipState& clutchSlipState, - const OmniPvdObjectHandle oh, const ClutchSlipState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const ClutchSlipState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); /////////////////////////////// //WHEEL ATTACHMENT PHYSX INTEGRATION @@ -863,32 +863,32 @@ struct PhysXMaterialFriction OmniPvdAttributeHandle materialPtrAH; }; -PhysXSuspensionLimitConstraintParams registerSuspLimitConstraintParams(OmniPvdWriter* omniWriter); -PhysXWheelShape registerPhysXWheelShape(OmniPvdWriter* omniWriter); -PhysXRoadGeomState registerPhysXRoadGeomState(OmniPvdWriter* omniWriter); -PhysXConstraintState registerPhysXConstraintState(OmniPvdWriter* omniWriter); -PhysXWheelAttachment registerPhysXWheelAttachment(OmniPvdWriter* omniWriter); -PhysXMaterialFriction registerPhysXMaterialFriction(OmniPvdWriter* omniWriter); +PhysXSuspensionLimitConstraintParams registerSuspLimitConstraintParams(OmniPvdWriter& omniWriter); +PhysXWheelShape registerPhysXWheelShape(OmniPvdWriter& omniWriter); +PhysXRoadGeomState registerPhysXRoadGeomState(OmniPvdWriter& omniWriter); +PhysXConstraintState registerPhysXConstraintState(OmniPvdWriter& omniWriter); +PhysXWheelAttachment registerPhysXWheelAttachment(OmniPvdWriter& omniWriter); +PhysXMaterialFriction registerPhysXMaterialFriction(OmniPvdWriter& omniWriter); void writePhysXSuspLimitConstraintParams (const PxVehiclePhysXSuspensionLimitConstraintParams& params, - const OmniPvdObjectHandle oh, const PhysXSuspensionLimitConstraintParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const PhysXSuspensionLimitConstraintParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writePhysXWheelShape (const PxShape* wheelShape, - const OmniPvdObjectHandle oh, const PhysXWheelShape& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const PhysXWheelShape& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writePhysXRoadGeomState (const PxVehiclePhysXRoadGeometryQueryState& roadGeomState, -const OmniPvdObjectHandle oh, const PhysXRoadGeomState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); +const OmniPvdObjectHandle oh, const PhysXRoadGeomState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writePhysXConstraintState (const PxVehiclePhysXConstraintState& roadGeomState, - const OmniPvdObjectHandle oh, const PhysXConstraintState& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const PhysXConstraintState& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writePhysXMaterialFriction (const PxVehiclePhysXMaterialFriction& materialFriction, - const OmniPvdObjectHandle oh, const PhysXMaterialFriction& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const PhysXMaterialFriction& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ////////////////////////////// //PHYSX RIGID ACTOR @@ -907,16 +907,16 @@ struct PhysXRigidActor }; -PhysXRoadGeometryQueryParams registerPhysXRoadGeometryQueryParams(OmniPvdWriter* omniWriter); -PhysXRigidActor registerPhysXRigidActor(OmniPvdWriter* omniWriter); +PhysXRoadGeometryQueryParams registerPhysXRoadGeometryQueryParams(OmniPvdWriter& omniWriter); +PhysXRigidActor registerPhysXRigidActor(OmniPvdWriter& omniWriter); void writePhysXRigidActor (const PxRigidActor* actor, - const OmniPvdObjectHandle oh, const PhysXRigidActor& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const PhysXRigidActor& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); void writePhysXRoadGeometryQueryParams (const PxVehiclePhysXRoadGeometryQueryParams& actor, - const OmniPvdObjectHandle oh, const PhysXRoadGeometryQueryParams& ah, OmniPvdWriter* omniWriter, OmniPvdContextHandle ch); + const OmniPvdObjectHandle oh, const PhysXRoadGeometryQueryParams& ah, OmniPvdWriter& omniWriter, OmniPvdContextHandle ch); ////////////////////////////// //VEHICLE @@ -950,7 +950,7 @@ struct Vehicle OmniPvdAttributeHandle physxRigidActorAH; }; -Vehicle registerVehicle(OmniPvdWriter* omniWriter); +Vehicle registerVehicle(OmniPvdWriter& omniWriter); #if !PX_DOXYGEN diff --git a/physx/source/physxvehicle2/src/suspension/VhSuspensionFunctions.cpp b/physx/source/physxvehicle2/src/suspension/VhSuspensionFunctions.cpp index f9732ec0b..a0b0a5e4e 100644 --- a/physx/source/physxvehicle2/src/suspension/VhSuspensionFunctions.cpp +++ b/physx/source/physxvehicle2/src/suspension/VhSuspensionFunctions.cpp @@ -331,7 +331,7 @@ static void limitSuspensionExpansionVelocity (const PxReal jounceSpeed, const PxReal previousJounceSpeed, const PxReal previousJounce, const PxReal suspStiffness, const PxReal suspDamping, const PxVec3& suspDirWorld, const PxReal wheelMass, - const PxReal dt, const PxVec3& gravity, + const PxReal dt, const PxVec3& gravity, const bool hasGroundHit, PxVehicleSuspensionState& suspState) { PX_ASSERT(jounceSpeed < 0.0f); // don't call this method if the suspension is not expanding @@ -357,16 +357,30 @@ static void limitSuspensionExpansionVelocity const PxReal gravitySuspDir = gravity.dot(suspDirWorld); - const PxReal suspDirVelWheel = suspDirVel + (gravitySuspDir * dt); - // gravity is considered too as it affects the wheel and can close the distance to the ground - // too. External forces acting on the sprung mass are ignored as those propagate through the - // suspension to the wheel. + PxReal velocityThreshold; + if (hasGroundHit) + { + velocityThreshold = (gravitySuspDir > 0.0f) ? suspDirVel + (gravitySuspDir * dt) : suspDirVel; + // gravity is considered too as it affects the wheel and can close the distance to the ground + // too. External forces acting on the sprung mass are ignored as those propagate + // through the suspension to the wheel. + // If gravity points in the opposite direction of the suspension travel direction, it is + // ignored. The suspension should never elongate more than what's given by the current delta + // jounce (defined by jounceSpeed, i.e., jounceSpeed < -suspDirVel has to hold all the time + // for the clamping to take place). + } + else + { + velocityThreshold = suspDirVel; + // if there was no hit detected, the gravity will not be taken into account since there is no + // ground to move towards. + } - if (jounceSpeed < (-suspDirVelWheel)) + if (jounceSpeed < (-velocityThreshold)) { // The suspension can not expand fast enough to place the wheel on the ground. As a result, // the scenario is interpreted as if there was no hit and the wheels end up in air. The - // jounce is adjusted based on the clamped velocity to not have it snap to 0 immediately. + // jounce is adjusted based on the clamped velocity to not have it snap to the target immediately. // note: could consider applying the suspension force to the sprung mass too but the complexity // seems high enough already. @@ -409,7 +423,7 @@ void PxVehicleSuspensionStateUpdate const PxReal jounceSpeed = (-prevJounce) / dt; const PxVec3 suspDirWorld = PxVehicleComputeSuspensionDirection(suspParams, rigidBodyState.pose); limitSuspensionExpansionVelocity(jounceSpeed, prevJounceSpeed, prevJounce, - suspStiffness, suspDamping, suspDirWorld, whlParams.mass, dt, gravity, + suspStiffness, suspDamping, suspDirWorld, whlParams.mass, dt, gravity, false, suspState); } } @@ -454,7 +468,7 @@ void PxVehicleSuspensionStateUpdate if (suspStateCalcParams.limitSuspensionExpansionVelocity && (suspState.jounceSpeed < 0.0f)) { limitSuspensionExpansionVelocity(suspState.jounceSpeed, prevJounceSpeed, prevJounce, - suspStiffness, suspDamping, suspDir, whlParams.mass, dt, gravity, + suspStiffness, suspDamping, suspDir, whlParams.mass, dt, gravity, true, suspState); } } diff --git a/physx/source/physxvehicle2/src/wheel/VhWheelFunctions.cpp b/physx/source/physxvehicle2/src/wheel/VhWheelFunctions.cpp index 651f3d165..ab8d4ee9d 100644 --- a/physx/source/physxvehicle2/src/wheel/VhWheelFunctions.cpp +++ b/physx/source/physxvehicle2/src/wheel/VhWheelFunctions.cpp @@ -64,14 +64,15 @@ void PxVehicleWheelRotationAngleUpdate const bool isBrakeApplied = actState.isBrakeApplied; const bool isDriveApplied = actState.isDriveApplied; const PxF32 lngSpeed = trSpeedState.speedStates[PxVehicleTireDirectionModes::eLONGITUDINAL]; + const PxF32 absLngSpeed = PxAbs(lngSpeed); PxF32 wheelOmega = whlRigidBody1dState.rotationSpeed; if (jounce > 0 && //(i) wheel touching ground !isBrakeApplied && //(ii) no brake applied !isDriveApplied && //(iii) no drive torque applied - PxAbs(lngSpeed < thresholdForwardSpeedForWheelAngleIntegration)) //(iv) low speed + (absLngSpeed < thresholdForwardSpeedForWheelAngleIntegration)) //(iv) low speed { const PxF32 wheelRadius = whlParams.radius; - const PxF32 alpha = PxAbs(lngSpeed) / thresholdForwardSpeedForWheelAngleIntegration; + const PxF32 alpha = absLngSpeed / thresholdForwardSpeedForWheelAngleIntegration; wheelOmega = (lngSpeed/wheelRadius)*(1.0f - alpha) + wheelOmega * alpha; } diff --git a/physx/source/pvd/include/PxPvdUserRenderer.h b/physx/source/pvd/include/PxPvdUserRenderer.h index ae390a199..2c74ae829 100644 --- a/physx/source/pvd/include/PxPvdUserRenderer.h +++ b/physx/source/pvd/include/PxPvdUserRenderer.h @@ -80,10 +80,10 @@ class PvdUserRenderer : public PxUserAllocated // Constraint visualization routines virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) = 0; - virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value, bool active) = 0; - virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper, bool active) = 0; - virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ, bool active) = 0; - virtual void visualizeDoubleCone(const PxTransform& t, float angle, bool active) = 0; + virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value) = 0; + virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper) = 0; + virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ) = 0; + virtual void visualizeDoubleCone(const PxTransform& t, float angle) = 0; // Clear the immedate buffer. virtual void flushRenderEvents() = 0; diff --git a/physx/source/pvd/src/PxPvdUserRenderer.cpp b/physx/source/pvd/src/PxPvdUserRenderer.cpp index 0cf98116a..9eb2e7938 100644 --- a/physx/source/pvd/src/PxPvdUserRenderer.cpp +++ b/physx/source/pvd/src/PxPvdUserRenderer.cpp @@ -184,25 +184,25 @@ struct UserRenderer : public PvdUserRenderer } // Constraint visualization routines - virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) + virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) PX_OVERRIDE { handleEvent(JointFramesRenderEvent(parent, child)); } - virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value, bool active) + virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, float value) PX_OVERRIDE { - handleEvent(LinearLimitRenderEvent(t0, t1, value, active)); + handleEvent(LinearLimitRenderEvent(t0, t1, value, true)); } - virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper, bool active) + virtual void visualizeAngularLimit(const PxTransform& t0, float lower, float upper) PX_OVERRIDE { - handleEvent(AngularLimitRenderEvent(t0, lower, upper, active)); + handleEvent(AngularLimitRenderEvent(t0, lower, upper, true)); } - virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ, bool active) + virtual void visualizeLimitCone(const PxTransform& t, float tanQSwingY, float tanQSwingZ) PX_OVERRIDE { - handleEvent(LimitConeRenderEvent(t, tanQSwingY, tanQSwingZ, active)); + handleEvent(LimitConeRenderEvent(t, tanQSwingY, tanQSwingZ, true)); } - virtual void visualizeDoubleCone(const PxTransform& t, float angle, bool active) + virtual void visualizeDoubleCone(const PxTransform& t, float angle) PX_OVERRIDE { - handleEvent(DoubleConeRenderEvent(t, angle, active)); + handleEvent(DoubleConeRenderEvent(t, angle, true)); } // Clear the immedate buffer. virtual void flushRenderEvents() diff --git a/physx/source/scenequery/src/SqQuery.cpp b/physx/source/scenequery/src/SqQuery.cpp index 67bbdd54c..5008f0d94 100644 --- a/physx/source/scenequery/src/SqQuery.cpp +++ b/physx/source/scenequery/src/SqQuery.cpp @@ -183,7 +183,7 @@ template struct GeomQueryAny { static PX_FORCE_INLINE PxU32 geomHit( - const CachedFuncs& funcs, const MultiQueryInput& input, const Gu::ShapeData& sd, + const CachedFuncs& funcs, const MultiQueryInput& input, const Gu::ShapeData* sd, const PxGeometry& sceneGeom, const PxTransform& pose, PxHitFlags hitFlags, PxU32 maxHits, HitType* hits, const PxReal shrunkMaxDistance, const PxBounds3* precomputedBounds, PxQueryThreadContext* context) @@ -217,6 +217,7 @@ struct GeomQueryAny else if(HitTypeSupport::IsSweep) { PX_ASSERT(precomputedBounds != NULL); + PX_ASSERT(sd != NULL); // b0 = query shape bounds // b1 = scene shape bounds // AP: Here we clip the sweep to bounds with sum of extents. This is needed for GJK stability. @@ -274,7 +275,7 @@ struct GeomQueryAny { const bool precise = hitFlags & PxHitFlag::ePRECISE_SWEEP; const SweepCapsuleFunc func = precise ? sf.preciseCapsuleMap[geom1.getType()] : sf.capsuleMap[geom1.getType()]; - retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd.getGuCapsule(), unitDir, distance, sweepHit, hitFlags, inflation, context)); + retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd->getGuCapsule(), unitDir, distance, sweepHit, hitFlags, inflation, context)); } break; @@ -282,7 +283,7 @@ struct GeomQueryAny { const bool precise = hitFlags & PxHitFlag::ePRECISE_SWEEP; const SweepBoxFunc func = precise ? sf.preciseBoxMap[geom1.getType()] : sf.boxMap[geom1.getType()]; - retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd.getGuBox(), unitDir, distance, sweepHit, hitFlags, inflation, context)); + retVal = PxU32(func(geom1, pose1Offset, static_cast(geom0), pose0, sd->getGuBox(), unitDir, distance, sweepHit, hitFlags, inflation, context)); } break; @@ -371,6 +372,7 @@ static PX_FORCE_INLINE bool applyAllPreFiltersSQ( static PX_NOINLINE void computeCompoundShapeTransform(PxTransform* PX_RESTRICT transform, const PxTransform* PX_RESTRICT compoundPose, const PxTransform* PX_RESTRICT transforms, PxU32 primIndex) { + // PT:: tag: scalar transform*transform *transform = (*compoundPose) * transforms[primIndex]; } @@ -553,7 +555,7 @@ struct MultiQueryCallback : public PrunerRaycastCallback, public PrunerOverlapCa // call the geometry specific intersection template const PxU32 nbSubHits = GeomQueryAny::geomHit( - mScene.mCachedFuncs, mInput, *mShapeData, shapeGeom, + mScene.mCachedFuncs, mInput, mShapeData, shapeGeom, *shapeTransform, filteredHitFlags | mMeshAnyHitFlags, maxSubHits1, subHits1, mShrunkDistance, mQueryShapeBounds, &mHitCall); @@ -590,7 +592,7 @@ struct MultiQueryCallback : public PrunerRaycastCallback, public PrunerOverlapCa return false; // found a hit for ANY qType, can early exit now } - if(mNoBlock) + if(mNoBlock && hitType==PxQueryHitType::eBLOCK) hitType = PxQueryHitType::eTOUCH; PX_WARN_ONCE_IF(HitTypeSupport::IsOverlap && hitType == PxQueryHitType::eBLOCK, @@ -935,6 +937,11 @@ bool SceneQueries::_overlap( PX_PROFILE_ZONE("SceneQuery.overlap", getContextId()); PX_SIMD_GUARD_CNDT(flags & PxGeometryQueryFlag::eSIMD_GUARD) +#if PX_CHECKED + if (!PxGeometryQuery::isValid(geometry)) + return outputError(__LINE__, "Provided geometry is not valid"); +#endif + MultiQueryInput input(&geometry, &pose); return multiQuery(input, hits, PxHitFlags(), cache, filterData, filterCall); } @@ -1025,6 +1032,7 @@ static bool doQueryVsCached(const PrunerHandle handle, PxU32 prunerIndex, const pcb.mShapeData = &sd; // againAfterCache = pcb.invoke(dummyDist, 0); againAfterCache = pcb.template _invoke(dummyDist, 0, payloads, transform, compoundPosePtr); + pcb.mQueryShapeBounds = NULL; pcb.mShapeData = NULL; } else // againAfterCache = pcb.invoke(dummyDist, 0); diff --git a/physx/source/simulationcontroller/include/ScActorCore.h b/physx/source/simulationcontroller/include/ScActorCore.h index 5f3202f64..7c0c9e0d7 100644 --- a/physx/source/simulationcontroller/include/ScActorCore.h +++ b/physx/source/simulationcontroller/include/ScActorCore.h @@ -31,27 +31,15 @@ #include "common/PxMetaData.h" #include "PxActor.h" -#include "foundation/PxUserAllocated.h" namespace physx { - -class PxActor; - namespace Sc { - - class Scene; class ActorSim; - class ActorCore : public PxUserAllocated + class ActorCore { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION ActorCore(const PxEMPTY) : mSim(NULL), mActorFlags(PxEmpty) @@ -59,9 +47,8 @@ namespace Sc } static void getBinaryMetaData(PxOutputStream& stream); //~PX_SERIALIZATION - ActorCore(PxActorType::Enum actorType, PxU8 actorFlags, - PxClientID owner, PxDominanceGroup dominanceGroup); - /*virtual*/ ~ActorCore(); + ActorCore(PxActorType::Enum actorType, PxU8 actorFlags, PxClientID owner, PxDominanceGroup dominanceGroup); + ~ActorCore(); PX_FORCE_INLINE ActorSim* getSim() const { return mSim; } PX_FORCE_INLINE void setSim(ActorSim* sim) @@ -104,9 +91,6 @@ namespace Sc const PxU32 id = mAggregateIDOwnerClient & 0x00ffffff; return id == 0x00ffffff ? PX_INVALID_U32 : id; } - //virtual PxActor* getPxActor() const = 0; - //virtual PxIntBool isFrozen() const { return IntTrue; }; - private: ActorSim* mSim; // PxU32 mAggregateIDOwnerClient; // PxClientID (8bit) | aggregate ID (24bit) diff --git a/physx/source/simulationcontroller/include/ScArticulationCore.h b/physx/source/simulationcontroller/include/ScArticulationCore.h index 04a14df7c..da1a8d21b 100644 --- a/physx/source/simulationcontroller/include/ScArticulationCore.h +++ b/physx/source/simulationcontroller/include/ScArticulationCore.h @@ -34,29 +34,14 @@ namespace physx { - -class PxvArticulation; - class PxNodeIndex; namespace Sc { - //typedef Dy::FsData ArticulationDriveCache; - class ArticulationSim; - class BodyCore; - class BodySim; - class ArticulationJointCore; class ArticulationCore { - //= 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. - //================================================================================================== - //--------------------------------------------------------------------------------- // Construction, destruction & initialization //--------------------------------------------------------------------------------- @@ -111,7 +96,8 @@ namespace Sc bool applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag)const; - void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const; + void copyInternalStateToCache + (PxArticulationCache& cache, const PxArticulationCacheFlags flag, const bool isGpuSimEnabled) const; void packJointData(const PxReal* maximum, PxReal* reduced) const; @@ -129,7 +115,6 @@ namespace Sc void computeJointForce(PxArticulationCache& cache) const; - void computeDenseJacobian(PxArticulationCache& cache, PxU32& nRows, PxU32& nCols) const; void computeCoefficientMatrix(PxArticulationCache& cache) const; @@ -140,7 +125,7 @@ namespace Sc PxU32 getCoefficientMatrixSize() const; - PxSpatialVelocity getLinkAcceleration(const PxU32 linkId) const; + PxSpatialVelocity getLinkAcceleration(const PxU32 linkId, const bool isGpuSimEnabled) const; PxU32 getGpuArticulationIndex() const; @@ -164,7 +149,7 @@ namespace Sc return *reinterpret_cast(reinterpret_cast(&core) - offset); } - PxNodeIndex getIslandNodeIndex() const; + PxNodeIndex getIslandNodeIndex() const; void setGlobalPose(); diff --git a/physx/source/simulationcontroller/include/ScArticulationJointCore.h b/physx/source/simulationcontroller/include/ScArticulationJointCore.h index 8acec0de6..67028ded9 100644 --- a/physx/source/simulationcontroller/include/ScArticulationJointCore.h +++ b/physx/source/simulationcontroller/include/ScArticulationJointCore.h @@ -31,7 +31,6 @@ #include "foundation/PxTransform.h" #include "common/PxMetaData.h" -#include "foundation/PxUserAllocated.h" #include "DyVArticulation.h" namespace physx @@ -51,15 +50,8 @@ namespace Sc PxTransform childPose; }; - class ArticulationJointCore : public PxUserAllocated + class ArticulationJointCore { - //= 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. - //================================================================================================== - public: // PX_SERIALIZATION ArticulationJointCore(const PxEMPTY) : mCore(PxEmpty), mSim(NULL) {} diff --git a/physx/source/simulationcontroller/include/ScBodyCore.h b/physx/source/simulationcontroller/include/ScBodyCore.h index b23a44a81..d84d02d8f 100644 --- a/physx/source/simulationcontroller/include/ScBodyCore.h +++ b/physx/source/simulationcontroller/include/ScBodyCore.h @@ -34,29 +34,15 @@ #include "PxRigidDynamic.h" #include "PxvDynamics.h" #include "PxvConfig.h" -#include "foundation/PxPool.h" namespace physx { -class PxRigidBodyDesc; - namespace Sc { class BodySim; - struct SimStateData; class BodyCore : public RigidCore { - //= 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. - //================================================================================================== - - //--------------------------------------------------------------------------------- - // Construction, destruction & initialization - //--------------------------------------------------------------------------------- public: // PX_SERIALIZATION BodyCore(const PxEMPTY) : RigidCore(PxEmpty), mCore(PxEmpty) {} @@ -91,10 +77,10 @@ namespace Sc PX_FORCE_INLINE const PxTransform& getBody2Actor() const { return mCore.getBody2Actor(); } void setBody2Actor(const PxTransform& p); - void addSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc); - void setSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc); + void addSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc); + void setSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc); void clearSpatialAcceleration(bool force, bool torque); - void addSpatialVelocity(PxPool* simStateDataPool, const PxVec3* linVelDelta, const PxVec3* angVelDelta); + void addSpatialVelocity(const PxVec3* linVelDelta, const PxVec3* angVelDelta); void clearSpatialVelocity(bool force, bool torque); PX_FORCE_INLINE PxReal getMaxPenetrationBias() const { return mCore.maxPenBias; } @@ -112,7 +98,7 @@ namespace Sc void setAngularDamping(PxReal d); PX_FORCE_INLINE PxRigidBodyFlags getFlags() const { return mCore.mFlags; } - void setFlags(PxPool* simStateDataPool, PxRigidBodyFlags f); + void setFlags(PxRigidBodyFlags f); PX_FORCE_INLINE PxRigidDynamicLockFlags getRigidDynamicLockFlags() const { return mCore.lockFlags; } @@ -184,7 +170,7 @@ namespace Sc return *reinterpret_cast(reinterpret_cast(&core) - getCoreOffset()); } - void setKinematicLink(const bool value); + void setFixedBaseLink(bool value); private: PX_ALIGN_PREFIX(16) PxsBodyCore mCore PX_ALIGN_SUFFIX(16); }; diff --git a/physx/source/geomutils/src/distance/GuDistanceSegmentSegmentSIMD.h b/physx/source/simulationcontroller/include/ScBroadphase.h similarity index 63% rename from physx/source/geomutils/src/distance/GuDistanceSegmentSegmentSIMD.h rename to physx/source/simulationcontroller/include/ScBroadphase.h index 3c68e3f91..279f775b4 100644 --- a/physx/source/geomutils/src/distance/GuDistanceSegmentSegmentSIMD.h +++ b/physx/source/simulationcontroller/include/ScBroadphase.h @@ -26,31 +26,46 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef GU_DISTANCE_SEGMENT_SEGMENT_SIMD_H -#define GU_DISTANCE_SEGMENT_SEGMENT_SIMD_H +#ifndef SC_BROADPHASE_H +#define SC_BROADPHASE_H -#include "common/PxPhysXCommonConfig.h" -#include "foundation/PxVecMath.h" +#include "PxvConfig.h" +#include "foundation/PxArray.h" + +// PT: this class captures parts of the Sc::Scene that deals with broadphase matters. namespace physx { -namespace Gu + class PxBroadPhaseCallback; + +namespace Bp +{ + class AABBManagerBase; +} + +namespace Sc { - PX_PHYSX_COMMON_API aos::FloatV distanceSegmentSegmentSquared( const aos::Vec3VArg p1, const aos::Vec3VArg d1, const aos::Vec3VArg p2, const aos::Vec3VArg d2, - aos::FloatV& param0, - aos::FloatV& param1); - - /* - This function do four segment segment closest point test in one go - */ - aos::Vec4V distanceSegmentSegmentSquared4( const aos::Vec3VArg p, const aos::Vec3VArg d, - const aos::Vec3VArg p02, const aos::Vec3VArg d02, - const aos::Vec3VArg p12, const aos::Vec3VArg d12, - const aos::Vec3VArg p22, const aos::Vec3VArg d22, - const aos::Vec3VArg p32, const aos::Vec3VArg d32, - aos::Vec4V& s, aos::Vec4V& t); -} // namespace Gu + class ObjectIDTracker; + + class BroadphaseManager + { + public: + BroadphaseManager(); + ~BroadphaseManager(); + PX_FORCE_INLINE void setBroadPhaseCallback(PxBroadPhaseCallback* callback) { mBroadPhaseCallback = callback; } + PX_FORCE_INLINE PxBroadPhaseCallback* getBroadPhaseCallback() const { return mBroadPhaseCallback; } + + void prepareOutOfBoundsCallbacks(Bp::AABBManagerBase* aabbManager); + bool fireOutOfBoundsCallbacks(Bp::AABBManagerBase* aabbManager, const ObjectIDTracker& tracker); + + void flush(Bp::AABBManagerBase* aabbManager); + + PxBroadPhaseCallback* mBroadPhaseCallback; + PxArray mOutOfBoundsIDs; + }; + +} } #endif diff --git a/physx/source/simulationcontroller/include/ScConstraintCore.h b/physx/source/simulationcontroller/include/ScConstraintCore.h index a96432736..6f826897d 100644 --- a/physx/source/simulationcontroller/include/ScConstraintCore.h +++ b/physx/source/simulationcontroller/include/ScConstraintCore.h @@ -33,7 +33,6 @@ namespace physx { - class PxsSimulationController; namespace Sc { class ConstraintSim; @@ -41,12 +40,6 @@ namespace Sc class ConstraintCore { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION ConstraintCore(const PxEMPTY) : mFlags(PxEmpty), mConnector(NULL), mSim(NULL) {} @@ -54,7 +47,6 @@ namespace Sc { mConnector = &n; mSolverPrep = shaders.solverPrep; - mProject = shaders.project; mVisualize = shaders.visualize; } static void getBinaryMetaData(PxOutputStream& stream); @@ -86,7 +78,6 @@ namespace Sc void breakApart(); PX_FORCE_INLINE PxConstraintVisualize getVisualize() const { return mVisualize; } - PX_FORCE_INLINE PxConstraintProject getProject() const { return mProject; } PX_FORCE_INLINE PxConstraintSolverPrep getSolverPrep() const { return mSolverPrep; } PX_FORCE_INLINE PxU32 getConstantBlockSize() const { return mDataSize; } @@ -111,7 +102,6 @@ namespace Sc PxVec3 mAppliedTorque; PxConstraintConnector* mConnector; - PxConstraintProject mProject; PxConstraintSolverPrep mSolverPrep; PxConstraintVisualize mVisualize; PxU32 mDataSize; diff --git a/physx/source/simulationcontroller/include/ScFEMClothCore.h b/physx/source/simulationcontroller/include/ScFEMClothCore.h index 98dc6d44f..3217bb2a6 100644 --- a/physx/source/simulationcontroller/include/ScFEMClothCore.h +++ b/physx/source/simulationcontroller/include/ScFEMClothCore.h @@ -26,11 +26,11 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_PHYSICS_SCP_FEMCLOTH_CORE #define PX_PHYSICS_SCP_FEMCLOTH_CORE #include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION #include "PxFEMCloth.h" #endif @@ -48,21 +48,9 @@ namespace physx namespace Sc { class FEMClothSim; - //class BodyCore; class FEMClothCore : public ActorCore { - //= 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. - //================================================================================================== - - //--------------------------------------------------------------------------------- - // Construction, destruction & initialization - //--------------------------------------------------------------------------------- - // PX_SERIALIZATION public: FEMClothCore(const PxEMPTY) : ActorCore(PxEmpty) {} @@ -75,8 +63,6 @@ namespace physx //--------------------------------------------------------------------------------- // External API //--------------------------------------------------------------------------------- - //void commit(PxBuffer& positionInvMassBuf, const PxTransform& transform, const PxReal density, const PxReal scale, const PxReal maxInvMass); - PxFEMParameters getParameter() const; void setParameter(const PxFEMParameters& paramters); @@ -100,6 +86,7 @@ namespace physx const PxVec4& triBarycentric); void removeClothAttachment(Sc::FEMClothCore* otherCore, PxU32 handle); +#if 0 // disabled until future use. void setDrag(const PxReal v) { mCore.drag = v; } PxReal getDrag() const { return mCore.drag; } @@ -112,6 +99,10 @@ namespace physx void setAirDensity(const float airDensity) { mCore.airDensity = airDensity; } PxReal getAirDensity() const { return mCore.airDensity; } + void setBendingActivationAngle(const PxReal angle) { mCore.mBendingActivationAngle = angle; } + PxReal getBendingActivationAngle() const { return mCore.mBendingActivationAngle; } +#endif + void setBendingScales(const PxReal* const bendingScales, PxU32 nbElements); const PxReal* getBendingScales() const; PxU32 getNbBendingScales() const { return mCore.mBendingScales.size(); } @@ -119,8 +110,8 @@ namespace physx void setMaxVelocity(const float maxVelocity) { mCore.maxVelocity = maxVelocity; } PxReal getMaxVelocity() const { return mCore.maxVelocity; } - void setBendingActivationAngle(const PxReal angle) { mCore.mBendingActivationAngle = angle; } - PxReal getBendingActivationAngle() const { return mCore.mBendingActivationAngle; } + void setMaxDepenetrationVelocity(const float maxDepenetrationVelocity) { mCore.maxDepenetrationVelocity = maxDepenetrationVelocity; } + PxReal getMaxDepenetrationVelocity() const { return mCore.maxDepenetrationVelocity; } void setNbCollisionPairUpdatesPerTimestep(const PxU32 frequency) { mCore.NbCollisionPairUpdatesPerTimestep = frequency; } PxU32 getNbCollisionPairUpdatesPerTimestep() const { return mCore.NbCollisionPairUpdatesPerTimestep; } @@ -162,13 +153,9 @@ namespace physx #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION PxFEMClothFlags getFlags() const { return mCore.mFlags; } - void setFlags(PxFEMClothFlags flags) { mCore.mFlags = flags; } + void setFlags(PxFEMClothFlags flags); #endif - PxReal getRestVolumeScale() const { return mCore.mRestVolumeScale; } - - void setRestVolumeScale(PxReal scale) { mCore.mRestVolumeScale = scale; } - PX_FORCE_INLINE PxU64& getGpuMemStat() { return mGpuMemStat; } void onShapeChange(ShapeCore& shape, ShapeChangeNotifyFlags notifyFlags); @@ -181,5 +168,6 @@ namespace physx } // namespace Sc } +#endif #endif diff --git a/physx/source/simulationcontroller/include/ScHairSystemCore.h b/physx/source/simulationcontroller/include/ScHairSystemCore.h index ab5c51dc8..1bd10e311 100644 --- a/physx/source/simulationcontroller/include/ScHairSystemCore.h +++ b/physx/source/simulationcontroller/include/ScHairSystemCore.h @@ -27,83 +27,78 @@ #ifndef SC_HAIR_SYSTEM_CORE_H #define SC_HAIR_SYSTEM_CORE_H -#include "PxHairSystemFlag.h" -#include "DyHairSystemCore.h" -#include "ScHairSystemShapeCore.h" - -#include "foundation/PxAssert.h" +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "ScActorCore.h" +#include "ScHairSystemShapeCore.h" +#include "DyHairSystem.h" namespace physx { - namespace Sc - { - class HairSystemSim; - class BodyCore; - - class HairSystemCore : public ActorCore - { - //= 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_SERIALIZATION - public: - HairSystemCore(const PxEMPTY) : ActorCore(PxEmpty) {} - static void getBinaryMetaData(PxOutputStream& stream); - //~PX_SERIALIZATION - HairSystemCore(); - ~HairSystemCore(); - - //--------------------------------------------------------------------------------- - // External API - //--------------------------------------------------------------------------------- - void setMaterial(const PxU16 handle); - void clearMaterials(); - - PxReal getContactOffset() const; - void setContactOffset(PxReal v); - - PxReal getSleepThreshold() const { return mShapeCore.getLLCore().mSleepThreshold; } - void setSleepThreshold(const PxReal v); - - PxU16 getSolverIterationCounts() const { return mShapeCore.getLLCore().mSolverIterationCounts; } - void setSolverIterationCounts(PxU16 c); - - PxReal getWakeCounter() const { return mShapeCore.getLLCore().mWakeCounter; } - void setWakeCounter(const PxReal v); - - bool isSleeping() const; - void wakeUp(PxReal wakeCounter); - void putToSleep(); - - PxActor* getPxActor() const; - - void addRigidAttachment(const Sc::BodyCore* core); - void removeRigidAttachment(const Sc::BodyCore* core); - - - //--------------------------------------------------------------------------------- - // Internal API - //--------------------------------------------------------------------------------- - public: - - HairSystemSim* getSim() const; - - PX_FORCE_INLINE const HairSystemShapeCore& getShapeCore() const { return mShapeCore; } - PX_FORCE_INLINE HairSystemShapeCore& getShapeCore() { return mShapeCore; } - - PxHairSystemFlags getFlags() const { return PxHairSystemFlags(mShapeCore.getLLCore().mParams.mFlags); } - - void setFlags(PxHairSystemFlags flags); - - private: - HairSystemShapeCore mShapeCore; - }; - } // namespace Sc +namespace Sc +{ +class HairSystemSim; +class BodySim; +class SoftBodySim; + +class HairSystemCore : public ActorCore +{ + // PX_SERIALIZATION + public: + HairSystemCore(const PxEMPTY) : ActorCore(PxEmpty) {} + static void getBinaryMetaData(PxOutputStream& stream); + //~PX_SERIALIZATION + + HairSystemCore(); + ~HairSystemCore(); + + //--------------------------------------------------------------------------------- + // External API + //--------------------------------------------------------------------------------- + void setMaterial(const PxU16 handle); + void clearMaterials(); + + PxReal getContactOffset() const; + void setContactOffset(PxReal v); + + PxReal getSleepThreshold() const { return mShapeCore.getLLCore().mSleepThreshold; } + void setSleepThreshold(const PxReal v); + + PxU16 getSolverIterationCounts() const { return mShapeCore.getLLCore().mSolverIterationCounts; } + void setSolverIterationCounts(PxU16 c); + + PxReal getWakeCounter() const { return mShapeCore.getLLCore().mWakeCounter; } + void setWakeCounter(const PxReal v); + + bool isSleeping() const; + void wakeUp(PxReal wakeCounter); + void putToSleep(); + + PxActor* getPxActor() const; + + void addAttachment(const BodySim& bodySim); + void removeAttachment(const BodySim& bodySim); + void addAttachment(const SoftBodySim& sbSim); + void removeAttachment(const SoftBodySim& sbSim); + + //--------------------------------------------------------------------------------- + // Internal API + //--------------------------------------------------------------------------------- + public: + HairSystemSim* getSim() const; + + PX_FORCE_INLINE const HairSystemShapeCore& getShapeCore() const { return mShapeCore; } + PX_FORCE_INLINE HairSystemShapeCore& getShapeCore() { return mShapeCore; } + + PxHairSystemFlags getFlags() const { return PxHairSystemFlags(mShapeCore.getLLCore().mParams.mFlags); } + + void setFlags(PxHairSystemFlags flags); + + private: + HairSystemShapeCore mShapeCore; +}; +} // namespace Sc } // namespace physx #endif +#endif diff --git a/physx/source/simulationcontroller/include/ScIterators.h b/physx/source/simulationcontroller/include/ScIterators.h index cb52d83c5..ed14a2ed7 100644 --- a/physx/source/simulationcontroller/include/ScIterators.h +++ b/physx/source/simulationcontroller/include/ScIterators.h @@ -40,7 +40,7 @@ class PxsContactManagerOutputIterator; namespace Sc { class ShapeSimBase; - class Interaction; + class ElementSimInteraction; class ActorSim; struct Contact @@ -87,17 +87,18 @@ namespace Sc }; ContactIterator() {} - explicit ContactIterator(Interaction** first, Interaction** last, PxsContactManagerOutputIterator& outputs): mCurrent(first), mLast(last), mOffset(0), mOutputs(&outputs) + explicit ContactIterator(ElementSimInteraction** first, ElementSimInteraction** last, PxsContactManagerOutputIterator& outputs): mCurrent(first), mLast(last), mOffset(0), mOutputs(&outputs) { - if (!mCurrent) + if ((!first) || (!last) || (first == last)) { + mCurrent = NULL; mLast = NULL; } } Pair* getNextPair(); private: - Interaction** mCurrent; - Interaction** mLast; + ElementSimInteraction** mCurrent; + ElementSimInteraction** mLast; Pair mCurrentPair; PxU32 mOffset; PxsContactManagerOutputIterator* mOutputs; diff --git a/physx/source/simulationcontroller/include/ScParticleSystemCore.h b/physx/source/simulationcontroller/include/ScParticleSystemCore.h index f9c051781..533a5068b 100644 --- a/physx/source/simulationcontroller/include/ScParticleSystemCore.h +++ b/physx/source/simulationcontroller/include/ScParticleSystemCore.h @@ -29,6 +29,8 @@ #ifndef SC_PARTICLESYSTEM_CORE_H #define SC_PARTICLESYSTEM_CORE_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxParticleSystem.h" #include "foundation/PxAssert.h" #include "ScActorCore.h" @@ -37,11 +39,8 @@ #include "DyParticleSystem.h" #include "ScParticleSystemShapeCore.h" - namespace physx { - - namespace Sc { class ParticleSystemSim; @@ -49,21 +48,10 @@ namespace physx class ParticleSystemCore : public ActorCore { - //= 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. - //================================================================================================== - - //--------------------------------------------------------------------------------- - // Construction, destruction & initialization - //--------------------------------------------------------------------------------- - // PX_SERIALIZATION public: ParticleSystemCore(const PxEMPTY) : ActorCore(PxEmpty) {} - static void getBinaryMetaData(PxOutputStream& stream); + static void getBinaryMetaData(PxOutputStream& stream); //~PX_SERIALIZATION ParticleSystemCore(PxActorType::Enum actorType); ~ParticleSystemCore(); @@ -98,9 +86,6 @@ namespace physx PxParticleSystemCallback* getParticleSystemCallback() const; void setParticleSystemCallback(PxParticleSystemCallback* callback); - - PxCustomParticleSystemSolverCallback* getParticleSystemSolverCallback() const; - void setParticleSystemSolverCallback(PxCustomParticleSystemSolverCallback* callback); PxReal getFluidBoundaryDensityScale() const; void setFluidBoundaryDensityScale(const PxReal v); @@ -117,7 +102,6 @@ namespace physx PxU16 getSolverIterationCounts() const { return mShapeCore.getLLCore().solverIterationCounts; } void setSolverIterationCounts(PxU16 c); - PxReal getWakeCounter() const; void setWakeCounter(const PxReal v); void setWakeCounterInternal(const PxReal v); @@ -158,10 +142,6 @@ namespace physx void removeRigidAttachment(Sc::BodyCore* core); - void setPeriodicBoundary(const PxVec3& boundary) { mShapeCore.setPeriodicBoundary(boundary); } - - PxVec3 getPeriodicBoundary() const { return mShapeCore.getPeriodicBoundary(); } - //--------------------------------------------------------------------------------- // Internal API //--------------------------------------------------------------------------------- @@ -176,11 +156,10 @@ namespace physx private: //ParticleSystemSim* mSim; ParticleSystemShapeCore mShapeCore; - }; } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/include/ScPhysics.h b/physx/source/simulationcontroller/include/ScPhysics.h index d755bdb1f..295b2f877 100644 --- a/physx/source/simulationcontroller/include/ScPhysics.h +++ b/physx/source/simulationcontroller/include/ScPhysics.h @@ -94,7 +94,6 @@ namespace Sc ptrdiff_t scPBDParticleSystem2PxActor; ptrdiff_t scFLIPParticleSystem2PxActor; ptrdiff_t scMPMParticleSystem2PxActor; - ptrdiff_t scCustomParticleSystem2PxActor; ptrdiff_t scHairSystem2PxActor; ptrdiff_t scShape2Px; ptrdiff_t scArticulationRC2Px; diff --git a/physx/source/simulationcontroller/include/ScRigidCore.h b/physx/source/simulationcontroller/include/ScRigidCore.h index 731db150d..fea3f6b35 100644 --- a/physx/source/simulationcontroller/include/ScRigidCore.h +++ b/physx/source/simulationcontroller/include/ScRigidCore.h @@ -59,12 +59,6 @@ namespace Sc class RigidCore : public ActorCore { - //= 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. - //================================================================================================== public: PX_FORCE_INLINE PxActor* getPxActor() const diff --git a/physx/source/simulationcontroller/include/ScScene.h b/physx/source/simulationcontroller/include/ScScene.h index 4708319ae..b00919d81 100644 --- a/physx/source/simulationcontroller/include/ScScene.h +++ b/physx/source/simulationcontroller/include/ScScene.h @@ -31,7 +31,6 @@ #include "PxPhysXConfig.h" #include "PxScene.h" -#include "PxSceneDesc.h" #include "PxSimulationEventCallback.h" #include "foundation/PxPool.h" #include "foundation/PxHashSet.h" @@ -43,11 +42,16 @@ #include "ScIterators.h" #include "PxsMaterialManager.h" #include "PxvManager.h" +#include "ScStaticCore.h" #include "ScBodyCore.h" #include "PxAggregate.h" #include "PxsContext.h" #include "PxsIslandSim.h" #include "GuPrunerTypedef.h" +#include "DyContext.h" +#include "ScFiltering.h" +#include "ScBroadphase.h" +#include "ScInteraction.h" #define PX_MAX_DOMINANCE_GROUP 32 @@ -57,20 +61,8 @@ namespace physx { class NpShape; -// PT: TODO: move INVALID_FILTER_PAIR_INDEX out of public API -struct PxFilterInfo -{ - PX_FORCE_INLINE PxFilterInfo() : filterFlags(0), pairFlags(0), filterPairIndex(INVALID_FILTER_PAIR_INDEX) {} - PX_FORCE_INLINE PxFilterInfo(PxFilterFlags filterFlags_) : filterFlags(filterFlags_), pairFlags(0), filterPairIndex(INVALID_FILTER_PAIR_INDEX) {} - - PxFilterFlags filterFlags; - PxPairFlags pairFlags; - PxU32 filterPairIndex; -}; - struct PxTriggerPair; -class PxsIslandManager; class PxsSimulationController; class PxsSimulationControllerCallback; class PxsMemoryManager; @@ -119,11 +111,9 @@ namespace Sc { class ActorSim; class ElementSim; - class Interaction; class ShapeCore; class RigidCore; - class StaticCore; class ConstraintCore; class ArticulationCore; class ArticulationJointCore; @@ -145,14 +135,12 @@ namespace Sc class NPhaseCore; class ConstraintInteraction; - + class ElementSimInteraction; class BodySim; class ShapeSim; class RigidSim; class StaticSim; class ConstraintSim; - struct ConstraintGroupNode; - class ConstraintProjectionManager; struct TriggerPairExtraData; class ObjectIDTracker; class ActorPairReport; @@ -188,21 +176,6 @@ namespace Sc PxInlineArray removedShapes; }; - struct InteractionType - { - enum Enum - { - eOVERLAP = 0, // corresponds to ShapeInteraction - eTRIGGER, // corresponds to TriggerInteraction - eMARKER, // corresponds to ElementInteractionMarker - eTRACKED_IN_SCENE_COUNT, // not a real type, interactions above this limit are tracked in the scene - eCONSTRAINTSHADER, // corresponds to ConstraintInteraction - eARTICULATION, // corresponds to ArticulationJointSim - - eINVALID - }; - }; - struct SceneInternalFlag { enum Enum @@ -248,29 +221,117 @@ namespace Sc PX_NOCOPY(Scene) - //--------------------------------------------------------------------------------- - // External interface - //--------------------------------------------------------------------------------- public: + Scene(const PxSceneDesc& desc, PxU64 contextID); + ~Scene() {} //use release() plz. + + void preAllocate(PxU32 nbStatics, PxU32 nbBodies, PxU32 nbStaticShapes, PxU32 nbDynamicShapes); void release(); - PX_FORCE_INLINE void setGravity(const PxVec3& g) { mGravity = g; mBodyGravityDirty = true; } - PX_FORCE_INLINE PxVec3 getGravity() const { return mGravity; } - PX_FORCE_INLINE void setElapsedTime(const PxReal t) { mDt = t; mOneOverDt = t > 0.0f ? 1.0f/t : 0.0f; } + PX_FORCE_INLINE PxsSimulationController* getSimulationController() { return mSimulationController; } + PX_FORCE_INLINE const PxsSimulationController* getSimulationController() const { return mSimulationController; } + + PX_FORCE_INLINE Bp::AABBManagerBase* getAABBManager() { return mAABBManager; } + PX_FORCE_INLINE const Bp::AABBManagerBase* getAABBManager() const { return mAABBManager; } + PX_FORCE_INLINE PxArray& getCcdBodies() { return mCcdBodies; } + + PX_FORCE_INLINE IG::SimpleIslandManager* getSimpleIslandManager() { return mSimpleIslandManager; } + PX_FORCE_INLINE const IG::SimpleIslandManager* getSimpleIslandManager() const { return mSimpleIslandManager; } + + PX_FORCE_INLINE SimulationStage::Enum getSimulationStage() const { return mSimulationStage; } + PX_FORCE_INLINE void setSimulationStage(SimulationStage::Enum stage) { mSimulationStage = stage; } + + PX_FORCE_INLINE PxPool* getSimStateDataPool() { return mSimStateDataPool; } + PX_FORCE_INLINE PxBitMap& getDirtyShapeSimMap() { return mDirtyShapeSimMap; } + + PX_FORCE_INLINE void setGravity(const PxVec3& g) { mGravity = g; } + PX_FORCE_INLINE const PxVec3& getGravity() const { return mGravity; } + + PX_FORCE_INLINE void setElapsedTime(PxReal t) { mDt = t; mOneOverDt = t > 0.0f ? 1.0f/t : 0.0f; } + PX_FORCE_INLINE PxReal getOneOverDt() const { return mOneOverDt; } +// PX_FORCE_INLINE PxReal getDt() const { return mDt; } + + PX_FORCE_INLINE void setLimits(const PxSceneLimits& limits) { mLimits = limits; } + PX_FORCE_INLINE const PxSceneLimits& getLimits() const { return mLimits; } + + PX_FORCE_INLINE void setBatchRemove(BatchRemoveState* bs) { mBatchRemoveState = bs; } + PX_FORCE_INLINE BatchRemoveState* getBatchRemove() const { return mBatchRemoveState; } + + PX_FORCE_INLINE void setMaxArticulationLinks(const PxU32 maxLinks) { mMaxNbArticulationLinks = maxLinks; } + PX_FORCE_INLINE PxU32 getMaxArticulationLinks() const { return mMaxNbArticulationLinks; } + + // mDynamicsContext wrappers + PX_FORCE_INLINE Dy::Context* getDynamicsContext() { return mDynamicsContext; } + PX_FORCE_INLINE const Dy::Context* getDynamicsContext() const { return mDynamicsContext; } + + PX_FORCE_INLINE void setBounceThresholdVelocity(PxReal t) { mDynamicsContext->setBounceThreshold(-t); } + PX_FORCE_INLINE PxReal getBounceThresholdVelocity() const { return -mDynamicsContext->getBounceThreshold(); } + + PX_FORCE_INLINE PxSolverType::Enum getSolverType() const { return mDynamicsContext->getSolverType(); } + + PX_FORCE_INLINE void setFrictionType(PxFrictionType::Enum model) { mDynamicsContext->setFrictionType(model); } + PX_FORCE_INLINE PxFrictionType::Enum getFrictionType() const { return mDynamicsContext->getFrictionType(); } + + PX_FORCE_INLINE void setSolverBatchSize(PxU32 solverBatchSize) { mDynamicsContext->setSolverBatchSize(solverBatchSize); } + PX_FORCE_INLINE PxU32 getSolverBatchSize() const { return mDynamicsContext->getSolverBatchSize(); } + + PX_FORCE_INLINE void setSolverArticBatchSize(PxU32 solverBatchSize) { mDynamicsContext->setSolverArticBatchSize(solverBatchSize); } + PX_FORCE_INLINE PxU32 getSolverArticBatchSize() const { return mDynamicsContext->getSolverArticBatchSize(); } + + PX_FORCE_INLINE void setCCDMaxSeparation(PxReal separation) { mDynamicsContext->setCCDSeparationThreshold(separation); } + PX_FORCE_INLINE PxReal getCCDMaxSeparation() const { return mDynamicsContext->getCCDSeparationThreshold(); } + + PX_FORCE_INLINE void setMaxBiasCoefficient(PxReal coeff) { mDynamicsContext->setMaxBiasCoefficient(coeff); } + PX_FORCE_INLINE PxReal getMaxBiasCoefficient() const { return mDynamicsContext->getMaxBiasCoefficient(); } - void setBounceThresholdVelocity(const PxReal t); - PxReal getBounceThresholdVelocity() const; + PX_FORCE_INLINE void setFrictionOffsetThreshold(PxReal t) { mDynamicsContext->setFrictionOffsetThreshold(t); } + PX_FORCE_INLINE PxReal getFrictionOffsetThreshold() const { return mDynamicsContext->getFrictionOffsetThreshold(); } - void setPublicFlags(PxSceneFlags flags); - PX_FORCE_INLINE PxSceneFlags getPublicFlags() const { return mPublicFlags; } - PX_FORCE_INLINE PxSceneFlags getFlags() const { return mPublicFlags; } + PX_FORCE_INLINE void setFrictionCorrelationDistance(PxReal t) { mDynamicsContext->setCorrelationDistance(t); } + PX_FORCE_INLINE PxReal getFrictionCorrelationDistance() const { return mDynamicsContext->getCorrelationDistance(); } - PxSolverType::Enum getSolverType() const; + PX_FORCE_INLINE PxReal getLengthScale() const { return mDynamicsContext->getLengthScale(); } - void setFrictionType(PxFrictionType::Enum model); - PxFrictionType::Enum getFrictionType() const; - PX_FORCE_INLINE void setPCM(bool enabled) { mLLContext->setPCM(enabled); } - PX_FORCE_INLINE void setContactCache(bool enabled) { mLLContext->setContactCache(enabled); } + PX_FORCE_INLINE void setDynamicsDirty() { mDynamicsContext->setStateDirty(true); } + //~mDynamicsContext wrappers + + // mLLContext wrappers + PX_FORCE_INLINE PxsContext* getLowLevelContext() { return mLLContext; } + PX_FORCE_INLINE const PxsContext* getLowLevelContext() const { return mLLContext; } + + PX_FORCE_INLINE Cm::FlushPool* getFlushPool() { return &mLLContext->getTaskPool(); } + + PX_FORCE_INLINE void setPCM(bool enabled) { mLLContext->setPCM(enabled); } + PX_FORCE_INLINE void setContactCache(bool enabled) { mLLContext->setContactCache(enabled); } + + PX_FORCE_INLINE void setContactModifyCallback(PxContactModifyCallback* callback) { mLLContext->setContactModifyCallback(callback); } + PX_FORCE_INLINE PxContactModifyCallback* getContactModifyCallback() const { return mLLContext->getContactModifyCallback(); } + + PX_FORCE_INLINE void setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value) + { + mVisualizationParameterChanged = true; + mLLContext->setVisualizationParameter(param, value); + } + + PX_FORCE_INLINE PxReal getVisualizationParameter(PxVisualizationParameter::Enum param) const { return mLLContext->getVisualizationParameter(param); } + PX_FORCE_INLINE void setVisualizationCullingBox(const PxBounds3& box) { mLLContext->setVisualizationCullingBox(box); } + PX_FORCE_INLINE const PxBounds3& getVisualizationCullingBox() const { return mLLContext->getVisualizationCullingBox(); } + PX_FORCE_INLINE PxReal getVisualizationScale() const { return mLLContext->getRenderScale(); } + PX_FORCE_INLINE PxRenderBuffer& getRenderBuffer() { return mLLContext->getRenderBuffer(); } + + PX_FORCE_INLINE void setNbContactDataBlocks(PxU32 blockCount) { mLLContext->getNpMemBlockPool().setBlockCount(blockCount); } + PX_FORCE_INLINE PxU32 getNbContactDataBlocksUsed() const { return mLLContext->getNpMemBlockPool().getUsedBlockCount(); } + PX_FORCE_INLINE PxU32 getMaxNbContactDataBlocksUsed() const { return mLLContext->getNpMemBlockPool().getMaxUsedBlockCount(); } + PX_FORCE_INLINE PxU32 getMaxNbConstraintDataBlocksUsed() const { return mLLContext->getNpMemBlockPool().getPeakConstraintBlockCount(); } + PX_FORCE_INLINE void setScratchBlock(void* addr, PxU32 size) { mLLContext->setScratchBlock(addr, size); } + //~mLLContext wrappers + + PX_FORCE_INLINE void setFlags(PxSceneFlags flags) + { + mPublicFlags = flags; + } + PX_FORCE_INLINE PxSceneFlags getFlags() const { return mPublicFlags; } + PX_FORCE_INLINE bool readInternalFlag(SceneInternalFlag::Enum flag) const { return (mInternalFlags & flag) != 0; } void addStatic(StaticCore&, NpShape*const *shapes, PxU32 nbShapes, size_t shapePtrOffset, PxBounds3* uninflatedBounds); void removeStatic(StaticCore&, PxInlineArray& removedShapes, bool wakeOnLostTouch); @@ -288,25 +349,9 @@ namespace Sc void addBody(PxActor* actor, BatchInsertionState&, PxBounds3* outBounds, bool compound); void finishBatchInsertion(BatchInsertionState&); - // Batch remove helpers - PX_FORCE_INLINE void setBatchRemove(BatchRemoveState* bs) { mBatchRemoveState = bs; } - PX_FORCE_INLINE BatchRemoveState* getBatchRemove() const { return mBatchRemoveState; } - void addConstraint(ConstraintCore&, RigidCore*, RigidCore*); void removeConstraint(ConstraintCore&); - void addSoftBody(SoftBodyCore&); - void removeSoftBody(SoftBodyCore&); - - void addFEMCloth(FEMClothCore&); - void removeFEMCloth(FEMClothCore&); - - void addParticleSystem(ParticleSystemCore&); - void removeParticleSystem(ParticleSystemCore&); - - void addHairSystem(HairSystemCore&); - void removeHairSystem(HairSystemCore&); - void addArticulation(ArticulationCore&, BodyCore& root); void removeArticulation(ArticulationCore&); @@ -324,33 +369,11 @@ namespace Sc void addArticulationSimControl(ArticulationCore& core); void removeArticulationSimControl(ArticulationCore& core); - void addSoftBodySimControl(SoftBodyCore& core); - void removeSoftBodySimControl(SoftBodyCore& core); - void addFEMClothSimControl(FEMClothCore& core); - void removeFEMClothSimControl(FEMClothCore& core); - void addParticleSystemSimControl(ParticleSystemCore& core); - void removeParticleSystemSimControl(ParticleSystemCore& core); - void addHairSystemSimControl(HairSystemCore& core); - void removeHairSystemSimControl(HairSystemCore& core); void updateBodySim(BodySim& sim); PX_FORCE_INLINE PxU32 getNbArticulations() const { return mArticulations.size(); } PX_FORCE_INLINE ArticulationCore* const* getArticulations() { return mArticulations.getEntries(); } - -#if PX_SUPPORT_GPU_PHYSX - PX_FORCE_INLINE PxU32 getNbSoftBodies() const { return mSoftBodies.size(); } - PX_FORCE_INLINE SoftBodyCore* const* getSoftBodies() { return mSoftBodies.getEntries(); } - - PX_FORCE_INLINE PxU32 getNbFEMCloths() const { return mFEMCloths.size(); } - PX_FORCE_INLINE FEMClothCore* const* getFEMCloths() { return mFEMCloths.getEntries(); } - - PX_FORCE_INLINE PxU32 getNbParticleSystems() const { return mParticleSystems.size(); } - PX_FORCE_INLINE ParticleSystemCore* const* getParticleSystems() { return mParticleSystems.getEntries(); } - - PX_FORCE_INLINE PxU32 getNbHairSystems() const { return mHairSystems.size(); } - PX_FORCE_INLINE HairSystemCore* const* getHairSystems() { return mHairSystems.getEntries(); } -#endif PX_FORCE_INLINE PxU32 getNbConstraints() const { return mConstraints.size(); } PX_FORCE_INLINE ConstraintCore*const* getConstraints() const { return mConstraints.getEntries(); } @@ -358,14 +381,9 @@ namespace Sc void initContactsIterator(ContactIterator&, PxsContactManagerOutputIterator&); - // Simulation events void setSimulationEventCallback(PxSimulationEventCallback* callback); PxSimulationEventCallback* getSimulationEventCallback() const; - // Contact modification - PX_FORCE_INLINE void setContactModifyCallback(PxContactModifyCallback* callback) { mLLContext->setContactModifyCallback(callback); } - PX_FORCE_INLINE PxContactModifyCallback* getContactModifyCallback() const { return mLLContext->getContactModifyCallback(); } - void setCCDContactModifyCallback(PxCCDContactModifyCallback* callback); PxCCDContactModifyCallback* getCCDContactModifyCallback() const; @@ -375,13 +393,9 @@ namespace Sc void setCCDThreshold(PxReal t); PxReal getCCDThreshold() const; - // Broad-phase callback - PX_FORCE_INLINE void setBroadPhaseCallback(PxBroadPhaseCallback* callback) { mBroadPhaseCallback = callback; } - PX_FORCE_INLINE PxBroadPhaseCallback* getBroadPhaseCallback() const { return mBroadPhaseCallback; } - // Broad-phase management void finishBroadPhase(PxBaseTask* continuation); - void finishBroadPhaseStage2(const PxU32 ccdPass); + void finishBroadPhaseStage2(PxU32 ccdPass); void preallocateContactManagers(PxBaseTask* continuation); void islandInsertion(PxBaseTask* continuation); @@ -391,29 +405,9 @@ namespace Sc void secondPassNarrowPhase(PxBaseTask* continuation); - // Groups void setDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2, const PxDominanceGroupPair& dominance); PxDominanceGroupPair getDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2) const; - void setSolverBatchSize(PxU32 solverBatchSize); - PxU32 getSolverBatchSize() const; - - void setSolverArticBatchSize(PxU32 solverBatchSize); - PxU32 getSolverArticBatchSize() const; - - void setDynamicsDirty(); - - PX_FORCE_INLINE void setVisualizationParameter(PxVisualizationParameter::Enum param, PxReal value) - { - mVisualizationParameterChanged = true; - mLLContext->setVisualizationParameter(param, value); - } - - PX_FORCE_INLINE PxReal getVisualizationParameter(PxVisualizationParameter::Enum param) const { return mLLContext->getVisualizationParameter(param); } - PX_FORCE_INLINE void setVisualizationCullingBox(const PxBounds3& box) { mLLContext->setVisualizationCullingBox(box); } - PX_FORCE_INLINE const PxBounds3& getVisualizationCullingBox() const { return mLLContext->getVisualizationCullingBox(); } - PX_FORCE_INLINE PxReal getVisualizationScale() const { return mLLContext->getRenderScale(); } - // Run void simulate(PxReal timeStep, PxBaseTask* continuation); void advance(PxReal timeStep, PxBaseTask* continuation); @@ -428,39 +422,15 @@ namespace Sc const PxArray& getQueuedContactPairHeaders(); - bool fireOutOfBoundsCallbacks(); - void prepareOutOfBoundsCallbacks(); void postCallbacksPreSync(); + void postCallbacksPreSyncKinematics(); void postReportsCleanup(); void fireCallbacksPostSync(); void syncSceneQueryBounds(SqBoundsSync& sync, SqRefFinder& finder); PxU32 getDefaultContactReportStreamBufferSize() const; - void setCCDMaxSeparation(PxReal separation); - PxReal getCCDMaxSeparation() const; - void setMaxBiasCoefficient(PxReal coeff); - PxReal getMaxBiasCoefficient() const; - void setFrictionOffsetThreshold(PxReal t); - PxReal getFrictionOffsetThreshold() const; - void setFrictionCorrelationDistance(PxReal t); - PxReal getFrictionCorrelationDistance() const; - - PX_FORCE_INLINE void setLimits(const PxSceneLimits& limits) { mLimits = limits; } - PX_FORCE_INLINE const PxSceneLimits& getLimits() const { return mLimits; } - void visualizeStartStep(); - PX_FORCE_INLINE PxRenderBuffer& getRenderBuffer() { return mLLContext->getRenderBuffer(); } - - void setNbContactDataBlocks(PxU32 blockCount); - PxU32 getNbContactDataBlocksUsed() const; - PxU32 getMaxNbContactDataBlocksUsed() const; - PxU32 getMaxNbConstraintDataBlocksUsed() const; - - void setMaxArticulationLinks(const PxU32 maxLinks) { mMaxNbArticulationLinks = maxLinks; } - PxU32 getMaxArticulationLinks() const { return mMaxNbArticulationLinks; } - - void setScratchBlock(void* addr, PxU32 size); // PX_ENABLE_SIM_STATS void getStats(PxSimulationStatistics& stats) const; @@ -472,12 +442,6 @@ namespace Sc PxActor** getActiveActors(PxU32& nbActorsOut); void setActiveActors(PxActor** actors, PxU32 nbActors); - PxActor** getActiveSoftBodyActors(PxU32& nbActorsOut); - void setActiveSoftBodyActors(PxActor** actors, PxU32 nbActors); - - //PxActor** getActiveFEMClothActors(PxU32& nbActorsOut); - //void setActiveFEMClothActors(PxActor** actors, PxU32 nbActors); - PxActor** getFrozenActors(PxU32& nbActorsOut); void finalizeContactStreamAndCreateHeader(PxContactPairHeader& header, @@ -489,40 +453,9 @@ namespace Sc void shiftOrigin(const PxVec3& shift); - PX_FORCE_INLINE PxPool* getSimStateDataPool() { return mSimStateDataPool; } - - PX_FORCE_INLINE bool isCollisionPhaseActive() const { return mIsCollisionPhaseActive; } - PX_FORCE_INLINE void setCollisionPhaseToActive() { PX_ASSERT(!mIsCollisionPhaseActive); mIsCollisionPhaseActive = true; } - PX_FORCE_INLINE void setCollisionPhaseToInactive() { PX_ASSERT(mIsCollisionPhaseActive); mIsCollisionPhaseActive = false; } - - //--------------------------------------------------------------------------------- - // Miscellaneous - //--------------------------------------------------------------------------------- - //internal public methods: - public: - Scene(const PxSceneDesc& desc, PxU64 contextID); - ~Scene() {} //use release() plz. - - void preAllocate(PxU32 nbStatics, PxU32 nbBodies, PxU32 nbStaticShapes, PxU32 nbDynamicShapes); - - PX_FORCE_INLINE PxsContext* getLowLevelContext() { return mLLContext; } - PX_FORCE_INLINE const PxsContext* getLowLevelContext() const { return mLLContext; } - - PX_FORCE_INLINE Dy::Context* getDynamicsContext() { return mDynamicsContext; } - PX_FORCE_INLINE const Dy::Context* getDynamicsContext() const { return mDynamicsContext; } - - PX_FORCE_INLINE PxsSimulationController* getSimulationController() { return mSimulationController; } - PX_FORCE_INLINE const PxsSimulationController* getSimulationController() const { return mSimulationController; } - - PX_FORCE_INLINE Bp::AABBManagerBase* getAABBManager() { return mAABBManager; } - PX_FORCE_INLINE const Bp::AABBManagerBase* getAABBManager() const { return mAABBManager; } - PX_FORCE_INLINE PxArray& getCcdBodies() { return mCcdBodies; } - - PX_FORCE_INLINE IG::SimpleIslandManager* getSimpleIslandManager() { return mSimpleIslandManager; } - PX_FORCE_INLINE const IG::SimpleIslandManager* getSimpleIslandManager() const { return mSimpleIslandManager; } - - PX_FORCE_INLINE SimulationStage::Enum getSimulationStage() const { return mSimulationStage; } - PX_FORCE_INLINE void setSimulationStage(SimulationStage::Enum stage) { mSimulationStage = stage; } + PX_FORCE_INLINE bool isCollisionPhaseActive() const { return mIsCollisionPhaseActive; } + PX_FORCE_INLINE void setCollisionPhaseToActive() { PX_ASSERT(!mIsCollisionPhaseActive); mIsCollisionPhaseActive = true; } + PX_FORCE_INLINE void setCollisionPhaseToInactive() { PX_ASSERT(mIsCollisionPhaseActive); mIsCollisionPhaseActive = false; } void addShape_(RigidSim&, ShapeCore&); void removeShape_(ShapeSim&, bool wakeOnLostTouch); @@ -536,28 +469,17 @@ namespace Sc PX_FORCE_INLINE BodyCore*const* getActiveBodiesArray() const { return mActiveBodies.begin(); } PX_FORCE_INLINE PxU32 getNumActiveBodies() const { return mActiveBodies.size(); } -#if PX_SUPPORT_GPU_PHYSX - PX_FORCE_INLINE SoftBodyCore*const* getActiveSoftBodiesArray() const { return mActiveSoftBodies.begin(); } - PX_FORCE_INLINE PxU32 getNumActiveSoftBodies() const { return mActiveSoftBodies.size(); } - - PX_FORCE_INLINE FEMClothCore*const* getActiveFEMClothsArray() const { return mActiveFEMCloths.begin(); } - PX_FORCE_INLINE PxU32 getNumActiveFEMCloths() const { return mActiveFEMCloths.size(); } - - PX_FORCE_INLINE HairSystemCore*const* getActiveHairSystemsArray() const { return mActiveHairSystems.begin(); } - PX_FORCE_INLINE PxU32 getNumActiveHairSystems() const { return mActiveHairSystems.size(); } -#endif - PX_FORCE_INLINE BodyCore*const* getActiveCompoundBodiesArray() const { return mActiveCompoundBodies.begin(); } PX_FORCE_INLINE PxU32 getNumActiveCompoundBodies() const { return mActiveCompoundBodies.size(); } PX_FORCE_INLINE PxU32 getNbInteractions(InteractionType::Enum type) const { return mInteractions[type].size(); } PX_FORCE_INLINE PxU32 getNbActiveInteractions(InteractionType::Enum type) const { return mActiveInteractionCount[type]; } // Get all interactions of a certain type - PX_FORCE_INLINE Interaction** getInteractions(InteractionType::Enum type) { return mInteractions[type].begin(); } - PX_FORCE_INLINE Interaction** getActiveInteractions(InteractionType::Enum type) { return mInteractions[type].begin(); } + PX_FORCE_INLINE ElementSimInteraction** getInteractions(InteractionType::Enum type) { return mInteractions[type].begin(); } + PX_FORCE_INLINE ElementSimInteraction** getActiveInteractions(InteractionType::Enum type) { return mInteractions[type].begin(); } - void registerInteraction(Interaction* interaction, bool active); - void unregisterInteraction(Interaction* interaction); + void registerInteraction(ElementSimInteraction* interaction, bool active); + void unregisterInteraction(ElementSimInteraction* interaction); void notifyInteractionActivated(Interaction* interaction); void notifyInteractionDeactivated(Interaction* interaction); @@ -578,20 +500,8 @@ namespace Sc // Get the active non-kinematic actors PX_FORCE_INLINE BodyCore*const* getActiveDynamicBodies() const { return mActiveBodies.begin() + mActiveKinematicBodyCount; } -#if PX_SUPPORT_GPU_PHYSX - // Get the active soft body actors - PX_FORCE_INLINE SoftBodyCore*const* getActiveSoftBodies() const { return mActiveSoftBodies.begin(); } - - // Get the active FEM-cloth actors - PX_FORCE_INLINE FEMClothCore*const* getActiveFEMCloths() const { return mActiveFEMCloths.begin(); } -#endif - void swapInteractionArrayIndices(PxU32 id1, PxU32 id2, InteractionType::Enum type); public: - PxReal getLengthScale() const; - - PX_FORCE_INLINE PxBitMap& getDirtyShapeSimMap() { return mDirtyShapeSimMap; } - void addDirtyArticulationSim(ArticulationSim* artiSim); void removeDirtyArticulationSim(ArticulationSim* artiSim); @@ -600,14 +510,11 @@ namespace Sc void removeFromActiveCompoundBodyList(BodySim& actor); void swapInActiveBodyList(BodySim& body); // call when an active body gets switched from dynamic to kinematic or vice versa - void addBrokenConstraint(ConstraintCore*); void addActiveBreakableConstraint(ConstraintSim*, ConstraintInteraction*); void removeActiveBreakableConstraint(ConstraintSim*); //the Actor should register its top level shapes with these. void removeBody(BodySim&); - void raiseSceneFlag(SceneInternalFlag::Enum flag) { mInternalFlags |= flag; } - //lists of actors woken up or put to sleep last simulate void onBodyWakeUp(BodySim* body); void onBodySleep(BodySim* body); @@ -623,43 +530,18 @@ namespace Sc Dy::FeatherstoneArticulation* createLLArticulation(ArticulationSim* sim); void destroyLLArticulation(Dy::FeatherstoneArticulation&); -#if PX_SUPPORT_GPU_PHYSX - Dy::SoftBody* createLLSoftBody(SoftBodySim* sim); - void destroyLLSoftBody(Dy::SoftBody& softBody); - - Dy::FEMCloth* createLLFEMCloth(FEMClothSim* sim); - void destroyLLFEMCloth(Dy::FEMCloth& femCloth); - - Dy::ParticleSystem* createLLParticleSystem(ParticleSystemSim* sim); - void destroyLLParticleSystem(Dy::ParticleSystem& softBody); - - Dy::HairSystem* createLLHairSystem(HairSystemSim* sim); - void destroyLLHairSystem(Dy::HairSystem& hairSystem); -#endif - PX_FORCE_INLINE PxPool* getConstraintInteractionPool() const { return mConstraintInteractionPool; } public: PX_FORCE_INLINE const PxsMaterialManager& getMaterialManager() const { return mMaterialManager; } PX_FORCE_INLINE PxsMaterialManager& getMaterialManager() { return mMaterialManager; } -#if PX_SUPPORT_GPU_PHYSX - PX_FORCE_INLINE const PxsFEMMaterialManager& getFEMMaterialManager() const { return mFEMMaterialManager; } - PX_FORCE_INLINE PxsFEMMaterialManager& getFEMMaterialManager() { return mFEMMaterialManager; } - - PX_FORCE_INLINE const PxsFEMClothMaterialManager& getFEMClothMaterialManager() const { return mFEMClothMaterialManager; } - PX_FORCE_INLINE PxsFEMClothMaterialManager& getFEMClothMaterialManager() { return mFEMClothMaterialManager; } - - PX_FORCE_INLINE const PxsPBDMaterialManager& getPBDMaterialManager() const { return mPBDMaterialManager; } - PX_FORCE_INLINE PxsPBDMaterialManager& getPBDMaterialManager() { return mPBDMaterialManager; } - PX_FORCE_INLINE const PxsFLIPMaterialManager& getFLIPMaterialManager() const { return mFLIPMaterialManager; } - PX_FORCE_INLINE PxsFLIPMaterialManager& getFLIPMaterialManager() { return mFLIPMaterialManager; } + PX_FORCE_INLINE const BroadphaseManager& getBroadphaseManager() const { return mBroadphaseManager; } + PX_FORCE_INLINE BroadphaseManager& getBroadphaseManager() { return mBroadphaseManager; } + PX_FORCE_INLINE bool fireOutOfBoundsCallbacks() + { + return mBroadphaseManager.fireOutOfBoundsCallbacks(mAABBManager, *mElementIDPool); + } - PX_FORCE_INLINE const PxsMPMMaterialManager& getMPMMaterialManager() const { return mMPMMaterialManager; } - PX_FORCE_INLINE PxsMPMMaterialManager& getMPMMaterialManager() { return mMPMMaterialManager; } - - PX_FORCE_INLINE const PxsCustomMaterialManager& getCustomMaterialManager() const { return mCustomMaterialManager; } - PX_FORCE_INLINE PxsCustomMaterialManager& getCustomMaterialManager() { return mCustomMaterialManager; } -#endif // Collision filtering void setFilterShaderData(const void* data, PxU32 dataSize); PX_FORCE_INLINE const void* getFilterShaderDataFast() const { return mFilterShaderData; } @@ -672,13 +554,6 @@ namespace Sc PX_FORCE_INLINE PxU32 getTimeStamp() const { return mTimeStamp; } PX_FORCE_INLINE PxU32 getReportShapePairTimeStamp() const { return mReportShapePairTimeStamp; } - PX_FORCE_INLINE PxReal getOneOverDt() const { return mOneOverDt; } - PX_FORCE_INLINE PxReal getDt() const { return mDt; } - - PX_FORCE_INLINE const PxVec3& getGravityFast() const { return mGravity; } - PX_FORCE_INLINE bool readFlag(SceneInternalFlag::Enum flag) const { return (mInternalFlags & flag) != 0; } - PX_FORCE_INLINE bool readPublicFlag(PxSceneFlag::Enum flag) const { return (mPublicFlags & flag); } - PX_FORCE_INLINE NPhaseCore* getNPhaseCore() const { return mNPhaseCore; } void checkConstraintBreakage(); @@ -695,22 +570,14 @@ namespace Sc PX_FORCE_INLINE StaticSim& getStaticAnchor() { return *mStaticAnchor; } - PX_FORCE_INLINE ConstraintProjectionManager& getProjectionManager() { return *mProjectionManager; } - PX_FORCE_INLINE Bp::BoundsArray& getBoundsArray() const { return *mBoundsArray; } PX_FORCE_INLINE void updateContactDistance(PxU32 idx, PxReal distance) { (*mContactDistance)[idx] = distance; mHasContactDistanceChanged = true; } PX_FORCE_INLINE SqBoundsManager& getSqBoundsManager() const { return *mSqBoundsManager; } PX_FORCE_INLINE BodyCore* const* getSleepBodiesArray(PxU32& count) { count = mSleepBodies.size(); return mSleepBodies.getEntries(); } - PX_FORCE_INLINE SoftBodyCore* const* getSleepSoftBodiesArray(PxU32& count) { count = mSleepSoftBodies.size(); return mSleepSoftBodies.getEntries(); } - PX_FORCE_INLINE PxTaskManager& getTaskManager() const { PX_ASSERT(mTaskManager); return *mTaskManager; } - Cm::FlushPool* getFlushPool(); - - PX_FORCE_INLINE bool getStabilizationEnabled() const { return mEnableStabilization; } - PX_FORCE_INLINE void setPostSolverVelocityNeeded() { mContactReportsNeedPostSolverVelocity = true; } PX_FORCE_INLINE ObjectIDTracker& getConstraintIDTracker() { return *mConstraintIDTracker; } @@ -727,11 +594,11 @@ namespace Sc PX_FORCE_INLINE bool isInPosePreviewList(BodySim& b) const { return mPosePreviewBodies.contains(&b); } #endif - PX_FORCE_INLINE void setSpeculativeCCDRigidBody(const PxU32 index) { mSpeculativeCCDRigidBodyBitMap.growAndSet(index); } - PX_FORCE_INLINE void resetSpeculativeCCDRigidBody(const PxU32 index) { if(index < mSpeculativeCCDRigidBodyBitMap.size()) mSpeculativeCCDRigidBodyBitMap.reset(index); } + PX_FORCE_INLINE void setSpeculativeCCDRigidBody(PxU32 index) { mSpeculativeCCDRigidBodyBitMap.growAndSet(index); } + PX_FORCE_INLINE void resetSpeculativeCCDRigidBody(PxU32 index) { if(index < mSpeculativeCCDRigidBodyBitMap.size()) mSpeculativeCCDRigidBodyBitMap.reset(index); } - PX_FORCE_INLINE void setSpeculativeCCDArticulationLink(const PxU32 index) { mSpeculativeCDDArticulationBitMap.growAndSet(index); } - PX_FORCE_INLINE void resetSpeculativeCCDArticulationLink(const PxU32 index) { if(index < mSpeculativeCDDArticulationBitMap.size()) mSpeculativeCDDArticulationBitMap.reset(index); } + PX_FORCE_INLINE void setSpeculativeCCDArticulationLink(PxU32 index) { mSpeculativeCDDArticulationBitMap.growAndSet(index); } + PX_FORCE_INLINE void resetSpeculativeCCDArticulationLink(PxU32 index) { if(index < mSpeculativeCDDArticulationBitMap.size()) mSpeculativeCDDArticulationBitMap.reset(index); } PX_FORCE_INLINE PxU64 getContextId() const { return mContextId; } PX_FORCE_INLINE bool isUsingGpuDynamicsOrBp() const { return mUseGpuBp || mUseGpuDynamics; } @@ -745,75 +612,16 @@ namespace Sc PX_FORCE_INLINE void increaseNumDynamicsCounter() { mNbRigidDynamics++; } PX_FORCE_INLINE void decreaseNumDynamicsCounter() { mNbRigidDynamics--; } - void addParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId); - void removeParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId); - - PxU32 addParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId, const PxVec4& barycentric); - void removeParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 handle); - - void addRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 vertId); - void removeRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 vertId); - - PxU32 addRigidAttachment(BodyCore* core, SoftBodySim& sim, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); - void removeRigidAttachment(BodyCore* core, SoftBodySim& sim, PxU32 handle); - - void addTetRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 tetIdx); - void removeTetRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 tetIdx); - - PxU32 addTetRigidAttachment(BodyCore* core, SoftBodySim& sim, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); - - void addSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1); - void removeSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1); - void addSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize); - void removeSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize); - - PxU32 addSoftBodyAttachment(SoftBodyCore& core, PxU32 tetIdx0, const PxVec4& triBarycentric0, SoftBodySim& sim, PxU32 tetIdx1, const PxVec4& tetBarycentric1, - PxConeLimitedConstraint* constraint); - void removeSoftBodyAttachment(SoftBodyCore& core, SoftBodySim& sim, PxU32 handle); - - void addClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx); - void removeClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx); - - PxU32 addClothAttachment(FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, SoftBodySim& sim, PxU32 tetIdx, const PxVec4& tetBarycentric, - PxConeLimitedConstraint* constraint); - void removeClothAttachment(FEMClothCore& core, SoftBodySim& sim, PxU32 handle); - - void addRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 vertId); - void removeRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 vertId); - - PxU32 addRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); - void removeRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 handle); - - void addClothFilter(FEMClothCore& core0, PxU32 triIdx0, Sc::FEMClothSim& sim1, PxU32 triIdx1); - void removeClothFilter(FEMClothCore& core, PxU32 triIdx0, FEMClothSim& sim1, PxU32 triIdx1); - - PxU32 addTriClothAttachment(FEMClothCore& core0, PxU32 triIdx0, const PxVec4& barycentric0, Sc::FEMClothSim& sim1, PxU32 triIdx1, const PxVec4& barycentric1); - void removeTriClothAttachment(FEMClothCore& core, FEMClothSim& sim1, PxU32 handle); - - void addTriRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 triIdx); - void removeTriRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 triIdx); - - PxU32 addTriRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 triIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); - void removeTriRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 handle); - - void addRigidAttachment(BodyCore* core, ParticleSystemSim& sim); - void removeRigidAttachment(BodyCore* core, ParticleSystemSim& sim); - - void addRigidAttachment(const BodyCore* core, const HairSystemSim& sim); - void removeRigidAttachment(const BodyCore* core, const HairSystemSim& sim); - ConstraintCore* findConstraintCore(const ActorSim* sim0, const ActorSim* sim1); //internal private methods: private: void activateEdgesInternal(const IG::EdgeIndex* activatingEdges, const PxU32 nbActivatingEdges); void releaseConstraints(bool endOfScene); - PX_INLINE void clearBrokenConstraintBuffer(); + PX_INLINE void clearBrokenConstraintBuffer() { mBrokenConstraints.clear(); } ///////////////////////////////////////////////////////////// - void prepareCollide(); - void collideStep(PxBaseTask* continuation); void advanceStep(PxBaseTask* continuation); @@ -822,7 +630,6 @@ namespace Sc void stepSetupSolve(PxBaseTask* continuation); //void stepSetupSimulate(); - void fetchPatchEvents(PxBaseTask*); void processNarrowPhaseTouchEvents(); void processNarrowPhaseTouchEventsStage2(PxBaseTask*); void setEdgesConnected(PxBaseTask*); @@ -833,11 +640,10 @@ namespace Sc void updateKinematicCached(PxBaseTask* task); void beforeSolver(PxBaseTask* continuation); - void checkForceThresholdContactEvents(const PxU32 ccdPass); - void endStep(); + void checkForceThresholdContactEvents(PxU32 ccdPass); private: - void putObjectsToSleep(PxU32 infoFlag); - void wakeObjectsUp(PxU32 infoFlag); + void putObjectsToSleep(); + void wakeObjectsUp(); void collectPostSolverVelocitiesBeforeCCD(); @@ -846,34 +652,12 @@ namespace Sc PX_INLINE void cleanUpWokenBodies(); PX_INLINE void cleanUpSleepOrWokenBodies(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker); -#if PX_SUPPORT_GPU_PHYSX - // PT: TODO: why inline these ones? - PX_INLINE void cleanUpSleepSoftBodies(); - PX_INLINE void cleanUpWokenSoftBodies(); - PX_INLINE void cleanUpSleepOrWokenSoftBodies(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker); - - PX_INLINE void cleanUpSleepHairSystems(); - PX_INLINE void cleanUpWokenHairSystems(); - PX_INLINE void cleanUpSleepOrWokenHairSystems(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker); -#endif - - //internal variables: private: + // Material manager PX_ALIGN(16, PxsMaterialManager mMaterialManager); -#if PX_SUPPORT_GPU_PHYSX - PX_ALIGN(16, PxsFEMMaterialManager mFEMMaterialManager); - - PX_ALIGN(16, PxsFEMClothMaterialManager mFEMClothMaterialManager); - - PX_ALIGN(16, PxsPBDMaterialManager mPBDMaterialManager); - PX_ALIGN(16, PxsFLIPMaterialManager mFLIPMaterialManager); - - PX_ALIGN(16, PxsMPMMaterialManager mMPMMaterialManager); - - PX_ALIGN(16, PxsCustomMaterialManager mCustomMaterialManager); -#endif + BroadphaseManager mBroadphaseManager; PxU64 mContextId; PxArray mActiveBodies; // Sorted: kinematic before dynamic @@ -884,14 +668,12 @@ namespace Sc BodyCore** mActiveKinematicsCopy; PxU32 mActiveKinematicsCopyCapacity; -#if PX_SUPPORT_GPU_PHYSX - PxArray mActiveSoftBodies; - PxArray mActiveFEMCloths; - PxArray mActiveParticleSystems; - PxArray mActiveHairSystems; -#endif - PxArray mInteractions[InteractionType::eTRACKED_IN_SCENE_COUNT]; - PxU32 mActiveInteractionCount[InteractionType::eTRACKED_IN_SCENE_COUNT]; // Interactions with id < activeInteractionCount are active + // PT: this array used for: + // - debug visualization + // - processing trigger interactions + // - updating dirty interactions + PxArray mInteractions[InteractionType::eTRACKED_IN_SCENE_COUNT]; + PxU32 mActiveInteractionCount[InteractionType::eTRACKED_IN_SCENE_COUNT]; // Interactions with id < activeInteractionCount are active template struct Block @@ -915,13 +697,10 @@ namespace Sc PxI32 mNumFastMovingShapes; PxU32 mCCDPass; - //PxsIslandManager* mIslandManager; - IG::SimpleIslandManager* mSimpleIslandManager; Dy::Context* mDynamicsContext; - PxsMemoryManager* mMemoryManager; #if PX_SUPPORT_GPU_PHYSX @@ -936,7 +715,6 @@ namespace Sc PxSceneLimits mLimits; PxVec3 mGravity; //!< Gravity vector - PxU32 mBodyGravityDirty; // Set to true before body->updateForces() when the mGravity has changed PxArray mQueuedContactPairHeaders; @@ -952,26 +730,18 @@ namespace Sc PxCoalescedHashSet mConstraints; - ConstraintProjectionManager* mProjectionManager; Bp::BoundsArray* mBoundsArray; PxFloatArrayPinned* mContactDistance; bool mHasContactDistanceChanged; SqBoundsManager* mSqBoundsManager; PxArray mCcdBodies; - PxArray mProjectedBodies; PxArray mTriggerBufferAPI; PxArray* mTriggerBufferExtraData; PxCoalescedHashSet mArticulations; PxCoalescedHashSet mDirtyArticulationSims; -#if PX_SUPPORT_GPU_PHYSX - PxCoalescedHashSet mSoftBodies; - PxCoalescedHashSet mFEMCloths; - PxCoalescedHashSet mParticleSystems; - PxCoalescedHashSet mHairSystems; -#endif PxArray mBrokenConstraints; PxCoalescedHashSet mActiveBreakableConstraints; @@ -1001,26 +771,13 @@ namespace Sc PxCoalescedHashSet mSleepBodies; PxCoalescedHashSet mWokeBodies; - PxCoalescedHashSet mSleepSoftBodies; - PxCoalescedHashSet mWokeSoftBodies; - PxCoalescedHashSet mSleepHairSystems; - PxCoalescedHashSet mWokeHairSystems; bool mWokeBodyListValid; bool mSleepBodyListValid; - bool mWokeSoftBodyListValid; - bool mSleepSoftBodyListValid; - bool mWokeHairSystemListValid; - bool mSleepHairSystemListValid; const bool mEnableStabilization; PxArray mActiveActors; PxArray mFrozenActors; -#if PX_SUPPORT_GPU_PHYSX - PxArray mActiveSoftBodyActors; - PxArray mActiveFEMClothActors; - PxArray mActiveHairSystemActors; -#endif PxArray mClientPosePreviewBodies; // buffer for bodies that requested early report of the integrated pose (eENABLE_POSE_INTEGRATION_PREVIEW). // This buffer gets exposed to users. Is officially accessible from PxSimulationEventCallback::onAdvance() // until the next simulate()/advance(). @@ -1028,16 +785,17 @@ namespace Sc // to users. PxSimulationEventCallback* mSimulationEventCallback; - PxBroadPhaseCallback* mBroadPhaseCallback; SimStats* mStats; - PxU32 mInternalFlags; //!< Combination of ::SceneFlag - PxSceneFlags mPublicFlags; //copy of PxSceneDesc::flags, of type PxSceneFlag + PxU32 mInternalFlags; // PT: combination of ::SceneInternalFlag, looks like only 2 bits are needed + PxSceneFlags mPublicFlags; // Copy of PxSceneDesc::flags, of type PxSceneFlag - ObjectIDTracker* mConstraintIDTracker; - ObjectIDTracker* mActorIDTracker; - ObjectIDTracker* mElementIDPool; + // PT: TODO: unify names, "tracker" or "pool"? + ObjectIDTracker* mConstraintIDTracker; // PT: provides Sc::ContraintSim::mLowLevelConstraint::index + ObjectIDTracker* mActorIDTracker; // PT: provides Sc::ActorSim::mId + ObjectIDTracker* mElementIDPool; // PT: provides Sc::ElementSim::mElementID + StaticCore mAnchorCore; StaticSim* mStaticAnchor; Cm::PreallocatingPool* mShapeSimPool; @@ -1045,13 +803,6 @@ namespace Sc Cm::PreallocatingPool* mBodySimPool; PxPool* mConstraintSimPool; LLArticulationRCPool* mLLArticulationRCPool; -#if PX_SUPPORT_GPU_PHYSX - LLSoftBodyPool* mLLSoftBodyPool; - LLFEMClothPool* mLLFEMClothPool; - LLParticleSystemPool* mLLParticleSystemPool; - LLHairSystemPool* mLLHairSystemPool; -#endif - PxHashMap, ParticleOrSoftBodyRigidInteraction> mParticleOrSoftBodyRigidInteractionMap; PxHashMap, ConstraintCore*> mConstraintMap; @@ -1070,8 +821,6 @@ namespace Sc PxArray mTouchFoundEvents; PxArray mTouchLostEvents; - PxArray mOutOfBoundsIDs; - PxBitMap mDirtyShapeSimMap; PxU32 mDominanceBitMatrix[PX_MAX_DOMINANCE_GROUP]; @@ -1107,7 +856,6 @@ namespace Sc void processLostSolverPatches(PxBaseTask* continuation); void processFoundSolverPatches(PxBaseTask* continuation); void postIslandGen(PxBaseTask* continuation); - //void processTriggerInteractions(PxBaseTask* continuation); void solver(PxBaseTask* continuation); void updateBodies(PxBaseTask* continuation); void updateShapes(PxBaseTask* continuation); @@ -1140,6 +888,7 @@ namespace Sc private: void addShapes(NpShape*const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& sim, ShapeSim*& prefetchedShapeSim, PxBounds3* outBounds); void updateContactDistances(PxBaseTask* continuation); + void updateDirtyShapes(PxBaseTask* continuation); Cm::DelegateTask mSecondPassNarrowPhase; Cm::DelegateFanoutTask mPostNarrowPhase; @@ -1155,7 +904,6 @@ namespace Sc PxArray > mPostCCDPass; Cm::DelegateTask mAfterIntegration; - Cm::DelegateTask mConstraintProjection; Cm::DelegateTask mPostSolver; Cm::DelegateTask mSolver; Cm::DelegateTask mUpdateBodies; @@ -1177,7 +925,6 @@ namespace Sc Cm::DelegateTask mIslandGen; Cm::DelegateTask mPreRigidBodyNarrowPhase; Cm::DelegateTask mSetEdgesConnectedTask; - Cm::DelegateTask mFetchPatchEventsTask; Cm::DelegateTask mProcessLostPatchesTask; Cm::DelegateTask mProcessFoundPatchesTask; Cm::DelegateFanoutTask mUpdateBoundAndShapeTask; @@ -1211,27 +958,228 @@ namespace Sc SimulationStage::Enum mSimulationStage; - ConstraintGroupNode** mTmpConstraintGroupRootBuffer; // temporary list of constraint group roots, used for constraint projection - PxCoalescedHashSet mPosePreviewBodies; // list of bodies that requested early report of the integrated pose (eENABLE_POSE_INTEGRATION_PREVIEW). PxArray mPreallocatedContactManagers; PxArray mPreallocatedShapeInteractions; PxArray mPreallocatedInteractionMarkers; - OverlapFilterTask* mOverlapFilterTaskHead; - PxArray mFilterInfo; - PxBitMap mSpeculativeCCDRigidBodyBitMap; - PxBitMap mSpeculativeCDDArticulationBitMap; + OverlapFilterTask* mOverlapFilterTaskHead; // PT: tmp data passed from finishBroadPhase to preallocateContactManagers + PxArray mFilterInfo; // PT: tmp data passed from finishBroadPhase to preallocateContactManagers - bool mIsCollisionPhaseActive; + PxBitMap mSpeculativeCCDRigidBodyBitMap; + PxBitMap mSpeculativeCDDArticulationBitMap; + + bool mIsCollisionPhaseActive; // Set to true as long as collision phase is active (used as an indicator that it is OK to read object pose, // velocity etc. compared to the solver phase where these properties might get written to). public: // For OmniPVD. To notify NpScene that actor's sleeping state has changed. - typedef void(*SleepingStateChangedCallback)(PxActor*, bool); + typedef void(*SleepingStateChangedCallback)(PxRigidDynamic&, bool); SleepingStateChangedCallback mOnSleepingStateChanged; + +// PT: moved all the GPU-related code & data here in an attempt to clearly separate the CPU/GPU bits +#if PX_SUPPORT_GPU_PHYSX + public: + void gpu_addToActiveList(ActorSim& actorSim, ActorCore* appendedActorCore); + void gpu_removeFromActiveList(ActorSim& actorSim, PxU32 removedActiveIndex); + void gpu_clearSleepWakeBodies(); + void gpu_buildActiveActors(); + void gpu_buildActiveAndFrozenActors(); + void gpu_setSimulationEventCallback(PxSimulationEventCallback* callback); + PxU32 gpu_cleanUpSleepAndWokenBodies(); + void gpu_fireOnSleepCallback(PxActor** actors); + void gpu_fireOnWakeCallback(PxActor** actors); + void gpu_updateBounds(); + void gpu_releasePools(); + void gpu_release(); + + void addSoftBody(SoftBodyCore&); + void removeSoftBody(SoftBodyCore&); + void addFEMCloth(FEMClothCore&); + void removeFEMCloth(FEMClothCore&); + void addParticleSystem(ParticleSystemCore&); + void removeParticleSystem(ParticleSystemCore&); + void addHairSystem(HairSystemCore&); + void removeHairSystem(HairSystemCore&); + + PX_FORCE_INLINE PxU32 getNbSoftBodies() const { return mSoftBodies.size(); } + PX_FORCE_INLINE SoftBodyCore* const* getSoftBodies() { return mSoftBodies.getEntries(); } + + PX_FORCE_INLINE PxU32 getNbFEMCloths() const { return mFEMCloths.size(); } + PX_FORCE_INLINE FEMClothCore* const* getFEMCloths() { return mFEMCloths.getEntries(); } + + PX_FORCE_INLINE PxU32 getNbParticleSystems() const { return mParticleSystems.size(); } + PX_FORCE_INLINE ParticleSystemCore* const* getParticleSystems() { return mParticleSystems.getEntries(); } + + PX_FORCE_INLINE PxU32 getNbHairSystems() const { return mHairSystems.size(); } + PX_FORCE_INLINE HairSystemCore* const* getHairSystems() { return mHairSystems.getEntries(); } + + PX_FORCE_INLINE SoftBodyCore*const* getActiveSoftBodiesArray() const { return mActiveSoftBodies.begin(); } + PX_FORCE_INLINE PxU32 getNumActiveSoftBodies() const { return mActiveSoftBodies.size(); } + + PX_FORCE_INLINE FEMClothCore*const* getActiveFEMClothsArray() const { return mActiveFEMCloths.begin(); } + PX_FORCE_INLINE PxU32 getNumActiveFEMCloths() const { return mActiveFEMCloths.size(); } + + PX_FORCE_INLINE HairSystemCore*const* getActiveHairSystemsArray() const { return mActiveHairSystems.begin(); } + PX_FORCE_INLINE PxU32 getNumActiveHairSystems() const { return mActiveHairSystems.size(); } + + // PT: redundant? + // Get the active soft body actors + PX_FORCE_INLINE SoftBodyCore*const* getActiveSoftBodies() const { return mActiveSoftBodies.begin(); } + + PX_FORCE_INLINE SoftBodyCore*const* getSleepSoftBodiesArray(PxU32& count) { count = mSleepSoftBodies.size(); return mSleepSoftBodies.getEntries(); } + + // PT: redundant? + // Get the active FEM-cloth actors + PX_FORCE_INLINE FEMClothCore*const* getActiveFEMCloths() const { return mActiveFEMCloths.begin(); } + + PX_FORCE_INLINE const PxsFEMMaterialManager& getFEMMaterialManager() const { return mFEMMaterialManager; } + PX_FORCE_INLINE PxsFEMMaterialManager& getFEMMaterialManager() { return mFEMMaterialManager; } + + PX_FORCE_INLINE const PxsFEMClothMaterialManager& getFEMClothMaterialManager() const { return mFEMClothMaterialManager; } + PX_FORCE_INLINE PxsFEMClothMaterialManager& getFEMClothMaterialManager() { return mFEMClothMaterialManager; } + + PX_FORCE_INLINE const PxsPBDMaterialManager& getPBDMaterialManager() const { return mPBDMaterialManager; } + PX_FORCE_INLINE PxsPBDMaterialManager& getPBDMaterialManager() { return mPBDMaterialManager; } + + PX_FORCE_INLINE const PxsFLIPMaterialManager& getFLIPMaterialManager() const { return mFLIPMaterialManager; } + PX_FORCE_INLINE PxsFLIPMaterialManager& getFLIPMaterialManager() { return mFLIPMaterialManager; } + + PX_FORCE_INLINE const PxsMPMMaterialManager& getMPMMaterialManager() const { return mMPMMaterialManager; } + PX_FORCE_INLINE PxsMPMMaterialManager& getMPMMaterialManager() { return mMPMMaterialManager; } + + Dy::SoftBody* createLLSoftBody(SoftBodySim* sim); + void destroyLLSoftBody(Dy::SoftBody& softBody); + + Dy::FEMCloth* createLLFEMCloth(FEMClothSim* sim); + void destroyLLFEMCloth(Dy::FEMCloth& femCloth); + + Dy::ParticleSystem* createLLParticleSystem(ParticleSystemSim* sim); + void destroyLLParticleSystem(Dy::ParticleSystem& softBody); + + Dy::HairSystem* createLLHairSystem(HairSystemSim* sim); + void destroyLLHairSystem(Dy::HairSystem& hairSystem); + + // PT: TODO: why inline these ones? + PX_INLINE void cleanUpSleepSoftBodies(); + PX_INLINE void cleanUpWokenSoftBodies(); + PX_INLINE void cleanUpSleepOrWokenSoftBodies(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker); + + PX_INLINE void cleanUpSleepHairSystems(); + PX_INLINE void cleanUpWokenHairSystems(); + PX_INLINE void cleanUpSleepOrWokenHairSystems(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker); + + void addSoftBodySimControl(SoftBodyCore& core); + void removeSoftBodySimControl(SoftBodyCore& core); + void addFEMClothSimControl(FEMClothCore& core); + void removeFEMClothSimControl(FEMClothCore& core); + void addParticleSystemSimControl(ParticleSystemCore& core); + void removeParticleSystemSimControl(ParticleSystemCore& core); + void addHairSystemSimControl(HairSystemCore& core); + void removeHairSystemSimControl(HairSystemCore& core); + + void addParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId); + void removeParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId); + + PxU32 addParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId, const PxVec4& barycentric); + void removeParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 handle); + + void addRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 vertId); + void removeRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 vertId); + + PxU32 addRigidAttachment(BodyCore* core, SoftBodySim& sim, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); + void removeRigidAttachment(BodyCore* core, SoftBodySim& sim, PxU32 handle); + + void addTetRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 tetIdx); + void removeTetRigidFilter(BodyCore* core, SoftBodySim& sim, PxU32 tetIdx); + + PxU32 addTetRigidAttachment(BodyCore* core, SoftBodySim& sim, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); + + void addSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1); + void removeSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1); + void addSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize); + void removeSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize); + + PxU32 addSoftBodyAttachment(SoftBodyCore& core, PxU32 tetIdx0, const PxVec4& triBarycentric0, SoftBodySim& sim, PxU32 tetIdx1, const PxVec4& tetBarycentric1, PxConeLimitedConstraint* constraint, PxReal constraintOffset); + void removeSoftBodyAttachment(SoftBodyCore& core, SoftBodySim& sim, PxU32 handle); + + void addClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx); + void removeClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx); + + PxU32 addClothAttachment(FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, SoftBodySim& sim, PxU32 tetIdx, const PxVec4& tetBarycentric, PxConeLimitedConstraint* constraint, PxReal constraintOffset); + void removeClothAttachment(FEMClothCore& core, SoftBodySim& sim, PxU32 handle); + + void addRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 vertId); + void removeRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 vertId); + + PxU32 addRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); + void removeRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 handle); + + void addClothFilter(FEMClothCore& core0, PxU32 triIdx0, Sc::FEMClothSim& sim1, PxU32 triIdx1); + void removeClothFilter(FEMClothCore& core, PxU32 triIdx0, FEMClothSim& sim1, PxU32 triIdx1); + + PxU32 addTriClothAttachment(FEMClothCore& core0, PxU32 triIdx0, const PxVec4& barycentric0, Sc::FEMClothSim& sim1, PxU32 triIdx1, const PxVec4& barycentric1); + void removeTriClothAttachment(FEMClothCore& core, FEMClothSim& sim1, PxU32 handle); + + void addTriRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 triIdx); + void removeTriRigidFilter(BodyCore* core, FEMClothSim& sim, PxU32 triIdx); + + PxU32 addTriRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 triIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); + void removeTriRigidAttachment(BodyCore* core, FEMClothSim& sim, PxU32 handle); + + void addRigidAttachment(BodyCore* core, ParticleSystemSim& sim); + void removeRigidAttachment(BodyCore* core, ParticleSystemSim& sim); + + void addAttachment(const BodySim& bodySim, const HairSystemSim& hairSim); + void addAttachment(const SoftBodySim& sbSim, const HairSystemSim& hairSim); + void removeAttachment(const BodySim& bodySim, const HairSystemSim& hairSim); + void removeAttachment(const SoftBodySim& sbSim, const HairSystemSim& hairSim); + + PxActor** getActiveSoftBodyActors(PxU32& nbActorsOut); + void setActiveSoftBodyActors(PxActor** actors, PxU32 nbActors); + + //PxActor** getActiveFEMClothActors(PxU32& nbActorsOut); + //void setActiveFEMClothActors(PxActor** actors, PxU32 nbActors); + + PX_ALIGN(16, PxsFEMMaterialManager mFEMMaterialManager); + PX_ALIGN(16, PxsFEMClothMaterialManager mFEMClothMaterialManager); + PX_ALIGN(16, PxsPBDMaterialManager mPBDMaterialManager); + PX_ALIGN(16, PxsFLIPMaterialManager mFLIPMaterialManager); + PX_ALIGN(16, PxsMPMMaterialManager mMPMMaterialManager); + + PxArray mActiveSoftBodies; + PxArray mActiveFEMCloths; + PxArray mActiveParticleSystems; + PxArray mActiveHairSystems; + + PxCoalescedHashSet mSoftBodies; + PxCoalescedHashSet mFEMCloths; + PxCoalescedHashSet mParticleSystems; + PxCoalescedHashSet mHairSystems; + + PxCoalescedHashSet mSleepSoftBodies; + PxCoalescedHashSet mWokeSoftBodies; + PxCoalescedHashSet mSleepHairSystems; + PxCoalescedHashSet mWokeHairSystems; + + PxArray mActiveSoftBodyActors; + PxArray mActiveFEMClothActors; + PxArray mActiveHairSystemActors; + + LLSoftBodyPool* mLLSoftBodyPool; + LLFEMClothPool* mLLFEMClothPool; + LLParticleSystemPool* mLLParticleSystemPool; + LLHairSystemPool* mLLHairSystemPool; + + PxHashMap, ParticleOrSoftBodyRigidInteraction> mParticleOrSoftBodyRigidInteractionMap; + + bool mWokeSoftBodyListValid; + bool mSleepSoftBodyListValid; + bool mWokeHairSystemListValid; + bool mSleepHairSystemListValid; +#endif }; bool activateInteraction(Interaction* interaction, void* data); diff --git a/physx/source/simulationcontroller/include/ScShapeCore.h b/physx/source/simulationcontroller/include/ScShapeCore.h index 6eff5b4f2..f132e5757 100644 --- a/physx/source/simulationcontroller/include/ScShapeCore.h +++ b/physx/source/simulationcontroller/include/ScShapeCore.h @@ -37,6 +37,7 @@ namespace physx { class PxShape; +class PxsSimulationController; namespace Sc { @@ -44,12 +45,6 @@ namespace Sc class ShapeCore { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION ShapeCore(const PxEMPTY); @@ -108,27 +103,28 @@ namespace Sc return *reinterpret_cast(reinterpret_cast(&core) - getCoreOffset()); } - PX_FORCE_INLINE ShapeSim* getSim() const + PX_FORCE_INLINE ShapeSim* getExclusiveSim() const { - return reinterpret_cast(size_t(mSimAndIsExclusive) & ~1); + return mExclusiveSim; } - PX_FORCE_INLINE void setSim(ShapeSim* sim) - { - PX_ASSERT((NULL == mSimAndIsExclusive) || (1 == size_t(mSimAndIsExclusive))); - PX_ASSERT(0 == (size_t(sim) & 1)); - mSimAndIsExclusive = mSimAndIsExclusive ? reinterpret_cast(size_t(sim) | size_t(mSimAndIsExclusive)) : mSimAndIsExclusive; - } - PX_FORCE_INLINE void clearSim() + + PX_FORCE_INLINE void setExclusiveSim(ShapeSim* sim) { - mSimAndIsExclusive = reinterpret_cast(size_t(mSimAndIsExclusive) & 1); + if (!sim || mCore.mShapeCoreFlags.isSet(PxShapeCoreFlag::eIS_EXCLUSIVE)) + { + mExclusiveSim = sim; + } } + PxU32 getInternalShapeIndex(PxsSimulationController& simulationController) const; + + #if PX_WINDOWS_FAMILY // PT: to avoid "error: offset of on non-standard-layout type" on Linux protected: #endif PxFilterData mSimulationFilterData; // Simulation filter data PxsShapeCore PX_ALIGN(16, mCore); - ShapeSim* mSimAndIsExclusive; + ShapeSim* mExclusiveSim; //only set if shape is exclusive #if PX_WINDOWS_FAMILY // PT: to avoid "error: offset of on non-standard-layout type" on Linux public: #endif diff --git a/physx/source/simulationcontroller/include/ScSoftBodyCore.h b/physx/source/simulationcontroller/include/ScSoftBodyCore.h index d2c47f47a..6fd686540 100644 --- a/physx/source/simulationcontroller/include/ScSoftBodyCore.h +++ b/physx/source/simulationcontroller/include/ScSoftBodyCore.h @@ -29,6 +29,8 @@ #ifndef SC_SOFT_BODY_CORE_H #define SC_SOFT_BODY_CORE_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxSoftBody.h" #include "DySoftBodyCore.h" #include "foundation/PxAssert.h" @@ -37,11 +39,8 @@ #include "PxFiltering.h" #include "ScRigidCore.h" //KS - needed for ShapeChangeNotifyFlags. Move to a shared header - namespace physx { - - namespace Sc { class SoftBodySim; @@ -51,21 +50,10 @@ namespace physx class SoftBodyCore : public ActorCore { - //= 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. - //================================================================================================== - - //--------------------------------------------------------------------------------- - // Construction, destruction & initialization - //--------------------------------------------------------------------------------- - // PX_SERIALIZATION public: SoftBodyCore(const PxEMPTY) : ActorCore(PxEmpty){} - static void getBinaryMetaData(PxOutputStream& stream); + static void getBinaryMetaData(PxOutputStream& stream); //~PX_SERIALIZATION SoftBodyCore(); ~SoftBodyCore(); @@ -116,7 +104,6 @@ namespace physx PxU32 addRigidAttachment(Sc::BodyCore* core, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint); void removeRigidAttachment(Sc::BodyCore* core, PxU32 handle); - void addTetRigidFilter(Sc::BodyCore* core, PxU32 tetIdx); void removeTetRigidFilter(Sc::BodyCore* core, PxU32 tetIdx); @@ -129,16 +116,19 @@ namespace physx void removeSoftBodyFilters(Sc::SoftBodyCore& core, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize); PxU32 addSoftBodyAttachment(Sc::SoftBodyCore& core, PxU32 tetIdx0, const PxVec4& triBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1, - PxConeLimitedConstraint* constraint); + PxConeLimitedConstraint* constraint, PxReal constraintOffset); void removeSoftBodyAttachment(Sc::SoftBodyCore& core, PxU32 handle); void addClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, PxU32 tetIdx); void removeClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, PxU32 tetIdx); - PxU32 addClothAttachment(Sc::FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, PxConeLimitedConstraint* constraint); + PxU32 addClothAttachment(Sc::FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, + PxConeLimitedConstraint* constraint, PxReal constraintOffset); void removeClothAttachment(Sc::FEMClothCore& core, PxU32 handle); - PxU32 getGpuSoftBodyIndex(); + PxU32 getGpuSoftBodyIndex() const; + + void setKinematicTargets(const PxVec4* positions, PxSoftBodyFlags flags); //--------------------------------------------------------------------------------- // Internal API //--------------------------------------------------------------------------------- @@ -150,12 +140,6 @@ namespace physx PX_FORCE_INLINE Dy::SoftBodyCore& getCore() { return mCore; } - static PX_FORCE_INLINE SoftBodyCore& getSoftBodyCore(SoftBodyCore& core) - { - size_t offset = PX_OFFSET_OF_RT(SoftBodyCore, mCore); - return *reinterpret_cast(reinterpret_cast(&core) - offset); - } - void setSimulationFilterData(const PxFilterData& data); PxFilterData getSimulationFilterData() const; @@ -175,14 +159,10 @@ namespace physx Dy::SoftBodyCore mCore; PxFilterData mFilterData; PxU64 mGpuMemStat; - - }; - - } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/include/ScStaticCore.h b/physx/source/simulationcontroller/include/ScStaticCore.h index 9804a33c4..8aae90b51 100644 --- a/physx/source/simulationcontroller/include/ScStaticCore.h +++ b/physx/source/simulationcontroller/include/ScStaticCore.h @@ -36,17 +36,10 @@ namespace physx { namespace Sc { - class StaticSim; - class StaticCore: public RigidCore + class StaticCore : public RigidCore { - //= 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. - //================================================================================================== public: StaticCore(const PxTransform& actor2World): RigidCore(PxActorType::eRIGID_STATIC) { diff --git a/physx/source/simulationcontroller/src/ScActorSim.cpp b/physx/source/simulationcontroller/src/ScActorSim.cpp index 8f6977cee..82ac4a679 100644 --- a/physx/source/simulationcontroller/src/ScActorSim.cpp +++ b/physx/source/simulationcontroller/src/ScActorSim.cpp @@ -33,17 +33,71 @@ #include "ScInteraction.h" using namespace physx; +using namespace Sc; + +static const PxFilterObjectType::Enum gFilterType[PxActorType::eACTOR_COUNT] = +{ + PxFilterObjectType::eRIGID_STATIC, // PxActorType::eRIGID_STATIC + PxFilterObjectType::eRIGID_DYNAMIC, // PxActorType::eRIGID_DYNAMIC + PxFilterObjectType::eARTICULATION, // PxActorType::eARTICULATION_LINK + PxFilterObjectType::eSOFTBODY, // PxActorType::eSOFTBODY + PxFilterObjectType::eFEMCLOTH, // PxActorType::eFEMCLOTH + PxFilterObjectType::ePARTICLESYSTEM, // PxActorType::ePBD_PARTICLESYSTEM + PxFilterObjectType::ePARTICLESYSTEM, // PxActorType::eFLIP_PARTICLESYSTEM + PxFilterObjectType::ePARTICLESYSTEM, // PxActorType::eMPM_PARTICLESYSTEM + PxFilterObjectType::eHAIRSYSTEM, // PxActorType::eHAIRSYSTEM +}; + +static const PxU32 gFilterFlagEx[PxActorType::eACTOR_COUNT] = +{ + PxFilterObjectFlagEx::eRIGID_STATIC, // PxActorType::eRIGID_STATIC + PxFilterObjectFlagEx::eRIGID_DYNAMIC, // PxActorType::eRIGID_DYNAMIC + PxFilterObjectFlagEx::eRIGID_DYNAMIC, // PxActorType::eARTICULATION_LINK + PxFilterObjectFlagEx::eNON_RIGID|PxFilterObjectFlagEx::eSOFTBODY, // PxActorType::eSOFTBODY + PxFilterObjectFlagEx::eNON_RIGID|PxFilterObjectFlagEx::eFEMCLOTH, // PxActorType::eFEMCLOTH + PxFilterObjectFlagEx::eNON_RIGID|PxFilterObjectFlagEx::ePARTICLESYSTEM, // PxActorType::ePBD_PARTICLESYSTEM + PxFilterObjectFlagEx::eNON_RIGID|PxFilterObjectFlagEx::ePARTICLESYSTEM, // PxActorType::eFLIP_PARTICLESYSTEM + PxFilterObjectFlagEx::eNON_RIGID|PxFilterObjectFlagEx::ePARTICLESYSTEM, // PxActorType::eMPM_PARTICLESYSTEM + PxFilterObjectFlagEx::eNON_RIGID|PxFilterObjectFlagEx::eHAIRSYSTEM, // PxActorType::eHAIRSYSTEM +}; + +// PT: if this breaks, you need to update the above table +PX_COMPILE_TIME_ASSERT(PxActorType::eACTOR_COUNT==9); + +// PT: make sure that the highest flag fits into 16bit +PX_COMPILE_TIME_ASSERT(PxFilterObjectFlagEx::eLAST<=0xffff); Sc::ActorSim::ActorSim(Scene& scene, ActorCore& core) : - mScene (scene), - mCore (core), - mActiveListIndex(SC_NOT_IN_SCENE_INDEX), + mScene (scene), + mCore (core), + mActiveListIndex (SC_NOT_IN_SCENE_INDEX), mActiveCompoundListIndex(SC_NOT_IN_SCENE_INDEX), - mNodeIndex (PX_INVALID_NODE), - mInternalFlags (0) + mNodeIndex (PX_INVALID_NODE), + mInternalFlags (0) { core.setSim(this); mId = scene.getActorIDTracker().createID(); + + { + PX_ASSERT(gFilterType[PxActorType::eRIGID_STATIC] == PxFilterObjectType::eRIGID_STATIC); + PX_ASSERT(gFilterType[PxActorType::eRIGID_DYNAMIC] == PxFilterObjectType::eRIGID_DYNAMIC); + PX_ASSERT(gFilterType[PxActorType::eARTICULATION_LINK] == PxFilterObjectType::eARTICULATION); + PX_ASSERT(gFilterType[PxActorType::eSOFTBODY] == PxFilterObjectType::eSOFTBODY); + PX_ASSERT(gFilterType[PxActorType::eFEMCLOTH] == PxFilterObjectType::eFEMCLOTH); + PX_ASSERT(gFilterType[PxActorType::ePBD_PARTICLESYSTEM] == PxFilterObjectType::ePARTICLESYSTEM); + PX_ASSERT(gFilterType[PxActorType::eFLIP_PARTICLESYSTEM] == PxFilterObjectType::ePARTICLESYSTEM); + PX_ASSERT(gFilterType[PxActorType::eMPM_PARTICLESYSTEM] == PxFilterObjectType::ePARTICLESYSTEM); + PX_ASSERT(gFilterType[PxActorType::eHAIRSYSTEM] == PxFilterObjectType::eHAIRSYSTEM); + + const PxActorType::Enum actorType = getActorType(); + + PxFilterObjectAttributes filterAttr = 0; + setFilterObjectAttributeType(filterAttr, gFilterType[actorType]); + + filterAttr |= gFilterFlagEx[actorType]; + + mFilterFlags = PxTo16(filterAttr); + } } Sc::ActorSim::~ActorSim() @@ -69,7 +123,6 @@ void Sc::ActorSim::unregisterInteractionFromActor(Interaction* interaction) mInteractions[i]->setActorId(this, i); } -// PT: TODO: refactor with Sc::ParticlePacketShape::reallocInteractions - sschirm: particles are gone void Sc::ActorSim::reallocInteractions(Sc::Interaction**& mem, PxU32& capacity, PxU32 size, PxU32 requiredMinCapacity) { Interaction** newMem; @@ -116,39 +169,3 @@ void Sc::ActorSim::setActorsInteractionsDirty(InteractionDirtyFlag::Enum flag, c interaction->setDirty(flag); } } - -void Sc::ActorSim::setActive(bool active, PxU32 infoFlag) -{ - PX_ASSERT(!active || isDynamicRigid()); // Currently there should be no need to activate an actor that does not take part in island generation - - const PxU32 asPartOfCreation = infoFlag & ActorSim::AS_PART_OF_CREATION; - if (asPartOfCreation || isActive() != active) - { - PX_ASSERT(!asPartOfCreation || (getActorInteractionCount() == 0)); // On creation or destruction there should be no interactions - - if (active) - { - if (!asPartOfCreation) - { - // Inactive => Active - getScene().addToActiveList(*this); - } - - activate(); - - PX_ASSERT(asPartOfCreation || isActive()); - } - else - { - if (!asPartOfCreation) - { - // Active => Inactive - getScene().removeFromActiveList(*this); - } - - deactivate(); - - PX_ASSERT(asPartOfCreation || (!isActive())); - } - } -} diff --git a/physx/source/simulationcontroller/src/ScActorSim.h b/physx/source/simulationcontroller/src/ScActorSim.h index 7f113c0a2..73d8d442a 100644 --- a/physx/source/simulationcontroller/src/ScActorSim.h +++ b/physx/source/simulationcontroller/src/ScActorSim.h @@ -36,6 +36,7 @@ #include "ScInteractionFlags.h" #include "ScActorCore.h" #include "PxsSimpleIslandManager.h" +#include "PxFiltering.h" namespace physx { @@ -48,10 +49,27 @@ namespace Sc #define SC_NOT_IN_SCENE_INDEX 0xffffffff // the body is not in the scene yet #define SC_NOT_IN_ACTIVE_LIST_INDEX 0xfffffffe // the body is in the scene but not in the active list + struct PxFilterObjectFlagEx : PxFilterObjectFlag + { + enum Enum + { + eRIGID_STATIC = eNEXT_FREE, + eRIGID_DYNAMIC = eNEXT_FREE<<1, + eNON_RIGID = eNEXT_FREE<<2, + eSOFTBODY = eNEXT_FREE<<3, + eFEMCLOTH = eNEXT_FREE<<4, + ePARTICLESYSTEM = eNEXT_FREE<<5, + eHAIRSYSTEM = eNEXT_FREE<<6, + + eLAST = eHAIRSYSTEM + }; + }; + static const PxReal ScInternalWakeCounterResetValue = 20.0f*0.02f; class Interaction; class ElementSim; + class Scene; class ShapeManager : public PxUserAllocated { @@ -78,7 +96,6 @@ namespace Sc Cm::PtrTable mShapes; }; - class ActorSim : public ShapeManager { friend class Scene; // the scene is allowed to set the scene array index @@ -86,11 +103,6 @@ namespace Sc PX_NOCOPY(ActorSim) public: - enum ActivityChangeInfoFlag - { - AS_PART_OF_CREATION = (1 << 0), - AS_PART_OF_ISLAND_GEN = (1 << 1) - }; enum InternalFlags { @@ -110,7 +122,7 @@ namespace Sc BF_KINEMATIC_SETTLING = 1 << 9, // Set when the body was moved kinematically last frame BF_KINEMATIC_SETTLING_2 = 1 << 10, BF_KINEMATIC_MOVE_FLAGS = BF_KINEMATIC_MOVED | BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2, //Used to clear kinematic masks in 1 call - BF_KINEMATIC_SURFACE_VELOCITY = 1 << 11, //Set when the application calls setKinematicVelocity. Actor remains awake until application calls clearKinematicVelocity. + BF_KINEMATIC_SURFACE_VELOCITY = 1 << 11, //Set when the application calls setKinematicVelocity. Actor remains awake until application calls clearKinematicVelocity. BF_IS_COMPOUND_RIGID = 1 << 12, // Set when the body is a compound actor, we dont want to set the sq bounds // PT: WARNING: flags stored on 16-bits now. @@ -132,13 +144,13 @@ namespace Sc PX_FORCE_INLINE PxActorType::Enum getActorType() const { return mCore.getActorCoreType(); } // Returns true if the actor is a dynamic rigid body (including articulation links) - PX_FORCE_INLINE bool isDynamicRigid() const { const PxActorType::Enum type = getActorType(); return type == PxActorType::eRIGID_DYNAMIC || type == PxActorType::eARTICULATION_LINK; } - PX_FORCE_INLINE bool isSoftBody() const { const PxActorType::Enum type = getActorType(); return type == PxActorType::eSOFTBODY; } - PX_FORCE_INLINE bool isFEMCloth() const { const PxActorType::Enum type = getActorType(); return type == PxActorType::eFEMCLOTH; } - PX_FORCE_INLINE bool isParticleSystem() const { const PxActorType::Enum type = getActorType(); return type == PxActorType::ePBD_PARTICLESYSTEM || type == PxActorType::eFLIP_PARTICLESYSTEM || type == PxActorType::eMPM_PARTICLESYSTEM || type == PxActorType::eCUSTOM_PARTICLESYSTEM; } - PX_FORCE_INLINE bool isHairSystem() const { const PxActorType::Enum type = getActorType(); return type == PxActorType::eHAIRSYSTEM; } - PX_FORCE_INLINE bool isNonRigid() const { const PxActorType::Enum type = getActorType(); return type!=PxActorType::eRIGID_STATIC && type!=PxActorType::eRIGID_DYNAMIC && type!=PxActorType::eARTICULATION_LINK; } - PX_FORCE_INLINE bool isStaticRigid() const { const PxActorType::Enum type = getActorType(); return type == PxActorType::eRIGID_STATIC; } + PX_FORCE_INLINE PxU16 isDynamicRigid() const { return mFilterFlags & PxFilterObjectFlagEx::eRIGID_DYNAMIC; } + PX_FORCE_INLINE PxU16 isSoftBody() const { return mFilterFlags & PxFilterObjectFlagEx::eSOFTBODY; } + PX_FORCE_INLINE PxU16 isFEMCloth() const { return mFilterFlags & PxFilterObjectFlagEx::eFEMCLOTH; } + PX_FORCE_INLINE PxU16 isParticleSystem() const { return mFilterFlags & PxFilterObjectFlagEx::ePARTICLESYSTEM; } + PX_FORCE_INLINE PxU16 isHairSystem() const { return mFilterFlags & PxFilterObjectFlagEx::eHAIRSYSTEM; } + PX_FORCE_INLINE PxU16 isNonRigid() const { return mFilterFlags & PxFilterObjectFlagEx::eNON_RIGID; } + PX_FORCE_INLINE PxU16 isStaticRigid() const { return mFilterFlags & PxFilterObjectFlagEx::eRIGID_STATIC; } virtual void postActorFlagChange(PxU32, PxU32) {} @@ -147,7 +159,6 @@ namespace Sc PX_FORCE_INLINE ActorCore& getActorCore() const { return mCore; } PX_FORCE_INLINE bool isActive() const { return (mActiveListIndex < SC_NOT_IN_ACTIVE_LIST_INDEX); } - void setActive(bool active, PxU32 infoFlag = 0); // see ActivityChangeInfoFlag PX_FORCE_INLINE PxU32 getActiveListIndex() const { return mActiveListIndex; } // if the body is active, the index is smaller than SC_NOT_IN_ACTIVE_LIST_INDEX PX_FORCE_INLINE void setActiveListIndex(PxU32 index) { mActiveListIndex = index; } @@ -164,6 +175,8 @@ namespace Sc PX_FORCE_INLINE void raiseInternalFlag(InternalFlags flag) { mInternalFlags |= flag; } PX_FORCE_INLINE void clearInternalFlag(InternalFlags flag) { mInternalFlags &= ~flag; } + PX_FORCE_INLINE PxFilterObjectAttributes getFilterAttributes() const { return PxFilterObjectAttributes(mFilterFlags); } + virtual PxActor* getPxActor() const = 0; //This can all be removed and functionality can be subsumed by the island system, removing the need for this @@ -172,15 +185,12 @@ namespace Sc virtual void unregisterCountedInteraction() {} virtual PxU32 getNumCountedInteractions() const { return 0; } - virtual void activate() {} - virtual void deactivate() {} virtual void internalWakeUp(PxReal wakeCounterValue = ScInternalWakeCounterResetValue) { PX_UNUSED(wakeCounterValue); } private: //These are called from interaction creation/destruction void registerInteractionInActor(Interaction* interaction); void unregisterInteractionFromActor(Interaction* interaction); - void reallocInteractions(Sc::Interaction**& mem, PxU32& capacity, PxU32 size, PxU32 requiredMinCapacity); protected: // dsequeira: interaction arrays are a major cause of small allocations, so we don't want to delegate them to the heap allocator @@ -193,23 +203,19 @@ namespace Sc mInteractions; Scene& mScene; - ActorCore& mCore; - - //--------------------------------------------------------------------------------- - // Sleeping - //--------------------------------------------------------------------------------- - PxU32 mActiveListIndex; // Used by Scene to track active bodies + // Sleeping + PxU32 mActiveListIndex; // Used by Scene to track active bodies PxU32 mActiveCompoundListIndex; // Used by Scene to track active compound bodies - //--------------------------------------------------------------------------------- - // Island manager - //--------------------------------------------------------------------------------- + // Island manager PxNodeIndex mNodeIndex; - PxU32 mId; + PxU32 mId; // PT: ID provided by Sc::Scene::mActorIDTracker PxU16 mInternalFlags; + PxU16 mFilterFlags; // PT: PxFilterObjectAttributes. Capturing the type information in local flags here is redundant + // but avoids reading the Core memory from the Sim object, and is also faster to test multiple types at once. }; } // namespace Sc diff --git a/physx/source/simulationcontroller/src/ScArticulationCore.cpp b/physx/source/simulationcontroller/src/ScArticulationCore.cpp index 67d7ccbc4..b462236f2 100644 --- a/physx/source/simulationcontroller/src/ScArticulationCore.cpp +++ b/physx/source/simulationcontroller/src/ScArticulationCore.cpp @@ -135,10 +135,10 @@ void Sc::ArticulationCore::putToSleep() void Sc::ArticulationCore::setArticulationFlags(PxArticulationFlags flags) { mCore.flags = flags; - if (mSim) + if(mSim) { - const bool isKinematicLink = flags & PxArticulationFlag::eFIX_BASE; - mSim->setKinematicLink(isKinematicLink); + const bool isFixedBaseLink = flags & PxArticulationFlag::eFIX_BASE; + mSim->setFixedBaseLink(isFixedBaseLink); } } @@ -170,10 +170,10 @@ bool Sc::ArticulationCore::applyCache(PxArticulationCache& cache, const PxArticu return false; } -void Sc::ArticulationCore::copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const +void Sc::ArticulationCore::copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, const bool isGpuSimEnabled) const { if(mSim) - mSim->copyInternalStateToCache(cache, flag); + mSim->copyInternalStateToCache(cache, flag, isGpuSimEnabled); } @@ -253,9 +253,9 @@ PxU32 Sc::ArticulationCore::getCoefficientMatrixSize() const return mSim ? mSim->getCoefficientMatrixSize() : 0xFFFFFFFFu; } -PxSpatialVelocity Sc::ArticulationCore::getLinkAcceleration(const PxU32 linkId) const +PxSpatialVelocity Sc::ArticulationCore::getLinkAcceleration(const PxU32 linkId, const bool isGpuSimEnabled) const { - return mSim ? mSim->getLinkAcceleration(linkId) : PxSpatialVelocity(); + return mSim ? mSim->getLinkAcceleration(linkId, isGpuSimEnabled) : PxSpatialVelocity(); } PxU32 Sc::ArticulationCore::getGpuArticulationIndex() const @@ -269,7 +269,6 @@ void Sc::ArticulationCore::updateKinematic(PxArticulationKinematicFlags flags) if (mSim) mSim->updateKinematic(flags); - } PxNodeIndex Sc::ArticulationCore::getIslandNodeIndex() const diff --git a/physx/source/simulationcontroller/src/ScArticulationJointSim.cpp b/physx/source/simulationcontroller/src/ScArticulationJointSim.cpp index 141f41484..d4059fccf 100644 --- a/physx/source/simulationcontroller/src/ScArticulationJointSim.cpp +++ b/physx/source/simulationcontroller/src/ScArticulationJointSim.cpp @@ -40,7 +40,10 @@ Sc::ArticulationJointSim::ArticulationJointSim(ArticulationJointCore& joint, Act Interaction (parent, child, InteractionType::eARTICULATION, 0), mCore (joint) { - registerInActors(); + { + onActivate(NULL); + registerInActors(); + } BodySim& childBody = static_cast(child), & parentBody = static_cast(parent); @@ -71,7 +74,7 @@ Sc::BodySim& Sc::ArticulationJointSim::getChild() const return static_cast(getActorSim1()); } -bool Sc::ArticulationJointSim::onActivate_(void*) +bool Sc::ArticulationJointSim::onActivate(void*) { if(!(getParent().isActive() && getChild().isActive())) return false; @@ -80,7 +83,7 @@ bool Sc::ArticulationJointSim::onActivate_(void*) return true; } -bool Sc::ArticulationJointSim::onDeactivate_() +bool Sc::ArticulationJointSim::onDeactivate() { clearInteractionFlag(InteractionFlag::eIS_ACTIVE); return true; diff --git a/physx/source/simulationcontroller/src/ScArticulationJointSim.h b/physx/source/simulationcontroller/src/ScArticulationJointSim.h index 2569795b5..4c94392b8 100644 --- a/physx/source/simulationcontroller/src/ScArticulationJointSim.h +++ b/physx/source/simulationcontroller/src/ScArticulationJointSim.h @@ -40,14 +40,13 @@ namespace Sc class ArticulationJointSim : public Interaction { - ArticulationJointSim& operator=(const ArticulationJointSim &); - + PX_NOCOPY(ArticulationJointSim) public: ArticulationJointSim(ArticulationJointCore& joint, ActorSim& parent, ActorSim& child); ~ArticulationJointSim(); - bool onActivate_(void*); - bool onDeactivate_(); + bool onActivate(void*); + bool onDeactivate(); PX_FORCE_INLINE ArticulationJointCore& getCore() const { return mCore; } @@ -55,10 +54,6 @@ namespace Sc BodySim& getChild() const; void setDirty(); - - //--------------------------------------------------------------------------------- - // Low Level data access - //--------------------------------------------------------------------------------- private: ArticulationJointCore& mCore; }; diff --git a/physx/source/simulationcontroller/src/ScArticulationSim.cpp b/physx/source/simulationcontroller/src/ScArticulationSim.cpp index dbe104787..436161279 100644 --- a/physx/source/simulationcontroller/src/ScArticulationSim.cpp +++ b/physx/source/simulationcontroller/src/ScArticulationSim.cpp @@ -50,14 +50,14 @@ using namespace physx; using namespace physx::Dy; Sc::ArticulationSim::ArticulationSim(ArticulationCore& core, Scene& scene, BodyCore& root) : - mLLArticulation (NULL), - mScene (scene), - mCore (core), - mLinks ("ScArticulationSim::links"), - mBodies ("ScArticulationSim::bodies"), - mJoints ("ScArticulationSim::joints"), - mMaxDepth (0), - mIsLLArticultionInitialized(false) + mLLArticulation (NULL), + mScene (scene), + mCore (core), + mLinks ("ScArticulationSim::links"), + mBodies ("ScArticulationSim::bodies"), + mJoints ("ScArticulationSim::joints"), + mMaxDepth (0), + mIsLLArticulationInitialized(false) { mLinks.reserve(16); mJoints.reserve(16); @@ -65,11 +65,11 @@ Sc::ArticulationSim::ArticulationSim(ArticulationCore& core, Scene& scene, BodyC mLLArticulation = mScene.createLLArticulation(this); - mIslandNodeIndex = scene.getSimpleIslandManager()->addArticulation(this, mLLArticulation, false); + mIslandNodeIndex = scene.getSimpleIslandManager()->addArticulation(mLLArticulation, false); if(!mLLArticulation) { - PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Articulation: could not allocate low-level resources."); + PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Articulation: could not allocate low-level resources."); return; } @@ -240,10 +240,8 @@ void Sc::ArticulationSim::removeBody(BodySim& body) break; } } - } - void Sc::ArticulationSim::addTendon(ArticulationSpatialTendonSim* tendonSim) { tendonSim->mArtiSim = this; @@ -266,7 +264,6 @@ void Sc::ArticulationSim::addTendon(ArticulationFixedTendonSim* tendonSim) mFixedTendons.pushBack(&llTendon); } - void Sc::ArticulationSim::addSensor(ArticulationSensorSim* sensorSim, const PxU32 linkID) { const PxU32 index = mSensors.size(); @@ -294,8 +291,7 @@ void Sc::ArticulationSim::createLLStructure() mLLArticulation->assignSensors(mSensors.size(), const_cast(mSensors.begin()), const_cast(mSensorForces.begin())); - mIsLLArticultionInitialized = true; - + mIsLLArticulationInitialized = true; } void Sc::ArticulationSim::initializeConfiguration() @@ -469,7 +465,7 @@ void Sc::ArticulationSim::sleepCheck(PxReal dt) for(PxU32 i=0;inotifyReadyForSleeping(); - mBodies[i]->resetSleepFilter(); + mBodies[i]->getLowLevelBody().resetSleepFilter(); } mScene.getSimpleIslandManager()->deactivateNode(mIslandNodeIndex); @@ -490,23 +486,6 @@ void Sc::ArticulationSim::internalWakeUp(PxReal wakeCounter) } } -void Sc::ArticulationSim::setActive(const bool b, const PxU32 infoFlag) -{ - const PxReal wakeCounter = mCore.getWakeCounter(); - for(PxU32 i=0;igetBodyCore().setWakeCounterFromSim(wakeCounter); - mBodies[i]->setActive(b, infoFlag); - } -} - void Sc::ArticulationSim::updateForces(PxReal dt, bool notify) { PxU32 count = 0; @@ -537,7 +516,6 @@ void Sc::ArticulationSim::clearAcceleration(PxReal dt) PxPrefetchLine(mBodies[i + 1], 256); } - const bool accDirty = mBodies[i]->readVelocityModFlag(VMF_ACC_DIRTY); if (!accDirty) @@ -547,7 +525,6 @@ void Sc::ArticulationSim::clearAcceleration(PxReal dt) } else mBodies[i]->updateForces(dt, NULL, NULL, count, &mLLArticulation->getSolverDesc().acceleration[i]); - } mScene.getSimulationController()->updateArticulationExtAccel(mLLArticulation, mIslandNodeIndex); @@ -566,14 +543,12 @@ void Sc::ArticulationSim::saveLastCCDTransform() } } -void Sc::ArticulationSim::setKinematicLink(const bool value) +void Sc::ArticulationSim::setFixedBaseLink(bool value) { const PxU32 linkCount = mLinks.size(); - if (linkCount > 0) - { - mLinks[0].bodyCore->kinematicLink = PxU8(value); - } + if(linkCount > 0) + mLinks[0].bodyCore->fixedBaseLink = PxU8(value); } PxU32 Sc::ArticulationSim::getDofs() const @@ -589,96 +564,12 @@ PxU32 Sc::ArticulationSim::getDof(const PxU32 linkID) const PX_COMPILE_TIME_ASSERT(sizeof(Cm::SpatialVector)==sizeof(PxSpatialForce)); PxArticulationCache* Sc::ArticulationSim::createCache() { - const PxU32 totalSize = getCacheDataSize() + sizeof(PxArticulationCache); - - const PxU32 totalDofs = mLLArticulation->getDofs(); - const PxU32 linkCount = mLinks.size(); - const PxU32 sensorCount = mSensors.size(); - - PxU8* tCache = reinterpret_cast(PX_ALLOC(totalSize, "Articulation cache")); - PxMemZero(tCache, totalSize); - - PxArticulationCache* cache = reinterpret_cast(tCache); - - PxU32 offset = sizeof(PxArticulationCache); - cache->externalForces = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialForce) * linkCount; - cache->sensorForces = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialForce) * sensorCount; - - cache->denseJacobian = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * (6 + totalDofs) * (linkCount * 6); //size of dense jacobian assuming free floating base link. - - cache->massMatrix = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs * totalDofs; - - cache->jointVelocity = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointAcceleration = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointPosition = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointForce = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->jointSolverForces = reinterpret_cast(tCache + offset); - offset += sizeof(PxReal) * totalDofs; - - cache->linkVelocity = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialVelocity) * linkCount; - - cache->linkAcceleration = reinterpret_cast(tCache + offset); - offset += sizeof(PxSpatialVelocity) * linkCount; - - cache->rootLinkData = reinterpret_cast(tCache + offset); - - cache->coefficientMatrix = NULL; - cache->lambda =NULL; - - const PxU32 scratchMemorySize = getScratchMemorySize(); - void* scratchMemory = PX_ALLOC(scratchMemorySize, "Cache scratch memory"); - cache->scratchMemory = scratchMemory; - - PxcScratchAllocator* sa = PX_NEW(PxcScratchAllocator); - sa->setBlock(scratchMemory, scratchMemorySize); - cache->scratchAllocator = sa; - - return cache; + return FeatherstoneArticulation::createCache(getDofs(), mLinks.size(), mSensors.size()); } PxU32 Sc::ArticulationSim::getCacheDataSize() const { - const PxU32 totalDofs = mLLArticulation->getDofs(); - const PxU32 linkCount = mLinks.size(); - const PxU32 sensorCount = mSensors.size(); - const PxU32 totalSize = - sizeof(PxSpatialForce) * linkCount //external force - + sizeof(PxSpatialForce) * sensorCount //sensors - + sizeof(PxReal) * (6 + totalDofs) * (linkCount * 6) //Free floating base dofs = 6 + totalDofs, and each link (incl. base) velocity has 6 elements - + sizeof(PxReal) * totalDofs * totalDofs //mass matrix - + sizeof(PxReal) * totalDofs * 5 //jointVelocity, jointAcceleration, jointPosition, joint force, joint constraint force - + sizeof(PxSpatialVelocity) * linkCount * 2 //link velocity, link acceleration - + sizeof(PxArticulationRootLinkData); //root link data - - return totalSize; -} - -PxU32 Sc::ArticulationSim::getScratchMemorySize() const -{ - const PxU32 totalDofs = mLLArticulation->getDofs(); - const PxU32 linkCount = mLinks.size(); - - PxU32 totalSize = - sizeof(Cm::SpatialVectorF) * linkCount * 5 //motionVelocity, motionAccelerations, coriolisVectors, spatialZAVectors, externalAccels; - + sizeof(Dy::SpatialMatrix) * linkCount //compositeSpatialInertias; - + sizeof(PxReal) * totalDofs * 5; //jointVelocity, jointAcceleration, jointForces, jointPositions, jointFrictionForces - - totalSize = (totalSize+15)&~15; - - return totalSize; + return FeatherstoneArticulation::getCacheDataSize(getDofs(), mLinks.size(), mSensors.size()); } void Sc::ArticulationSim::zeroCache(PxArticulationCache& cache) const @@ -701,12 +592,11 @@ bool Sc::ArticulationSim::applyCache(PxArticulationCache& cache, const PxArticu } //copy internal data to external data -void Sc::ArticulationSim::copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const +void Sc::ArticulationSim::copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, const bool isGpuSimEnabled) const { - mLLArticulation->copyInternalStateToCache(cache, flag); + mLLArticulation->copyInternalStateToCache(cache, flag, isGpuSimEnabled); } - void Sc::ArticulationSim::packJointData(const PxReal* maximum, PxReal* reduced) const { mLLArticulation->packJointData(maximum, reduced); @@ -724,7 +614,7 @@ void Sc::ArticulationSim::commonInit() void Sc::ArticulationSim::computeGeneralizedGravityForce(PxArticulationCache& cache) { - mLLArticulation->getGeneralizedGravityForce(mScene.getGravityFast(), cache); + mLLArticulation->getGeneralizedGravityForce(mScene.getGravity(), cache); } void Sc::ArticulationSim::computeCoriolisAndCentrifugalForce(PxArticulationCache& cache) @@ -739,7 +629,7 @@ void Sc::ArticulationSim::computeGeneralizedExternalForce(PxArticulationCache& c void Sc::ArticulationSim::computeJointAcceleration(PxArticulationCache& cache) { - mLLArticulation->getJointAcceleration(mScene.getGravityFast(), cache); + mLLArticulation->getJointAcceleration(mScene.getGravity(), cache); } void Sc::ArticulationSim::computeJointForce(PxArticulationCache& cache) @@ -813,9 +703,9 @@ PxSpatialVelocity Sc::ArticulationSim::getLinkVelocity(const PxU32 linkId) const return reinterpret_cast(vel); } -PxSpatialVelocity Sc::ArticulationSim::getLinkAcceleration(const PxU32 linkId) const +PxSpatialVelocity Sc::ArticulationSim::getLinkAcceleration(const PxU32 linkId, const bool isGpuSimEnabled) const { - Cm::SpatialVector accel = mLLArticulation->getMotionAcceleration(linkId); + Cm::SpatialVector accel = mLLArticulation->getMotionAcceleration(linkId, isGpuSimEnabled); return reinterpret_cast(accel); } diff --git a/physx/source/simulationcontroller/src/ScArticulationSim.h b/physx/source/simulationcontroller/src/ScArticulationSim.h index 1fa16dc70..069bfa7a3 100644 --- a/physx/source/simulationcontroller/src/ScArticulationSim.h +++ b/physx/source/simulationcontroller/src/ScArticulationSim.h @@ -44,6 +44,7 @@ namespace Bp namespace Sc { class BodySim; + class BodyCore; class ArticulationJointSim; class ArticulationSpatialTendonSim; class ArticulationFixedTendonSim; @@ -63,9 +64,9 @@ namespace Sc typedef PxFlags ArticulationSimDirtyFlags; - class ArticulationSim : public PxUserAllocated { + PX_NOCOPY(ArticulationSim) public: ArticulationSim(ArticulationCore& core, Scene& scene, @@ -84,7 +85,6 @@ namespace Sc void removeBody(BodySim& body); - //we don't need removeTendon method anymore because when the articulation is removed from the scene, the articulation sim will //get completely distroy and when we re-add the articulation to the scene, all the data will get recomputed void addTendon(ArticulationSpatialTendonSim*); @@ -109,17 +109,16 @@ namespace Sc void updateCCDLinks(PxArray& sims); void updateCached(PxBitMapPinned* shapehapeChangedMap); void markShapesUpdated(PxBitMapPinned* shapeChangedMap); - void updateContactDistance(PxReal* contactDistance, const PxReal dt, const Bp::BoundsArray& boundsArray); + void updateContactDistance(PxReal* contactDistance, PxReal dt, const Bp::BoundsArray& boundsArray); - void setActive(const bool b, const PxU32 infoFlag=0); + void setActive(bool b, bool asPartOfCreation=false); void updateForces(PxReal dt, bool notify = true); void saveLastCCDTransform(); void clearAcceleration(PxReal dt); - - void setKinematicLink(const bool value); + void setFixedBaseLink(bool value); //external reduced coordinate implementation PxU32 getDofs() const; @@ -130,13 +129,12 @@ namespace Sc PxU32 getCacheDataSize() const; - PxU32 getScratchMemorySize() const; - void zeroCache(PxArticulationCache&) const; bool applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const; - void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const; + void copyInternalStateToCache + (PxArticulationCache& cache, const PxArticulationCacheFlags flag, const bool isGpuSimEnabled) const; void packJointData(const PxReal* maximum, PxReal* reduced) const; @@ -170,9 +168,8 @@ namespace Sc void setRootAngularVelocity(const PxVec3& velocity); PxSpatialVelocity getLinkVelocity(const PxU32 linkId) const; - PxSpatialVelocity getLinkAcceleration(const PxU32 linkId) const; + PxSpatialVelocity getLinkAcceleration(const PxU32 linkId, const bool isGpuSimEnabled) const; - //internal method implementation PX_FORCE_INLINE PxNodeIndex getIslandNodeIndex() const { return mIslandNodeIndex; } @@ -197,17 +194,13 @@ namespace Sc PxU32 getRootActorIndex() const; const PxSpatialForce& getSensorForce(const PxU32 lowLevelIndex) const; - - void updateKinematic(PxArticulationKinematicFlags flags); void copyJointStatus(const PxU32 linkIndex); - PX_FORCE_INLINE void getLLArticulationInitialized(bool val) { mIsLLArticultionInitialized = val; } - PX_FORCE_INLINE bool getLLArticulationInitialized() { return mIsLLArticultionInitialized; } + PX_FORCE_INLINE void getLLArticulationInitialized(bool val) { mIsLLArticulationInitialized = val; } + PX_FORCE_INLINE bool getLLArticulationInitialized() { return mIsLLArticulationInitialized; } private: - ArticulationSim& operator=(const ArticulationSim&); - Dy::FeatherstoneArticulation* mLLArticulation; Scene& mScene; ArticulationCore& mCore; @@ -219,13 +212,11 @@ namespace Sc PxArray mSensors; PxArray mSensorForces; - PxNodeIndex mIslandNodeIndex; PxArray mLoopConstraints; PxU32 mMaxDepth; - bool mIsLLArticultionInitialized; + bool mIsLLArticulationInitialized; ArticulationSimDirtyFlags mDirtyFlags; - }; } // namespace Sc diff --git a/physx/source/simulationcontroller/src/ScBodyCore.cpp b/physx/source/simulationcontroller/src/ScBodyCore.cpp index 8d3e55402..0e87df27a 100644 --- a/physx/source/simulationcontroller/src/ScBodyCore.cpp +++ b/physx/source/simulationcontroller/src/ScBodyCore.cpp @@ -137,18 +137,18 @@ void Sc::BodyCore::setBody2Actor(const PxTransform& p) } } -void Sc::BodyCore::addSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc) +void Sc::BodyCore::addSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc) { BodySim* sim = getSim(); PX_ASSERT(sim); - sim->addSpatialAcceleration(simStateDataPool, linAcc, angAcc); + sim->addSpatialAcceleration(linAcc, angAcc); } -void Sc::BodyCore::setSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc) +void Sc::BodyCore::setSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc) { BodySim* sim = getSim(); PX_ASSERT(sim); - sim->setSpatialAcceleration(simStateDataPool, linAcc, angAcc); + sim->setSpatialAcceleration(linAcc, angAcc); } void Sc::BodyCore::clearSpatialAcceleration(bool force, bool torque) @@ -159,11 +159,11 @@ void Sc::BodyCore::clearSpatialAcceleration(bool force, bool torque) sim->clearSpatialAcceleration(force, torque); } -void Sc::BodyCore::addSpatialVelocity(PxPool* simStateDataPool, const PxVec3* linVelDelta, const PxVec3* angVelDelta) +void Sc::BodyCore::addSpatialVelocity(const PxVec3* linVelDelta, const PxVec3* angVelDelta) { BodySim* sim = getSim(); PX_ASSERT(sim); - sim->addSpatialVelocity(simStateDataPool, linVelDelta, angVelDelta); + sim->addSpatialVelocity(linVelDelta, angVelDelta); } void Sc::BodyCore::clearSpatialVelocity(bool force, bool torque) @@ -372,7 +372,7 @@ void Sc::BodyCore::setMaxLinVelSq(PxReal v) } } -void Sc::BodyCore::setFlags(PxPool* simStateDataPool, PxRigidBodyFlags f) +void Sc::BodyCore::setFlags(PxRigidBodyFlags f) { const PxRigidBodyFlags old = mCore.mFlags; if(f != old) @@ -386,8 +386,6 @@ void Sc::BodyCore::setFlags(PxPool* simStateDataPool, PxRigidBodyF BodySim* sim = getSim(); if (sim) { - PX_ASSERT(simStateDataPool); - const PxU32 posePreviewFlag = f & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW; if(PxU32(old & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW) != posePreviewFlag) sim->postPosePreviewChange(posePreviewFlag); @@ -397,13 +395,9 @@ void Sc::BodyCore::setFlags(PxPool* simStateDataPool, PxRigidBodyF // Thus, the kinematic data should only be created/destroyed when we know for sure that we are in a scene. if(switchToKinematic) - { - sim->switchToKinematic(simStateDataPool); - } + sim->switchToKinematic(); else if(switchToDynamic) - { - sim->switchToDynamic(simStateDataPool); - } + sim->switchToDynamic(); const PxU32 wasSpeculativeCCD = old & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD; const PxU32 isSpeculativeCCD = f & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD; @@ -412,23 +406,15 @@ void Sc::BodyCore::setFlags(PxPool* simStateDataPool, PxRigidBodyF { if(wasSpeculativeCCD) { - if(sim->isArticulationLink()) - sim->getScene().resetSpeculativeCCDArticulationLink(sim->getNodeIndex().index()); - else - sim->getScene().resetSpeculativeCCDRigidBody(sim->getNodeIndex().index()); + sim->removeFromSpeculativeCCDMap(); sim->getLowLevelBody().mInternalFlags &= (~PxsRigidBody::eSPECULATIVE_CCD); } else { //Kinematic body switch puts the body to sleep, so we do not mark the speculative CCD bitmap for this actor to true in this case. - if (!switchToKinematic) - { - if (sim->isArticulationLink()) - sim->getScene().setSpeculativeCCDArticulationLink(sim->getNodeIndex().index()); - else - sim->getScene().setSpeculativeCCDRigidBody(sim->getNodeIndex().index()); - } + if(!switchToKinematic) + sim->addToSpeculativeCCDMap(); sim->getLowLevelBody().mInternalFlags |= (PxsRigidBody::eSPECULATIVE_CCD); } @@ -439,9 +425,9 @@ void Sc::BodyCore::setFlags(PxPool* simStateDataPool, PxRigidBodyF if (wasIntegrateGyroscopic ^ isIntegrateGyroscopic) { if(wasIntegrateGyroscopic) - sim->getLowLevelBody().mInternalFlags &= (PxsRigidBody::eENABLE_GYROSCROPIC); + sim->getLowLevelBody().mInternalFlags &= (PxsRigidBody::eENABLE_GYROSCOPIC); else - sim->getLowLevelBody().mInternalFlags |= (PxsRigidBody::eENABLE_GYROSCROPIC); + sim->getLowLevelBody().mInternalFlags |= (PxsRigidBody::eENABLE_GYROSCOPIC); } const PxU32 wasRetainAccel = old & PxRigidBodyFlag::eRETAIN_ACCELERATIONS; @@ -599,12 +585,12 @@ void Sc::BodyCore::invalidateKinematicTarget() simStateInvalidateKinematicTarget(sim->getSimStateData_Unchecked()); } -void Sc::BodyCore::setKinematicLink(const bool value) +void Sc::BodyCore::setFixedBaseLink(bool value) { BodySim* sim = getSim(); - if (sim) - sim->getLowLevelBody().mCore->kinematicLink = PxU8(value); + if(sim) + sim->getLowLevelBody().mCore->fixedBaseLink = PxU8(value); } void Sc::BodyCore::onRemoveKinematicFromScene() diff --git a/physx/source/simulationcontroller/src/ScBodySim.cpp b/physx/source/simulationcontroller/src/ScBodySim.cpp index d895d10fc..9e5086660 100644 --- a/physx/source/simulationcontroller/src/ScBodySim.cpp +++ b/physx/source/simulationcontroller/src/ScBodySim.cpp @@ -45,23 +45,33 @@ using namespace Sc; #define PX_SLEEP_DAMPING 0.5f #define PX_FREEZE_SCALE 0.9f +static void updateBPGroup(ActorSim* sim) +{ + PxU32 nbElems = sim->getNbElements(); + ElementSim** elems = sim->getElements(); + while (nbElems--) + { + ShapeSim* current = static_cast(*elems++); + current->updateBPGroup(); + } +} + BodySim::BodySim(Scene& scene, BodyCore& core, bool compound) : - RigidSim (scene, core), - mLLBody (&core.getCore(), PX_FREEZE_INTERVAL), - mSimStateData (NULL), - mVelModState (VMF_GRAVITY_DIRTY), - mArticulation (NULL), - mConstraintGroup (NULL) + RigidSim (scene, core), + mLLBody (&core.getCore(), PX_FREEZE_INTERVAL), + mSimStateData (NULL), + mVelModState (VMF_GRAVITY_DIRTY), + mArticulation (NULL) { core.getCore().numCountedInteractions = 0; core.getCore().disableGravity = core.getActorFlags() & PxActorFlag::eDISABLE_GRAVITY; if(core.getFlags() & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) mLLBody.mInternalFlags |= PxsRigidBody::eSPECULATIVE_CCD; - if (core.getFlags() & PxRigidBodyFlag::eENABLE_GYROSCOPIC_FORCES) - mLLBody.mInternalFlags |= PxsRigidBody::eENABLE_GYROSCROPIC; + if(core.getFlags() & PxRigidBodyFlag::eENABLE_GYROSCOPIC_FORCES) + mLLBody.mInternalFlags |= PxsRigidBody::eENABLE_GYROSCOPIC; - if (core.getFlags() & PxRigidBodyFlag::eRETAIN_ACCELERATIONS) + if(core.getFlags() & PxRigidBodyFlag::eRETAIN_ACCELERATIONS) mLLBody.mInternalFlags |= PxsRigidBody::eRETAIN_ACCELERATION; // PT: don't read the core ptr we just wrote, use input param @@ -73,7 +83,7 @@ BodySim::BodySim(Scene& scene, BodyCore& core, bool compound) : const bool isKine = isKinematic(); IG::SimpleIslandManager* simpleIslandManager = scene.getSimpleIslandManager(); - if (!isArticulationLink()) + if(!isArticulationLink()) { mNodeIndex = simpleIslandManager->addRigidBody(&mLLBody, isKine, isAwake); } @@ -81,8 +91,8 @@ BodySim::BodySim(Scene& scene, BodyCore& core, bool compound) : { if(mArticulation) { - PxU32 linkIndex = mArticulation->findBodyIndex(*this); - PxNodeIndex index = mArticulation->getIslandNodeIndex(); + const PxU32 linkIndex = mArticulation->findBodyIndex(*this); + const PxNodeIndex index = mArticulation->getIslandNodeIndex(); mNodeIndex.setIndices(index.index(), linkIndex); } } @@ -94,9 +104,9 @@ BodySim::BodySim(Scene& scene, BodyCore& core, bool compound) : if(compound) raiseInternalFlag(BF_IS_COMPOUND_RIGID); - setActive(isAwake, ActorSim::AS_PART_OF_CREATION); + setActive(isAwake, true); - if (isAwake) + if(isAwake) { scene.addToActiveList(*this); PX_ASSERT(isActive()); @@ -110,28 +120,28 @@ BodySim::BodySim(Scene& scene, BodyCore& core, bool compound) : simpleIslandManager->deactivateNode(mNodeIndex); } - if (isKine) + if(isKine) { initKinematicStateBase(core, true); - setupSimStateData(scene.getSimStateDataPool(), true); + setupSimStateData(true); notifyPutToSleep(); // sleep state of kinematics is fully controlled by the simulation controller not the island manager + + mFilterFlags |= PxFilterObjectFlag::eKINEMATIC; } } BodySim::~BodySim() { - Scene& scene = getScene(); + Scene& scene = mScene; const bool active = isActive(); - tearDownSimStateData(scene.getSimStateDataPool(), isKinematic() ? true : false); + tearDownSimStateData(isKinematic()); PX_ASSERT(!mSimStateData); PX_ASSERT(!readInternalFlag(BF_ON_DEATHROW)); // Before 3.0 it could happen that destroy could get called twice. Assert to make sure this is fixed. raiseInternalFlag(BF_ON_DEATHROW); scene.removeBody(*this); - PX_ASSERT(!getConstraintGroup()); // Removing from scene should erase constraint group node if it existed - //Articulations are represented by a single node, so they must only be removed by the articulation and not the links! if(mArticulation == NULL && mNodeIndex.articulationLinkId() == 0) //If it wasn't an articulation link, then we can remove it @@ -175,23 +185,17 @@ void BodySim::updateCached(PxsTransformCache& transformCache, Bp::BoundsArray& b } } -//-------------------------------------------------------------- -// -// BodyCore interface implementation -// -//-------------------------------------------------------------- - -bool BodySim::setupSimStateData(PxPool* simStateDataPool, const bool isKinematic) +bool BodySim::setupSimStateData(bool isKinematic) { SimStateData* data = mSimStateData; - if (!data) + if(!data) { - data = simStateDataPool->construct(); - if (!data) + data = mScene.getSimStateDataPool()->construct(); + if(!data) return false; } - if (isKinematic) + if(isKinematic) { PX_ASSERT(!mSimStateData || !mSimStateData->isKine()); @@ -212,7 +216,7 @@ bool BodySim::setupSimStateData(PxPool* simStateDataPool, const bo return true; } -void BodySim::tearDownSimStateData(PxPool* simStateDataPool, const bool isKinematic) +void BodySim::tearDownSimStateData(bool isKinematic) { PX_ASSERT(!mSimStateData || mSimStateData->isKine() == isKinematic); @@ -221,23 +225,62 @@ void BodySim::tearDownSimStateData(PxPool* simStateDataPool, const if (isKinematic) simStateRestoreBodyProperties(mSimStateData, getBodyCore().getCore()); - simStateDataPool->destroy(mSimStateData); + mScene.getSimStateDataPool()->destroy(mSimStateData); mSimStateData = NULL; } } -void BodySim::switchToKinematic(PxPool* simStateDataPool) +void BodySim::switchToKinematic() { - setupSimStateData(simStateDataPool, true); - postSwitchToKinematic(); - getScene().setDynamicsDirty(); + setupSimStateData(true); + + { + initKinematicStateBase(getBodyCore(), false); + + // - interactions need to get refiltered to make sure that kinematic-kinematic and kinematic-static pairs get suppressed + // - unlike postSwitchToDynamic(), constraint interactions are not marked dirty here because a transition to kinematic will put the object asleep which in turn + // triggers onDeactivate() on the constraint pairs that are active. If such pairs get deactivated, they will get removed from the list of active breakable + // constraints automatically. + setActorsInteractionsDirty(InteractionDirtyFlag::eBODY_KINEMATIC, NULL, InteractionFlag::eFILTERABLE); + + mScene.getSimpleIslandManager()->setKinematic(mNodeIndex); + + updateBPGroup(this); + } + + mScene.setDynamicsDirty(); + + mFilterFlags |= PxFilterObjectFlag::eKINEMATIC; } -void BodySim::switchToDynamic(PxPool* simStateDataPool) +void BodySim::switchToDynamic() { - tearDownSimStateData(simStateDataPool, true); - postSwitchToDynamic(); - getScene().setDynamicsDirty(); + tearDownSimStateData(true); + + { + mScene.getSimpleIslandManager()->setDynamic(mNodeIndex); + + setForcesToDefaults(true); + + // - interactions need to get refiltered to make sure that former kinematic-kinematic and kinematic-static pairs get enabled + // - switching from kinematic to dynamic does not change the sleep state of the body. The constraint interactions are marked dirty + // to check later whether they need to be activated plus potentially tracked for constraint break testing. This special treatment + // is necessary because constraints between two kinematic bodies are considered inactive, no matter whether one of the kinematics + // is active (has a target) or not. + setActorsInteractionsDirty(InteractionDirtyFlag::eBODY_KINEMATIC, NULL, InteractionFlag::eFILTERABLE | InteractionFlag::eCONSTRAINT); + + clearInternalFlag(BF_KINEMATIC_MOVE_FLAGS); + + if(isActive()) + mScene.swapInActiveBodyList(*this); + + // + updateBPGroup(this); + } + + mScene.setDynamicsDirty(); + + mFilterFlags &= ~PxFilterObjectFlag::eKINEMATIC; } void BodySim::setKinematicTarget(const PxTransform& p) @@ -251,24 +294,24 @@ void BodySim::setKinematicTarget(const PxTransform& p) clearInternalFlag(BF_KINEMATIC_SURFACE_VELOCITY); } -void BodySim::addSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc) +void BodySim::addSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc) { notifyAddSpatialAcceleration(); if (!mSimStateData || !mSimStateData->isVelMod()) - setupSimStateData(simStateDataPool, false); + setupSimStateData(false); VelocityMod* velmod = mSimStateData->getVelocityModData(); if (linAcc) velmod->accumulateLinearVelModPerSec(*linAcc); if (angAcc) velmod->accumulateAngularVelModPerSec(*angAcc); } -void BodySim::setSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc) +void BodySim::setSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc) { notifyAddSpatialAcceleration(); if (!mSimStateData || !mSimStateData->isVelMod()) - setupSimStateData(simStateDataPool, false); + setupSimStateData(false); VelocityMod* velmod = mSimStateData->getVelocityModData(); if (linAcc) velmod->setLinearVelModPerSec(*linAcc); @@ -292,12 +335,12 @@ void BodySim::clearSpatialAcceleration(bool force, bool torque) } } -void BodySim::addSpatialVelocity(PxPool* simStateDataPool, const PxVec3* linVelDelta, const PxVec3* angVelDelta) +void BodySim::addSpatialVelocity(const PxVec3* linVelDelta, const PxVec3* angVelDelta) { notifyAddSpatialVelocity(); if (!mSimStateData || !mSimStateData->isVelMod()) - setupSimStateData(simStateDataPool, false); + setupSimStateData(false); VelocityMod* velmod = mSimStateData->getVelocityModData(); if (linVelDelta) @@ -330,9 +373,9 @@ void BodySim::raiseVelocityModFlagAndNotify(VelocityModFlags flag) raiseVelocityModFlag(flag); if (!isArticulationLink()) - getScene().getVelocityModifyMap().growAndSet(getNodeIndex().index()); + mScene.getVelocityModifyMap().growAndSet(getNodeIndex().index()); else - getScene().addDirtyArticulationSim(getArticulation()); + mScene.addDirtyArticulationSim(getArticulation()); } void BodySim::postActorFlagChange(PxU32 oldFlags, PxU32 newFlags) @@ -368,78 +411,23 @@ void BodySim::postSetWakeCounter(PxReal t, bool forceWakeUp) } } -static void updateBPGroup(ActorSim* sim) -{ - PxU32 nbElems = sim->getNbElements(); - ElementSim** elems = sim->getElements(); - while (nbElems--) - { - ShapeSim* current = static_cast(*elems++); - current->updateBPGroup(); - } -} - -void BodySim::postSwitchToKinematic() -{ - initKinematicStateBase(getBodyCore(), false); - - // - interactions need to get refiltered to make sure that kinematic-kinematic and kinematic-static pairs get suppressed - // - unlike postSwitchToDynamic(), constraint interactions are not marked dirty here because a transition to kinematic will put the object asleep which in turn - // triggers onDeactivate_() on the constraint pairs that are active. If such pairs get deactivated, they will get removed from the list of active breakable - // constraints automatically. - setActorsInteractionsDirty(InteractionDirtyFlag::eBODY_KINEMATIC, NULL, InteractionFlag::eFILTERABLE); - - getScene().getSimpleIslandManager()->setKinematic(mNodeIndex); - - updateBPGroup(this); -} - -void BodySim::postSwitchToDynamic() -{ - mScene.getSimpleIslandManager()->setDynamic(mNodeIndex); - - setForcesToDefaults(true); - - if(getConstraintGroup()) - getConstraintGroup()->markForProjectionTreeRebuild(mScene.getProjectionManager()); - - // - interactions need to get refiltered to make sure that former kinematic-kinematic and kinematic-static pairs get enabled - // - switching from kinematic to dynamic does not change the sleep state of the body. The constraint interactions are marked dirty - // to check later whether they need to be activated plus potentially tracked for constraint break testing. This special treatment - // is necessary because constraints between two kinematic bodies are considered inactive, no matter whether one of the kinematics - // is active (has a target) or not. - setActorsInteractionsDirty(InteractionDirtyFlag::eBODY_KINEMATIC, NULL, InteractionFlag::eFILTERABLE | InteractionFlag::eCONSTRAINT); - - clearInternalFlag(BF_KINEMATIC_MOVE_FLAGS); - - if(isActive()) - mScene.swapInActiveBodyList(*this); - - // - updateBPGroup(this); -} - -void BodySim::postPosePreviewChange(const PxU32 posePreviewFlag) +void BodySim::postPosePreviewChange(PxU32 posePreviewFlag) { if (isActive()) { if (posePreviewFlag & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW) - getScene().addToPosePreviewList(*this); + mScene.addToPosePreviewList(*this); else - getScene().removeFromPosePreviewList(*this); + mScene.removeFromPosePreviewList(*this); } else - PX_ASSERT(!getScene().isInPosePreviewList(*this)); + PX_ASSERT(!mScene.isInPosePreviewList(*this)); } -//-------------------------------------------------------------- -// -// Sleeping -// -//-------------------------------------------------------------- - void BodySim::activate() { + BodyCore& core = getBodyCore(); + // Activate body { PX_ASSERT((!isKinematic()) || notInScene() || readInternalFlag(InternalFlags(BF_KINEMATIC_MOVED | BF_KINEMATIC_SURFACE_VELOCITY))); // kinematics should only get activated when a target is set. @@ -448,14 +436,13 @@ void BodySim::activate() { mLLBody.mInternalFlags &= (~PxsRigidBody::eFROZEN); // Put in list of activated bodies. The list gets cleared at the end of a sim step after the sleep callbacks have been fired. - getScene().onBodyWakeUp(this); + mScene.onBodyWakeUp(this); } - BodyCore& core = getBodyCore(); if(core.getFlags() & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW) { - PX_ASSERT(!getScene().isInPosePreviewList(*this)); - getScene().addToPosePreviewList(*this); + PX_ASSERT(!mScene.isInPosePreviewList(*this)); + mScene.addToPosePreviewList(*this); } createSqBounds(); } @@ -463,30 +450,20 @@ void BodySim::activate() activateInteractions(*this); //set speculative CCD bit map if speculative CCD flag is on - { - BodyCore& core = getBodyCore(); - if (core.getFlags() & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) - { - if (isArticulationLink()) - { - if (getNodeIndex().isValid()) - getScene().setSpeculativeCCDArticulationLink(getNodeIndex().index()); - } - else - getScene().setSpeculativeCCDRigidBody(getNodeIndex().index()); - } - } + if(core.getFlags() & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) + addToSpeculativeCCDMap(); } void BodySim::deactivate() { deactivateInteractions(*this); + BodyCore& core = getBodyCore(); + // Deactivate body { PX_ASSERT((!isKinematic()) || notInScene() || !readInternalFlag(BF_KINEMATIC_MOVED)); // kinematics should only get deactivated when no target is set. // exception: object gets newly added, then the state change will happen later - BodyCore& core = getBodyCore(); if(!readInternalFlag(BF_ON_DEATHROW)) { // Set velocity to 0. @@ -500,33 +477,21 @@ void BodySim::deactivate() } if(!isArticulationLink()) // Articulations have their own sleep logic. - getScene().onBodySleep(this); + mScene.onBodySleep(this); if(core.getFlags() & PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW) { - PX_ASSERT(getScene().isInPosePreviewList(*this)); - getScene().removeFromPosePreviewList(*this); + PX_ASSERT(mScene.isInPosePreviewList(*this)); + mScene.removeFromPosePreviewList(*this); } destroySqBounds(); } // reset speculative CCD bit map if speculative CCD flag is on - { - BodyCore& core = getBodyCore(); - if (core.getFlags() & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) - { - if (isArticulationLink()) - { - if (getNodeIndex().isValid()) - getScene().resetSpeculativeCCDArticulationLink(getNodeIndex().index()); - } - else - getScene().resetSpeculativeCCDRigidBody(getNodeIndex().index()); - } - } + if(core.getFlags() & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) + removeFromSpeculativeCCDMap(); } - void BodySim::wakeUp() { setActive(true); @@ -581,31 +546,26 @@ void BodySim::internalWakeUpBase(PxReal wakeCounterValue) //this one can only in void BodySim::notifyReadyForSleeping() { if(mArticulation == NULL) - getScene().getSimpleIslandManager()->deactivateNode(mNodeIndex); + mScene.getSimpleIslandManager()->deactivateNode(mNodeIndex); } void BodySim::notifyNotReadyForSleeping() { - getScene().getSimpleIslandManager()->activateNode(mNodeIndex); + mScene.getSimpleIslandManager()->activateNode(mNodeIndex); } void BodySim::notifyWakeUp() { - getScene().getSimpleIslandManager()->activateNode(mNodeIndex); + mScene.getSimpleIslandManager()->activateNode(mNodeIndex); } void BodySim::notifyPutToSleep() { - getScene().getSimpleIslandManager()->putNodeToSleep(mNodeIndex); -} - -void BodySim::resetSleepFilter() -{ - mLLBody.sleepAngVelAcc = PxVec3(0.0f); - mLLBody.sleepLinVelAcc = PxVec3(0.0f); + mScene.getSimpleIslandManager()->putNodeToSleep(mNodeIndex); } //This function will be called by CPU sleepCheck code +// PT: TODO: actually this seems to be only called by the articulation sim code, while regular rigid bodies use a copy of that code in LowLevelDynamics? PxReal BodySim::updateWakeCounter(PxReal dt, PxReal energyThreshold, const Cm::SpatialVector& motionVelocity) { // update the body's sleep state and @@ -648,7 +608,7 @@ PxReal BodySim::updateWakeCounter(PxReal dt, PxReal energyThreshold, const Cm::S if (normalizedEnergy >= threshold) { PX_ASSERT(isActive()); - resetSleepFilter(); + mLLBody.resetSleepFilter(); const float factor = threshold == 0.0f ? 2.0f : PxMin(normalizedEnergy/threshold, 2.0f); PxReal oldWc = wc; wc = factor * 0.5f * wakeCounterResetTime + dt * (clusterFactor - 1.0f); @@ -669,143 +629,18 @@ PxReal BodySim::updateWakeCounter(PxReal dt, PxReal energyThreshold, const Cm::S return wc; } -//-------------------------------------------------------------- -// -// Kinematics -// -//-------------------------------------------------------------- - PX_FORCE_INLINE void BodySim::initKinematicStateBase(BodyCore&, bool asPartOfCreation) { PX_ASSERT(!readInternalFlag(BF_KINEMATIC_MOVED)); if (!asPartOfCreation && isActive()) - getScene().swapInActiveBodyList(*this); + mScene.swapInActiveBodyList(*this); //mLLBody.setAccelerationV(Cm::SpatialVector::zero()); // Need to be before setting setRigidBodyFlag::KINEMATIC - - if (getConstraintGroup()) - getConstraintGroup()->markForProjectionTreeRebuild(getScene().getProjectionManager()); } -void BodySim::calculateKinematicVelocity(PxReal oneOverDt) -{ - PX_ASSERT(isKinematic()); - - /*------------------------------------------------\ - | kinematic bodies are moved directly by the user and are not influenced by external forces - | we simply determine the distance moved since the last simulation frame and - | assign the appropriate delta to the velocity. This vel will be used to shove dynamic - | objects in the solver. - | We have to do this like so in a delayed way, because when the user sets the target pos the dt is not - | yet known. - \------------------------------------------------*/ - PX_ASSERT(isActive()); - - BodyCore& core = getBodyCore(); - - if (readInternalFlag(BF_KINEMATIC_MOVED)) - { - clearInternalFlag(InternalFlags(BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2)); - const SimStateData* kData = getSimStateData(true); - PX_ASSERT(kData); - PX_ASSERT(kData->isKine()); - PX_ASSERT(kData->getKinematicData()->targetValid); - PxVec3 linVelLL, angVelLL; - const PxTransform targetPose = kData->getKinematicData()->targetPose; - const PxTransform& currBody2World = getBody2World(); - - //the kinematic target pose is now the target of the body (CoM) and not the actor. - - PxVec3 deltaPos = targetPose.p; - deltaPos -= currBody2World.p; - linVelLL = deltaPos * oneOverDt; - - PxQuat q = targetPose.q * currBody2World.q.getConjugate(); - - if (q.w < 0) //shortest angle. - q = -q; - - PxReal angle; - PxVec3 axis; - q.toRadiansAndUnitAxis(angle, axis); - angVelLL = axis * angle * oneOverDt; - - core.getCore().linearVelocity = linVelLL; - core.getCore().angularVelocity = angVelLL; - - // Moving a kinematic should trigger a wakeUp call on a higher level. - PX_ASSERT(core.getWakeCounter()>0); - PX_ASSERT(isActive()); - - } - else if (!readInternalFlag(BF_KINEMATIC_SURFACE_VELOCITY)) - { - core.setLinearVelocity(PxVec3(0.0f), true); - core.setAngularVelocity(PxVec3(0.0f), true); - } -} - -void BodySim::updateKinematicPose() -{ - /*------------------------------------------------\ - | kinematic bodies are moved directly by the user and are not influenced by external forces - | we simply determine the distance moved since the last simulation frame and - | assign the appropriate delta to the velocity. This vel will be used to shove dynamic - | objects in the solver. - | We have to do this like so in a delayed way, because when the user sets the target pos the dt is not - | yet known. - \------------------------------------------------*/ - - PX_ASSERT(isKinematic()); - PX_ASSERT(isActive()); - - if (readInternalFlag(BF_KINEMATIC_MOVED)) - { - clearInternalFlag(InternalFlags(BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2)); - const SimStateData* kData = getSimStateData(true); - PX_ASSERT(kData); - PX_ASSERT(kData->isKine()); - PX_ASSERT(kData->getKinematicData()->targetValid); - - const PxTransform targetPose = kData->getKinematicData()->targetPose; - getBodyCore().getCore().body2World = targetPose; - } -} - -bool BodySim::deactivateKinematic() -{ - BodyCore& core = getBodyCore(); - if(readInternalFlag(BF_KINEMATIC_SETTLING_2)) - { - clearInternalFlag(BF_KINEMATIC_SETTLING_2); - core.setWakeCounterFromSim(0); // For sleeping objects the wake counter must be 0. This needs to hold for kinematics too. - notifyReadyForSleeping(); - notifyPutToSleep(); - setActive(false); - return true; - } - else if (readInternalFlag(BF_KINEMATIC_SETTLING)) - { - clearInternalFlag(BF_KINEMATIC_SETTLING); - raiseInternalFlag(BF_KINEMATIC_SETTLING_2); - } - else if (!readInternalFlag(BF_KINEMATIC_SURFACE_VELOCITY)) - { - clearInternalFlag(BF_KINEMATIC_MOVED); - raiseInternalFlag(BF_KINEMATIC_SETTLING); - } - return false; -} - -//-------------------------------------------------------------- -// -// Miscellaneous -// -//-------------------------------------------------------------- - void BodySim::updateForces(PxReal dt, PxsRigidBody** updatedBodySims, PxU32* updatedBodyNodeIndices, PxU32& index, Cm::SpatialVector* acceleration) { PxVec3 linVelDt(0.0f), angVelDt(0.0f); @@ -883,7 +718,7 @@ void BodySim::setArticulation(ArticulationSim* a, PxReal wakeCounter, bool aslee getBodyCore().setWakeCounterFromSim(wakeCounter); if (getFlagsFast() & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) - getScene().setSpeculativeCCDArticulationLink(mNodeIndex.index()); + mScene.setSpeculativeCCDArticulationLink(mNodeIndex.index()); //Articulations defer registering their shapes with the nphaseContext until the IG node index is known. { @@ -892,7 +727,7 @@ void BodySim::setArticulation(ArticulationSim* a, PxReal wakeCounter, bool aslee while (nbElements--) { ShapeSim* sim = static_cast(*current++); - getScene().getLowLevelContext()->getNphaseImplementationContext()->registerShape(mNodeIndex, sim->getCore().getCore(), sim->getElementID(), sim->getActor().getPxActor()); + mScene.getLowLevelContext()->getNphaseImplementationContext()->registerShape(mNodeIndex, sim->getCore().getCore(), sim->getElementID(), sim->getActor().getPxActor()); } } @@ -905,7 +740,7 @@ void BodySim::setArticulation(ArticulationSim* a, PxReal wakeCounter, bool aslee ElementSim** current = getElements(); PxU32 nbElements = getNbElements(); - Bp::AABBManagerBase* aabbMgr = getScene().getAABBManager(); + Bp::AABBManagerBase* aabbMgr = mScene.getAABBManager(); Bp::FilterGroup::Enum rootGroup = Bp::getFilterGroup(false, a->getRootActorIndex(), false); @@ -978,7 +813,7 @@ void BodySim::freezeTransforms(PxBitMapPinned* shapeChangedMap) void BodySim::disableCompound() { if(isActive()) - getScene().removeFromActiveCompoundBodyList(*this); + mScene.removeFromActiveCompoundBodyList(*this); clearInternalFlag(BF_IS_COMPOUND_RIGID); } diff --git a/physx/source/simulationcontroller/src/ScBodySim.h b/physx/source/simulationcontroller/src/ScBodySim.h index d00841002..5ec172587 100644 --- a/physx/source/simulationcontroller/src/ScBodySim.h +++ b/physx/source/simulationcontroller/src/ScBodySim.h @@ -35,7 +35,6 @@ #include "PxvDynamics.h" #include "ScBodyCore.h" #include "ScSimStateData.h" -#include "ScConstraintGroupNode.h" #include "PxRigidDynamic.h" #include "PxsRigidBody.h" @@ -58,50 +57,17 @@ namespace Sc class BodySim : public RigidSim { - public: - //enum InternalFlags - //{ - // //BF_DISABLE_GRAVITY = 1 << 0, // Don't apply the scene's gravity - - // BF_HAS_STATIC_TOUCH = 1 << 1, // Set when a body is part of an island with static contacts. Needed to be able to recalculate adaptive force if this changes - // BF_KINEMATIC_MOVED = 1 << 2, // Set when the kinematic was moved - - // BF_ON_DEATHROW = 1 << 3, // Set when the body is destroyed - - // BF_IS_IN_SLEEP_LIST = 1 << 4, // Set when the body is added to the list of bodies which were put to sleep - // BF_IS_IN_WAKEUP_LIST = 1 << 5, // Set when the body is added to the list of bodies which were woken up - // BF_SLEEP_NOTIFY = 1 << 6, // A sleep notification should be sent for this body (and not a wakeup event, even if the body is part of the woken list as well) - // BF_WAKEUP_NOTIFY = 1 << 7, // A wake up notification should be sent for this body (and not a sleep event, even if the body is part of the sleep list as well) - - // BF_HAS_CONSTRAINTS = 1 << 8, // Set if the body has one or more constraints - // BF_KINEMATIC_SETTLING = 1 << 9, // Set when the body was moved kinematically last frame - // BF_KINEMATIC_SETTLING_2 = 1 << 10, - // BF_KINEMATIC_MOVE_FLAGS = BF_KINEMATIC_MOVED | BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2, //Used to clear kinematic masks in 1 call - // BF_KINEMATIC_SURFACE_VELOCITY = 1 << 11, //Set when the application calls setKinematicVelocity. Actor remains awake until application calls clearKinematicVelocity. - // BF_IS_COMPOUND_RIGID = 1 << 12 // Set when the body is a compound actor, we dont want to set the sq bounds - - // // PT: WARNING: flags stored on 16-bits now. - //}; - public: BodySim(Scene&, BodyCore&, bool); virtual ~BodySim(); - private: - bool setupSimStateData(PxPool* simStateDataPool, const bool isKinematic); - void tearDownSimStateData(PxPool* simStateDataPool, const bool isKinematic); - public: - void switchToKinematic(PxPool* simStateDataPool); - void switchToDynamic(PxPool* simStateDataPool); + void switchToKinematic(); + void switchToDynamic(); - private: - void postSwitchToKinematic(); - void postSwitchToDynamic(); - public: PX_FORCE_INLINE const SimStateData* getSimStateData(bool isKinematic) const { return (mSimStateData && (checkSimStateKinematicStatus(isKinematic)) ? mSimStateData : NULL); } PX_FORCE_INLINE SimStateData* getSimStateData(bool isKinematic) { return (mSimStateData && (checkSimStateKinematicStatus(isKinematic)) ? mSimStateData : NULL); } PX_FORCE_INLINE SimStateData* getSimStateData_Unchecked() const { return mSimStateData; } - PX_FORCE_INLINE bool checkSimStateKinematicStatus(const bool isKinematic) const + PX_FORCE_INLINE bool checkSimStateKinematicStatus(bool isKinematic) const { PX_ASSERT(mSimStateData); return mSimStateData->isKine() == isKinematic; @@ -109,34 +75,30 @@ namespace Sc void setKinematicTarget(const PxTransform& p); - void addSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc); - void setSpatialAcceleration(PxPool* simStateDataPool, const PxVec3* linAcc, const PxVec3* angAcc); + void addSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc); + void setSpatialAcceleration(const PxVec3* linAcc, const PxVec3* angAcc); void clearSpatialAcceleration(bool force, bool torque); - void addSpatialVelocity(PxPool* simStateDataPool, const PxVec3* linVelDelta, const PxVec3* angVelDelta); + void addSpatialVelocity(const PxVec3* linVelDelta, const PxVec3* angVelDelta); void clearSpatialVelocity(bool force, bool torque); - private: - void raiseVelocityModFlagAndNotify(VelocityModFlags flag); - PX_FORCE_INLINE void notifyAddSpatialAcceleration() { raiseVelocityModFlagAndNotify(VMF_ACC_DIRTY); } - PX_FORCE_INLINE void notifyClearSpatialAcceleration() { raiseVelocityModFlagAndNotify(VMF_ACC_DIRTY); } - PX_FORCE_INLINE void notifyAddSpatialVelocity() { raiseVelocityModFlagAndNotify(VMF_VEL_DIRTY); } - PX_FORCE_INLINE void notifyClearSpatialVelocity() { raiseVelocityModFlagAndNotify(VMF_VEL_DIRTY); } - public: + void updateCached(PxBitMapPinned* shapeChangedMap); void updateCached(PxsTransformCache& transformCache, Bp::BoundsArray& boundsArray); - void updateContactDistance(PxReal* contactDistance, const PxReal dt, const Bp::BoundsArray& boundsArray); + void updateContactDistance(PxReal* contactDistance, PxReal dt, const Bp::BoundsArray& boundsArray); // hooks for actions in body core when it's attached to a sim object. Generally // we get called after the attribute changed. - virtual void postActorFlagChange(PxU32 oldFlags, PxU32 newFlags); + virtual void postActorFlagChange(PxU32 oldFlags, PxU32 newFlags) PX_OVERRIDE; void postBody2WorldChange(); void postSetWakeCounter(PxReal t, bool forceWakeUp); - void postPosePreviewChange(const PxU32 posePreviewFlag); // called when PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW changes + void postPosePreviewChange(PxU32 posePreviewFlag); // called when PxRigidBodyFlag::eENABLE_POSE_INTEGRATION_PREVIEW changes PX_FORCE_INLINE const PxTransform& getBody2World() const { return getBodyCore().getCore().body2World; } PX_FORCE_INLINE const PxTransform& getBody2Actor() const { return getBodyCore().getCore().getBody2Actor(); } PX_FORCE_INLINE const PxsRigidBody& getLowLevelBody() const { return mLLBody; } PX_FORCE_INLINE PxsRigidBody& getLowLevelBody() { return mLLBody; } + + void setActive(bool active, bool asPartOfCreation=false); void wakeUp(); // note: for user API call purposes only, i.e., use from BodyCore. For simulation internal purposes there is internalWakeUp(). void putToSleep(); @@ -144,21 +106,10 @@ namespace Sc static PxU32 getRigidBodyOffset() { return PxU32(PX_OFFSET_OF_RT(BodySim, mLLBody));} - virtual void activate(); - virtual void deactivate(); - - //--------------------------------------------------------------------------------- - // Constraint projection - //--------------------------------------------------------------------------------- - PX_FORCE_INLINE ConstraintGroupNode* getConstraintGroup() { return mConstraintGroup; } - PX_FORCE_INLINE void setConstraintGroup(ConstraintGroupNode* node) { mConstraintGroup = node; } + void activate(); + void deactivate(); - //// A list of active projection trees in the scene might be better - //PX_FORCE_INLINE void projectPose() { PX_ASSERT(mConstraintGroup); ConstraintGroupNode::projectPose(*mConstraintGroup); } - - //--------------------------------------------------------------------------------- // Kinematics - //--------------------------------------------------------------------------------- PX_FORCE_INLINE bool isKinematic() const { return getBodyCore().getFlags() & PxRigidBodyFlag::eKINEMATIC; } PX_FORCE_INLINE bool isArticulationLink() const { return getActorType() == PxActorType::eARTICULATION_LINK; } PX_FORCE_INLINE bool hasForcedKinematicNotif() const @@ -168,64 +119,38 @@ namespace Sc void calculateKinematicVelocity(PxReal oneOverDt); void updateKinematicPose(); bool deactivateKinematic(); - private: - PX_FORCE_INLINE void initKinematicStateBase(BodyCore&, bool asPartOfCreation); - - //--------------------------------------------------------------------------------- // Sleeping - //--------------------------------------------------------------------------------- - public: - virtual void internalWakeUp(PxReal wakeCounterValue); + virtual void internalWakeUp(PxReal wakeCounterValue) PX_OVERRIDE; // PT: TODO: does it need to be virtual? void internalWakeUpArticulationLink(PxReal wakeCounterValue); // called by ArticulationSim to wake up this link PxReal updateWakeCounter(PxReal dt, PxReal energyThreshold, const Cm::SpatialVector& motionVelocity); - void resetSleepFilter(); void notifyReadyForSleeping(); // inform the sleep island generation system that the body is ready for sleeping void notifyNotReadyForSleeping(); // inform the sleep island generation system that the body is not ready for sleeping PX_FORCE_INLINE bool checkSleepReadinessBesidesWakeCounter(); // for API triggered changes to test sleep readiness - virtual void registerCountedInteraction() { mLLBody.getCore().numCountedInteractions++; PX_ASSERT(mLLBody.getCore().numCountedInteractions); } - virtual void unregisterCountedInteraction() { PX_ASSERT(mLLBody.getCore().numCountedInteractions); mLLBody.getCore().numCountedInteractions--; } - virtual PxU32 getNumCountedInteractions() const { return mLLBody.getCore().numCountedInteractions; } + // PT: TODO: this is only used for the rigid bodies' sleep check, the implementations in derived classes look useless + virtual void registerCountedInteraction() PX_OVERRIDE { mLLBody.getCore().numCountedInteractions++; PX_ASSERT(mLLBody.getCore().numCountedInteractions); } + virtual void unregisterCountedInteraction() PX_OVERRIDE { PX_ASSERT(mLLBody.getCore().numCountedInteractions); mLLBody.getCore().numCountedInteractions--; } + // PT: TODO: this is only used for the rigid bodies' sleep check called from the articulation sim code + virtual PxU32 getNumCountedInteractions() const PX_OVERRIDE { return mLLBody.getCore().numCountedInteractions; } PX_FORCE_INLINE PxIntBool isFrozen() const { return PxIntBool(mLLBody.mInternalFlags & PxsRigidBody::eFROZEN); } - private: - PX_FORCE_INLINE void notifyWakeUp(); // inform the sleep island generation system that the object got woken up - PX_FORCE_INLINE void notifyPutToSleep(); // inform the sleep island generation system that the object was put to sleep - PX_FORCE_INLINE void internalWakeUpBase(PxReal wakeCounterValue); - //--------------------------------------------------------------------------------- // External velocity changes - //--------------------------------------------------------------------------------- - public: - void updateForces(PxReal dt, PxsRigidBody** updatedBodySims, PxU32* updatedBodyNodeIndices, - PxU32& index, Cm::SpatialVector* acceleration); + void updateForces(PxReal dt, PxsRigidBody** updatedBodySims, PxU32* updatedBodyNodeIndices, PxU32& index, Cm::SpatialVector* acceleration); PX_FORCE_INLINE bool readVelocityModFlag(VelocityModFlags f) { return (mVelModState & f) != 0; } - private: - PX_FORCE_INLINE void raiseVelocityModFlag(VelocityModFlags f) { mVelModState |= f; } - PX_FORCE_INLINE void clearVelocityModFlag(VelocityModFlags f) { mVelModState &= ~f; } - - PX_FORCE_INLINE void setForcesToDefaults(bool enableGravity); - //--------------------------------------------------------------------------------- // Miscellaneous - //--------------------------------------------------------------------------------- - public: - /* PX_FORCE_INLINE PxU16 getInternalFlag() const { return mInternalFlags; } - PX_FORCE_INLINE PxU16 readInternalFlag(InternalFlags flag) const { return PxU16(mInternalFlags & flag); } - PX_FORCE_INLINE void raiseInternalFlag(InternalFlags flag) { mInternalFlags |= flag; } - PX_FORCE_INLINE void clearInternalFlag(InternalFlags flag) { mInternalFlags &= ~flag; }*/ - PX_FORCE_INLINE PxU32 getFlagsFast() const { return getBodyCore().getFlags(); } - - PX_FORCE_INLINE BodyCore& getBodyCore() const { return static_cast(getRigidCore()); } + PX_FORCE_INLINE bool notInScene() const { return mActiveListIndex == SC_NOT_IN_SCENE_INDEX; } + PX_FORCE_INLINE PxU32 getNbShapes() const { return mShapes.getCount(); } + PX_FORCE_INLINE PxU32 getFlagsFast() const { return getBodyCore().getFlags(); } + PX_FORCE_INLINE BodyCore& getBodyCore() const { return static_cast(getRigidCore()); } - PX_INLINE ArticulationSim* getArticulation() const { return mArticulation; } + PX_FORCE_INLINE ArticulationSim* getArticulation() const { return mArticulation; } void setArticulation(ArticulationSim* a, PxReal wakeCounter, bool asleep, PxU32 bodyIndex); - //PX_FORCE_INLINE IG::NodeIndex getNodeIndex() const { return mNodeIndex; } - PX_FORCE_INLINE void onConstraintAttach() { raiseInternalFlag(BF_HAS_CONSTRAINTS); registerCountedInteraction(); } void onConstraintDetach(); @@ -237,34 +162,23 @@ namespace Sc mSimStateData->getKinematicData()->targetPose.p -= shift; } - PX_FORCE_INLINE bool notInScene() const { return mActiveListIndex == SC_NOT_IN_SCENE_INDEX; } - PX_FORCE_INLINE bool usingSqKinematicTarget() const { const PxU32 ktFlags(PxRigidBodyFlag::eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES | PxRigidBodyFlag::eKINEMATIC); return (getFlagsFast()&ktFlags) == ktFlags; } - PX_FORCE_INLINE PxU32 getNbShapes() const { return mShapes.getCount(); } - void createSqBounds(); void destroySqBounds(); void freezeTransforms(PxBitMapPinned* shapeChangedMap); - void invalidateSqBounds(); + + void addToSpeculativeCCDMap(); + void removeFromSpeculativeCCDMap(); private: - //--------------------------------------------------------------------------------- // Base body - //--------------------------------------------------------------------------------- PxsRigidBody mLLBody; - //--------------------------------------------------------------------------------- - // Island manager - //--------------------------------------------------------------------------------- - // IG::NodeIndex mNodeIndex; - - //--------------------------------------------------------------------------------- // External velocity changes - //--------------------------------------------------------------------------------- // VelocityMod data allocated on the fly when the user applies velocity changes // which need to be accumulated. // VelMod dirty flags stored in BodySim so we can save ourselves the expense of looking at @@ -273,18 +187,29 @@ namespace Sc SimStateData* mSimStateData; PxU8 mVelModState; - //--------------------------------------------------------------------------------- // Articulation - //--------------------------------------------------------------------------------- ArticulationSim* mArticulation; // NULL if not in an articulation - //--------------------------------------------------------------------------------- // Joints & joint groups - //--------------------------------------------------------------------------------- - // This is a tree data structure that gives us the projection order of joints in which this body is the tree root. - // note: the link of the root body is not necces. the root link due to the re-rooting of the articulation! - ConstraintGroupNode* mConstraintGroup; + bool setupSimStateData(bool isKinematic); + void tearDownSimStateData(bool isKinematic); + + void raiseVelocityModFlagAndNotify(VelocityModFlags flag); + PX_FORCE_INLINE void notifyAddSpatialAcceleration() { raiseVelocityModFlagAndNotify(VMF_ACC_DIRTY); } + PX_FORCE_INLINE void notifyClearSpatialAcceleration() { raiseVelocityModFlagAndNotify(VMF_ACC_DIRTY); } + PX_FORCE_INLINE void notifyAddSpatialVelocity() { raiseVelocityModFlagAndNotify(VMF_VEL_DIRTY); } + PX_FORCE_INLINE void notifyClearSpatialVelocity() { raiseVelocityModFlagAndNotify(VMF_VEL_DIRTY); } + + PX_FORCE_INLINE void initKinematicStateBase(BodyCore&, bool asPartOfCreation); + + void notifyWakeUp(); // inform the sleep island generation system that the object got woken up + void notifyPutToSleep(); // inform the sleep island generation system that the object was put to sleep + void internalWakeUpBase(PxReal wakeCounterValue); + + PX_FORCE_INLINE void raiseVelocityModFlag(VelocityModFlags f) { mVelModState |= f; } + PX_FORCE_INLINE void clearVelocityModFlag(VelocityModFlags f) { mVelModState &= ~f; } + PX_FORCE_INLINE void setForcesToDefaults(bool enableGravity); }; #if PX_VC diff --git a/physx/source/simulationcontroller/src/ScBroadphase.cpp b/physx/source/simulationcontroller/src/ScBroadphase.cpp new file mode 100644 index 000000000..cbd1fab28 --- /dev/null +++ b/physx/source/simulationcontroller/src/ScBroadphase.cpp @@ -0,0 +1,132 @@ +// 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. + +#include "ScBroadphase.h" +#include "BpAABBManagerBase.h" +#include "ScShapeSim.h" + +using namespace physx; +using namespace Sc; +using namespace Bp; + +/////////////////////////////////////////////////////////////////////////////// + +BroadphaseManager::BroadphaseManager() : + mBroadPhaseCallback (NULL), + mOutOfBoundsIDs ("sceneOutOfBoundsIds") +{ +} + +BroadphaseManager::~BroadphaseManager() +{ +} + +void BroadphaseManager::prepareOutOfBoundsCallbacks(AABBManagerBase* aabbManager) +{ + AABBManagerBase::OutOfBoundsData data; + if(!aabbManager->getOutOfBoundsObjects(data)) + return; + + PxU32 nbOut = data.mNbOutOfBoundsObjects; + void** outObjects = data.mOutOfBoundsObjects; + + mOutOfBoundsIDs.clear(); + + while(nbOut--) + { + const ElementSim* volume = reinterpret_cast(*outObjects++); + + const Sc::ShapeSim* sim = static_cast(volume); + + mOutOfBoundsIDs.pushBack(sim->getElementID()); + } +} + +bool BroadphaseManager::fireOutOfBoundsCallbacks(Bp::AABBManagerBase* aabbManager, const ObjectIDTracker& tracker) +{ + AABBManagerBase::OutOfBoundsData data; + if(!aabbManager->getOutOfBoundsObjects(data)) + return false; + + bool outputWarning = false; + + PxBroadPhaseCallback* cb = mBroadPhaseCallback; + + // Actors + { + PxU32 nbOut = data.mNbOutOfBoundsObjects; + void** outObjects = data.mOutOfBoundsObjects; + + for(PxU32 i=0;i(outObjects[i]); + + Sc::ShapeSim* sim = static_cast(volume); + + // PT: TODO: I'm not sure the split between prepareOutOfBoundsCallbacks / fireOutOfBoundsCallbacks + // and the test for deletion is still needed after the removal of SCB + if(tracker.isDeletedID(mOutOfBoundsIDs[i])) + continue; + + if(cb) + { + ActorSim& actor = volume->getActor(); + RigidSim& rigidSim = static_cast(actor); + PxActor* pxActor = rigidSim.getPxActor(); + PxShape* px = sim->getPxShape(); + cb->onObjectOutOfBounds(*px, *pxActor); + } + else + outputWarning = true; + } + } + + // Aggregates + { + PxU32 nbOut = data.mNbOutOfBoundsAggregates; + void** outAgg = data.mOutOfBoundsAggregates; + + for(PxU32 i=0;i(outAgg[i]); + if(cb) + cb->onObjectOutOfBounds(*px); + else + outputWarning = true; + } + } + + aabbManager->clearOutOfBoundsObjects(); + + return outputWarning; +} + +void BroadphaseManager::flush(Bp::AABBManagerBase* /*aabbManager*/) +{ + mOutOfBoundsIDs.reset(); +} diff --git a/physx/source/simulationcontroller/src/ScCCD.cpp b/physx/source/simulationcontroller/src/ScCCD.cpp index 606559596..c3c0ae870 100644 --- a/physx/source/simulationcontroller/src/ScCCD.cpp +++ b/physx/source/simulationcontroller/src/ScCCD.cpp @@ -35,13 +35,38 @@ using namespace physx; using namespace Sc; +/////////////////////////////////////////////////////////////////////////////// + +void BodySim::addToSpeculativeCCDMap() +{ + if(mNodeIndex.isValid()) + { + if(isArticulationLink()) + mScene.setSpeculativeCCDArticulationLink(mNodeIndex.index()); + else + mScene.setSpeculativeCCDRigidBody(mNodeIndex.index()); + } +} + +void BodySim::removeFromSpeculativeCCDMap() +{ + if(mNodeIndex.isValid()) + { + if(isArticulationLink()) + mScene.resetSpeculativeCCDArticulationLink(mNodeIndex.index()); + else + mScene.resetSpeculativeCCDRigidBody(mNodeIndex.index()); + } +} + // PT: TODO: consider using a non-member function for this one -void BodySim::updateContactDistance(PxReal* contactDistance, const PxReal dt, const Bp::BoundsArray& boundsArray) +void BodySim::updateContactDistance(PxReal* contactDistance, PxReal dt, const Bp::BoundsArray& boundsArray) { const PxsRigidBody& llBody = getLowLevelBody(); const PxRigidBodyFlags flags = llBody.getCore().mFlags; + // PT: TODO: no need to test eENABLE_SPECULATIVE_CCD if we parsed mSpeculativeCCDRigidBodyBitMap initially if((flags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) && !(llBody.mInternalFlags & PxsRigidBody::eFROZEN)) { // PT: if both CCD flags are enabled we're in "hybrid mode" and we only use speculative contacts for the angular part @@ -69,23 +94,24 @@ void BodySim::updateContactDistance(PxReal* contactDistance, const PxReal dt, co } } -// PT: TODO: merge this with task code -void Sc::ArticulationSim::updateContactDistance(PxReal* contactDistance, const PxReal dt, const Bp::BoundsArray& boundsArray) +void Sc::ArticulationSim::updateContactDistance(PxReal* contactDistance, PxReal dt, const Bp::BoundsArray& boundsArray) { const PxU32 size = mBodies.size(); for(PxU32 i=0; iupdateContactDistance(contactDistance, dt, boundsArray); } +namespace +{ class SpeculativeCCDBaseTask : public Cm::Task { PX_NOCOPY(SpeculativeCCDBaseTask) public: const Bp::BoundsArray& mBoundsArray; - PxReal* mContactDistances; - const PxReal mDt; + float* mContactDistances; + const float mDt; - SpeculativeCCDBaseTask(PxU64 contextID, const Bp::BoundsArray& boundsArray, PxReal* contactDistances, const PxReal dt) : + SpeculativeCCDBaseTask(PxU64 contextID, const Bp::BoundsArray& boundsArray, PxReal* contactDistances, PxReal dt) : Cm::Task (contextID), mBoundsArray (boundsArray), mContactDistances (contactDistances), @@ -97,10 +123,10 @@ class SpeculativeCCDContactDistanceUpdateTask : public SpeculativeCCDBaseTask { public: static const PxU32 MaxBodies = 128; - BodySim* mBodySims[MaxBodies]; - PxU32 mNbBodies; + BodySim* mBodySims[MaxBodies]; + PxU32 mNbBodies; - SpeculativeCCDContactDistanceUpdateTask(PxU64 contextID, PxReal* contactDistances, const PxReal dt, const Bp::BoundsArray& boundsArray) : + SpeculativeCCDContactDistanceUpdateTask(PxU64 contextID, PxReal* contactDistances, PxReal dt, const Bp::BoundsArray& boundsArray) : SpeculativeCCDBaseTask (contextID, boundsArray, contactDistances, dt), mNbBodies (0) {} @@ -123,7 +149,7 @@ class SpeculativeCCDContactDistanceArticulationUpdateTask : public SpeculativeCC public: ArticulationSim* mArticulation; - SpeculativeCCDContactDistanceArticulationUpdateTask(PxU64 contextID, PxReal* contactDistances, const PxReal dt, const Bp::BoundsArray& boundsArray, ArticulationSim* sim) : + SpeculativeCCDContactDistanceArticulationUpdateTask(PxU64 contextID, PxReal* contactDistances, PxReal dt, const Bp::BoundsArray& boundsArray, ArticulationSim* sim) : SpeculativeCCDBaseTask (contextID, boundsArray, contactDistances, dt), mArticulation (sim) {} @@ -138,44 +164,62 @@ class SpeculativeCCDContactDistanceArticulationUpdateTask : public SpeculativeCC private: PX_NOCOPY(SpeculativeCCDContactDistanceArticulationUpdateTask) }; +} -static PX_FORCE_INLINE void startTask(Cm::Task* task, PxBaseTask* continuation) +static SpeculativeCCDContactDistanceUpdateTask* createCCDTask(Cm::FlushPool& pool, PxU64 contextID, PxReal* contactDistances, PxReal dt, const Bp::BoundsArray& boundsArray) { - task->setContinuation(continuation); - task->removeReference(); + return PX_PLACEMENT_NEW(pool.allocate(sizeof(SpeculativeCCDContactDistanceUpdateTask)), SpeculativeCCDContactDistanceUpdateTask)(contextID, contactDistances, dt, boundsArray); } void Sc::Scene::updateContactDistances(PxBaseTask* continuation) { - PX_PROFILE_ZONE("Scene.updateContactDistances", getContextId()); + PX_PROFILE_ZONE("Scene.updateContactDistances", mContextId); Cm::FlushPool& pool = mLLContext->getTaskPool(); IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - PxU32 index; bool hasContactDistanceChanged = mHasContactDistanceChanged; + // PT: TODO: it is quite unfortunate that we cannot shortcut parsing the bitmaps. Consider switching to arrays. + // We remove sleeping bodies from the map but we never shrink it.... + + // PT: TODO: why do we need to involve the island manager here? + // PT: TODO: why do we do that on sleeping bodies? Why don't we use mActiveBodies? + // PxArray mActiveBodies; // Sorted: kinematic before dynamic + // ===> because we remove bodies from the bitmap in BodySim::deactivate() + //calculate contact distance for speculative CCD shapes + if(1) { PxBitMap::Iterator speculativeCCDIter(mSpeculativeCCDRigidBodyBitMap); - SpeculativeCCDContactDistanceUpdateTask* ccdTask = PX_PLACEMENT_NEW(pool.allocate(sizeof(SpeculativeCCDContactDistanceUpdateTask)), SpeculativeCCDContactDistanceUpdateTask)(getContextId(), mContactDistance->begin(), mDt, *mBoundsArray); + SpeculativeCCDContactDistanceUpdateTask* ccdTask = createCCDTask(pool, mContextId, mContactDistance->begin(), mDt, *mBoundsArray); PxBitMapPinned& changedMap = mAABBManager->getChangedAABBMgActorHandleMap(); const size_t bodyOffset = PX_OFFSET_OF_RT(BodySim, getLowLevelBody()); + //printf("\n"); + //PxU32 count = 0; + + PxU32 nbBodies = 0; + PxU32 index; while((index = speculativeCCDIter.getNext()) != PxBitMap::Iterator::DONE) { PxsRigidBody* rigidBody = islandSim.getRigidBody(PxNodeIndex(index)); BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigidBody)-bodyOffset); - if (bodySim) + if(bodySim) { + //printf("%d\n", bodySim->getActiveListIndex()); + //printf("%d: %d\n", count++, bodySim->isActive()); + hasContactDistanceChanged = true; - ccdTask->mBodySims[ccdTask->mNbBodies++] = bodySim; + ccdTask->mBodySims[nbBodies++] = bodySim; // PT: ### changedMap pattern #1 // PT: TODO: isn't there a problem here? The task function will only touch the shapes whose body has the // speculative flag and isn't frozen, but here we mark all shapes as changed no matter what. + // + // Also we test some bodySim data and one bit of each ShapeSim here, not great. PxU32 nbElems = bodySim->getNbElements(); ElementSim** elems = bodySim->getElements(); while(nbElems--) @@ -185,34 +229,495 @@ void Sc::Scene::updateContactDistances(PxBaseTask* continuation) changedMap.growAndSet(sim->getElementID()); } - if(ccdTask->mNbBodies == SpeculativeCCDContactDistanceUpdateTask::MaxBodies) + // PT: TODO: better load balancing? + if(nbBodies == SpeculativeCCDContactDistanceUpdateTask::MaxBodies) { + ccdTask->mNbBodies = nbBodies; + nbBodies = 0; startTask(ccdTask, continuation); - ccdTask = PX_PLACEMENT_NEW(pool.allocate(sizeof(SpeculativeCCDContactDistanceUpdateTask)), SpeculativeCCDContactDistanceUpdateTask)(getContextId(), mContactDistance->begin(), mDt, *mBoundsArray); + + if(continuation) + ccdTask = createCCDTask(pool, mContextId, mContactDistance->begin(), mDt, *mBoundsArray); + else + ccdTask->mNbBodies = 0; // PT: no need to create a new task in single-threaded mode } } } - if(ccdTask->mNbBodies) + if(nbBodies) + { + ccdTask->mNbBodies = nbBodies; startTask(ccdTask, continuation); + } } +/* else + { + // PT: codepath without mSpeculativeCCDRigidBodyBitMap + PxU32 nb = mActiveBodies.size(); + BodyCore** bodies = mActiveBodies.begin(); + + while(nb--) + { + const BodyCore* current = *bodies++; + BodySim* bodySim = current->getSim(); + if(bodySim) + { + ... + } + } + }*/ //calculate contact distance for articulation links { - SpeculativeCCDContactDistanceArticulationUpdateTask* articulationUpdateTask = NULL; - PxBitMap::Iterator articulateCCDIter(mSpeculativeCDDArticulationBitMap); + PxU32 index; while((index = articulateCCDIter.getNext()) != PxBitMap::Iterator::DONE) { ArticulationSim* articulationSim = islandSim.getArticulationSim(PxNodeIndex(index)); if(articulationSim) { hasContactDistanceChanged = true; - articulationUpdateTask = PX_PLACEMENT_NEW(pool.allocate(sizeof(SpeculativeCCDContactDistanceArticulationUpdateTask)), SpeculativeCCDContactDistanceArticulationUpdateTask)(getContextId(), mContactDistance->begin(), mDt, *mBoundsArray, articulationSim); - startTask(articulationUpdateTask, continuation); + if(continuation) + { + SpeculativeCCDContactDistanceArticulationUpdateTask* articulationUpdateTask = PX_PLACEMENT_NEW(pool.allocate(sizeof(SpeculativeCCDContactDistanceArticulationUpdateTask)), SpeculativeCCDContactDistanceArticulationUpdateTask)(mContextId, mContactDistance->begin(), mDt, *mBoundsArray, articulationSim); + articulationUpdateTask->setContinuation(continuation); + articulationUpdateTask->removeReference(); + } + else + { + articulationSim->updateContactDistance(mContactDistance->begin(), mDt, *mBoundsArray); + } } } } mHasContactDistanceChanged = hasContactDistanceChanged; } + +/////////////////////////////////////////////////////////////////////////////// + +#include "ScNPhaseCore.h" +#include "ScShapeInteraction.h" +#include "PxsCCD.h" +#include "PxsSimulationController.h" +#include "CmTransformUtils.h" + +void Sc::Scene::setCCDContactModifyCallback(PxCCDContactModifyCallback* callback) +{ + mCCDContext->setCCDContactModifyCallback(callback); +} + +PxCCDContactModifyCallback* Sc::Scene::getCCDContactModifyCallback() const +{ + return mCCDContext->getCCDContactModifyCallback(); +} + +void Sc::Scene::setCCDMaxPasses(PxU32 ccdMaxPasses) +{ + mCCDContext->setCCDMaxPasses(ccdMaxPasses); +} + +PxU32 Sc::Scene::getCCDMaxPasses() const +{ + return mCCDContext->getCCDMaxPasses(); +} + +void Sc::Scene::setCCDThreshold(PxReal t) +{ + mCCDContext->setCCDThreshold(t); +} + +PxReal Sc::Scene::getCCDThreshold() const +{ + return mCCDContext->getCCDThreshold(); +} + +void Sc::Scene::collectPostSolverVelocitiesBeforeCCD() +{ + if(mContactReportsNeedPostSolverVelocity) + { + ActorPairReport*const* actorPairs = mNPhaseCore->getContactReportActorPairs(); + PxU32 nbActorPairs = mNPhaseCore->getNbContactReportActorPairs(); + for(PxU32 i=0; i < nbActorPairs; i++) + { + if(i < (nbActorPairs - 1)) + PxPrefetchLine(actorPairs[i+1]); + + ActorPairReport* aPair = actorPairs[i]; + + ContactStreamManager& cs = aPair->getContactStreamManager(); + + PxU32 streamManagerFlag = cs.getFlags(); + if(streamManagerFlag & ContactStreamManagerFlag::eINVALID_STREAM) + continue; + + PxU8* stream = mNPhaseCore->getContactReportPairData(cs.bufferIndex); + + if(i + 1 < nbActorPairs) + PxPrefetch(&(actorPairs[i+1]->getContactStreamManager())); + + if(!cs.extraDataSize) + continue; + else if (streamManagerFlag & ContactStreamManagerFlag::eNEEDS_POST_SOLVER_VELOCITY) + cs.setContactReportPostSolverVelocity(stream, aPair->getActorA(), aPair->getActorB()); + } + } +} + +void Sc::Scene::updateCCDMultiPass(PxBaseTask* parentContinuation) +{ + getCcdBodies().forceSize_Unsafe(mSimulationControllerCallback->getNbCcdBodies()); + + // second run of the broadphase for making sure objects we have integrated did not tunnel. + if(mPublicFlags & PxSceneFlag::eENABLE_CCD) + { + if(mContactReportsNeedPostSolverVelocity) + { + // the CCD code will overwrite the post solver body velocities, hence, we need to extract the info + // first if any CCD enabled pair requested it. + collectPostSolverVelocitiesBeforeCCD(); + } + + //We use 2 CCD task chains to be able to chain together an arbitrary number of ccd passes + if(mPostCCDPass.size() != 2) + { + mPostCCDPass.clear(); + mUpdateCCDSinglePass.clear(); + mCCDBroadPhase.clear(); + mCCDBroadPhaseAABB.clear(); + mPostCCDPass.reserve(2); + mUpdateCCDSinglePass.reserve(2); + mUpdateCCDSinglePass2.reserve(2); + mUpdateCCDSinglePass3.reserve(2); + mCCDBroadPhase.reserve(2); + mCCDBroadPhaseAABB.reserve(2); + for (int j = 0; j < 2; j++) + { + mPostCCDPass.pushBack(Cm::DelegateTask(mContextId, this, "ScScene.postCCDPass")); + mUpdateCCDSinglePass.pushBack(Cm::DelegateTask(mContextId, this, "ScScene.updateCCDSinglePass")); + mUpdateCCDSinglePass2.pushBack(Cm::DelegateTask(mContextId, this, "ScScene.updateCCDSinglePassStage2")); + mUpdateCCDSinglePass3.pushBack(Cm::DelegateTask(mContextId, this, "ScScene.updateCCDSinglePassStage3")); + mCCDBroadPhase.pushBack(Cm::DelegateTask(mContextId, this, "ScScene.ccdBroadPhase")); + mCCDBroadPhaseAABB.pushBack(Cm::DelegateTask(mContextId, this, "ScScene.ccdBroadPhaseAABB")); + } + } + + //reset thread context in a place we know all tasks possibly accessing it, are in sync with. (see US6664) + mLLContext->resetThreadContexts(); + + mCCDContext->updateCCDBegin(); + + mCCDBroadPhase[0].setContinuation(parentContinuation); + mCCDBroadPhaseAABB[0].setContinuation(&mCCDBroadPhase[0]); + mCCDBroadPhase[0].removeReference(); + mCCDBroadPhaseAABB[0].removeReference(); + } +} + +namespace +{ +class UpdateCCDBoundsTask : public Cm::Task +{ + Bp::BoundsArray* mBoundArray; + PxsTransformCache* mTransformCache; + BodySim** mBodySims; + PxU32 mNbToProcess; + PxI32* mNumFastMovingShapes; + +public: + + static const PxU32 MaxPerTask = 256; + + UpdateCCDBoundsTask(PxU64 contextID, Bp::BoundsArray* boundsArray, PxsTransformCache* transformCache, BodySim** bodySims, PxU32 nbToProcess, PxI32* numFastMovingShapes) : + Cm::Task (contextID), + mBoundArray (boundsArray), + mTransformCache (transformCache), + mBodySims (bodySims), + mNbToProcess (nbToProcess), + mNumFastMovingShapes(numFastMovingShapes) + { + } + + virtual const char* getName() const { return "UpdateCCDBoundsTask";} + + PxIntBool updateSweptBounds(ShapeSim* sim, BodySim* body) + { + PX_ASSERT(body==sim->getBodySim()); + + const PxU32 elementID = sim->getElementID(); + + const ShapeCore& shapeCore = sim->getCore(); + const PxTransform& endPose = mTransformCache->getTransformCache(elementID).transform; + + const PxGeometry& shapeGeom = shapeCore.getGeometry(); + + const PxsRigidBody& rigidBody = body->getLowLevelBody(); + const PxsBodyCore& bodyCore = body->getBodyCore().getCore(); + PX_ALIGN(16, PxTransform shape2World); + Cm::getDynamicGlobalPoseAligned(rigidBody.mLastTransform, shapeCore.getShape2Actor(), bodyCore.getBody2Actor(), shape2World); + + const float ccdThreshold = computeCCDThreshold(shapeGeom); + PxBounds3 bounds = Gu::computeBounds(shapeGeom, endPose); + PxIntBool isFastMoving; + if(1) + { + // PT: this alternative implementation avoids computing the start bounds for slow moving objects. + isFastMoving = (shape2World.p - endPose.p).magnitudeSquared() >= ccdThreshold * ccdThreshold ? 1 : 0; + if(isFastMoving) + { + const PxBounds3 startBounds = Gu::computeBounds(shapeGeom, shape2World); + bounds.include(startBounds); + } + } + else + { + const PxBounds3 startBounds = Gu::computeBounds(shapeGeom, shape2World); + + isFastMoving = (startBounds.getCenter() - bounds.getCenter()).magnitudeSquared() >= ccdThreshold * ccdThreshold ? 1 : 0; + + if(isFastMoving) + bounds.include(startBounds); + } + + PX_ASSERT(bounds.minimum.x <= bounds.maximum.x + && bounds.minimum.y <= bounds.maximum.y + && bounds.minimum.z <= bounds.maximum.z); + + mBoundArray->setBounds(bounds, elementID); + + return isFastMoving; + } + + virtual void runInternal() + { + PxU32 activeShapes = 0; + const PxU32 nb = mNbToProcess; + for(PxU32 i=0; i(*elems++); + if(sim->getFlags() & PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) + { + const PxIntBool fastMovingShape = updateSweptBounds(sim, &bodySim); + activeShapes += fastMovingShape; + + isFastMoving = isFastMoving | fastMovingShape; + } + } + + bodySim.getLowLevelBody().getCore().isFastMoving = isFastMoving!=0; + } + + PxAtomicAdd(mNumFastMovingShapes, PxI32(activeShapes)); + } +}; +} + +void Sc::Scene::ccdBroadPhaseAABB(PxBaseTask* continuation) +{ + PX_PROFILE_START_CROSSTHREAD("Sim.ccdBroadPhaseComplete", mContextId); + PX_PROFILE_ZONE("Sim.ccdBroadPhaseAABB", mContextId); + PX_UNUSED(continuation); + + PxU32 currentPass = mCCDContext->getCurrentCCDPass(); + + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + mNumFastMovingShapes = 0; + + //If we are on the 1st pass or we had some sweep hits previous CCD pass, we need to run CCD again + if(currentPass == 0 || mCCDContext->getNumSweepHits()) + { + PxsTransformCache& transformCache = getLowLevelContext()->getTransformCache(); + for(PxU32 i = 0; i < mCcdBodies.size(); i+= UpdateCCDBoundsTask::MaxPerTask) + { + const PxU32 nbToProcess = PxMin(UpdateCCDBoundsTask::MaxPerTask, mCcdBodies.size() - i); + UpdateCCDBoundsTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(UpdateCCDBoundsTask)), UpdateCCDBoundsTask)(mContextId, mBoundsArray, &transformCache, &mCcdBodies[i], nbToProcess, &mNumFastMovingShapes); + task->setContinuation(continuation); + task->removeReference(); + } + } +} + +void Sc::Scene::ccdBroadPhase(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.ccdBroadPhase", mContextId); + + PxU32 currentPass = mCCDContext->getCurrentCCDPass(); + const PxU32 ccdMaxPasses = mCCDContext->getCCDMaxPasses(); + mCCDPass = currentPass+1; + + //If we are on the 1st pass or we had some sweep hits previous CCD pass, we need to run CCD again + if( (currentPass == 0 || mCCDContext->getNumSweepHits()) && mNumFastMovingShapes != 0) + { + const PxU32 currIndex = currentPass & 1; + const PxU32 nextIndex = 1 - currIndex; + //Initialize the CCD task chain unless this is the final pass + if(currentPass != (ccdMaxPasses - 1)) + { + mCCDBroadPhase[nextIndex].setContinuation(continuation); + mCCDBroadPhaseAABB[nextIndex].setContinuation(&mCCDBroadPhase[nextIndex]); + } + mPostCCDPass[currIndex].setContinuation(currentPass == ccdMaxPasses-1 ? continuation : &mCCDBroadPhaseAABB[nextIndex]); + mUpdateCCDSinglePass3[currIndex].setContinuation(&mPostCCDPass[currIndex]); + mUpdateCCDSinglePass2[currIndex].setContinuation(&mUpdateCCDSinglePass3[currIndex]); + mUpdateCCDSinglePass[currIndex].setContinuation(&mUpdateCCDSinglePass2[currIndex]); + + //Do the actual broad phase + PxBaseTask* continuationTask = &mUpdateCCDSinglePass[currIndex]; +// const PxU32 numCpuTasks = continuationTask->getTaskManager()->getCpuDispatcher()->getWorkerCount(); + + mCCDBp = true; + + mBpSecondPass.setContinuation(continuationTask); + mBpFirstPass.setContinuation(&mBpSecondPass); + + mBpSecondPass.removeReference(); + mBpFirstPass.removeReference(); + + //mAABBManager->updateAABBsAndBP(numCpuTasks, mLLContext->getTaskPool(), &mLLContext->getScratchAllocator(), false, continuationTask, NULL); + + //Allow the CCD task chain to continue + mPostCCDPass[currIndex].removeReference(); + mUpdateCCDSinglePass3[currIndex].removeReference(); + mUpdateCCDSinglePass2[currIndex].removeReference(); + mUpdateCCDSinglePass[currIndex].removeReference(); + if(currentPass != (ccdMaxPasses - 1)) + { + mCCDBroadPhase[nextIndex].removeReference(); + mCCDBroadPhaseAABB[nextIndex].removeReference(); + } + } + else if (currentPass == 0) + { + PX_PROFILE_STOP_CROSSTHREAD("Sim.ccdBroadPhaseComplete", mContextId); + mCCDContext->resetContactManagers(); + } +} + +void Sc::Scene::updateCCDSinglePass(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.updateCCDSinglePass", mContextId); + mReportShapePairTimeStamp++; // This will makes sure that new report pairs will get created instead of re-using the existing ones. + + mAABBManager->postBroadPhase(NULL, *getFlushPool()); + finishBroadPhase(continuation); + + const PxU32 currentPass = mCCDContext->getCurrentCCDPass() + 1; // 0 is reserved for discrete collision phase + if(currentPass == 1) // reset the handle map so we only update CCD objects from here on + { + PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); + //changedAABBMgrActorHandles.clear(); + for(PxU32 i = 0; i < mCcdBodies.size();i++) + { + // PT: ### changedMap pattern #1 + PxU32 nbElems = mCcdBodies[i]->getNbElements(); + ElementSim** elems = mCcdBodies[i]->getElements(); + while(nbElems--) + { + ShapeSim* sim = static_cast(*elems++); + if(sim->getFlags()&PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) // TODO: need trigger shape here? + changedAABBMgrActorHandles.growAndSet(sim->getElementID()); + } + } + } +} + +void Sc::Scene::updateCCDSinglePassStage2(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.updateCCDSinglePassStage2", mContextId); + postBroadPhaseStage2(continuation); +} + +void Sc::Scene::updateCCDSinglePassStage3(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.updateCCDSinglePassStage3", mContextId); + mReportShapePairTimeStamp++; // This will makes sure that new report pairs will get created instead of re-using the existing ones. + + const PxU32 currentPass = mCCDContext->getCurrentCCDPass() + 1; // 0 is reserved for discrete collision phase + finishBroadPhaseStage2(currentPass); + PX_PROFILE_STOP_CROSSTHREAD("Sim.ccdBroadPhaseComplete", mContextId); + + //reset thread context in a place we know all tasks possibly accessing it, are in sync with. (see US6664) + mLLContext->resetThreadContexts(); + + mCCDContext->updateCCD(mDt, continuation, mSimpleIslandManager->getAccurateIslandSim(), (mPublicFlags & PxSceneFlag::eDISABLE_CCD_RESWEEP), mNumFastMovingShapes); +} + +static PX_FORCE_INLINE Sc::ShapeInteraction* getSI(PxvContactManagerTouchEvent& evt) +{ + return reinterpret_cast(evt.getCMTouchEventUserData()); +} + +void Sc::Scene::postCCDPass(PxBaseTask* /*continuation*/) +{ + // - Performs sleep check + // - Updates touch flags + + PxU32 currentPass = mCCDContext->getCurrentCCDPass(); + PX_ASSERT(currentPass > 0); // to make sure changes to the CCD pass counting get noticed. For contact reports, 0 means discrete collision phase. + + int newTouchCount, lostTouchCount, ccdTouchCount; + mLLContext->getManagerTouchEventCount(&newTouchCount, &lostTouchCount, &ccdTouchCount); + PX_ALLOCA(newTouches, PxvContactManagerTouchEvent, newTouchCount); + PX_ALLOCA(lostTouches, PxvContactManagerTouchEvent, lostTouchCount); + PX_ALLOCA(ccdTouches, PxvContactManagerTouchEvent, ccdTouchCount); + + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + + // Note: For contact notifications it is important that the new touch pairs get processed before the lost touch pairs. + // This allows to know for sure if a pair of actors lost all touch (see eACTOR_PAIR_LOST_TOUCH). + mLLContext->fillManagerTouchEvents(newTouches, newTouchCount, lostTouches, lostTouchCount, ccdTouches, ccdTouchCount); + for(PxI32 i=0; imanagerNewTouch(*si); + si->managerNewTouch(currentPass, true, outputs); + if (!si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) + { + mSimpleIslandManager->setEdgeConnected(si->getEdgeIndex(), IG::Edge::eCONTACT_MANAGER); + } + } + for(PxI32 i=0; imanagerLostTouch(currentPass, true, outputs) && !si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) + addToLostTouchList(si->getShape0().getActor(), si->getShape1().getActor()); + + mSimpleIslandManager->setEdgeDisconnected(si->getEdgeIndex()); + } + for(PxI32 i=0; isendCCDRetouch(currentPass, outputs); + } + checkForceThresholdContactEvents(currentPass); + { + PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); + + for (PxU32 i = 0, s = mCcdBodies.size(); i < s; i++) + { + BodySim*const body = mCcdBodies[i]; + if(i+8 < s) + PxPrefetch(mCcdBodies[i+8], 512); + + PX_ASSERT(body->getBody2World().p.isFinite()); + PX_ASSERT(body->getBody2World().q.isFinite()); + + body->updateCached(&changedAABBMgrActorHandles); + } + + ArticulationCore* const* articList = mArticulations.getEntries(); + for(PxU32 i=0;igetSim()->updateCached(&changedAABBMgrActorHandles); + } +} diff --git a/physx/source/simulationcontroller/src/ScConstraintBreakage.cpp b/physx/source/simulationcontroller/src/ScConstraintBreakage.cpp new file mode 100644 index 000000000..eea229f17 --- /dev/null +++ b/physx/source/simulationcontroller/src/ScConstraintBreakage.cpp @@ -0,0 +1,130 @@ +// 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. + +#include "ScScene.h" +#include "ScConstraintSim.h" +#include "ScConstraintCore.h" +#include "ScConstraintInteraction.h" +#include "common/PxProfileZone.h" + +using namespace physx; + +// PT: the breakable constraints are added to / removed from mActiveBreakableConstraints: + +void Sc::Scene::addActiveBreakableConstraint(Sc::ConstraintSim* c, Sc::ConstraintInteraction* ci) +{ + PX_ASSERT(ci && ci->readInteractionFlag(InteractionFlag::eIS_ACTIVE)); + PX_UNUSED(ci); + PX_ASSERT(!mActiveBreakableConstraints.contains(c)); + PX_ASSERT(!c->isBroken()); + mActiveBreakableConstraints.insert(c); + c->setFlag(ConstraintSim::eCHECK_MAX_FORCE_EXCEEDED); +} + +void Sc::Scene::removeActiveBreakableConstraint(Sc::ConstraintSim* c) +{ + const bool exists = mActiveBreakableConstraints.erase(c); + PX_ASSERT(exists); + PX_UNUSED(exists); + c->clearFlag(ConstraintSim::eCHECK_MAX_FORCE_EXCEEDED); +} + +// PT: then at runtime we parse mActiveBreakableConstraints, check for max force exceeded, +// and add broken constraints to mBrokenConstraints: + +void Sc::Scene::checkConstraintBreakage() +{ + PX_PROFILE_ZONE("Sim.checkConstraintBreakage", mContextId); + + PxU32 count = mActiveBreakableConstraints.size(); + if(!count) + return; + + PxPinnedArray& pool = mDynamicsContext->getConstraintWriteBackPool(); + + ConstraintSim* const* constraints = mActiveBreakableConstraints.getEntries(); + while(count--) + { + ConstraintSim* sim = constraints[count]; // start from the back because broken constraints get removed from the list + + PX_ASSERT(sim->readFlag(ConstraintSim::eCHECK_MAX_FORCE_EXCEEDED)); + + const Dy::ConstraintWriteback& solverOutput = pool[sim->getLowLevelConstraint().index]; + if(solverOutput.broken) + { + sim->setFlag(ConstraintSim::eBROKEN); + + ConstraintCore& core = sim->getCore(); + if(mSimulationEventCallback) + { + PX_ASSERT(mBrokenConstraints.find(&core) == mBrokenConstraints.end()); + mBrokenConstraints.pushBack(&core); + } + + core.breakApart(); + + ConstraintInteraction* interaction = const_cast(sim->getInteraction()); + + interaction->destroy(); // PT: this will call removeFromActiveBreakableList above + + // update related SIPs + { + ActorSim& a0 = interaction->getActorSim0(); + ActorSim& a1 = interaction->getActorSim1(); + ActorSim& actor = (a0.getActorInteractionCount() < a1.getActorInteractionCount()) ? a0 : a1; + + actor.setActorsInteractionsDirty(InteractionDirtyFlag::eFILTER_STATE, NULL, InteractionFlag::eRB_ELEMENT); + // because broken constraints can re-enable contact response between the two bodies + } + + PX_ASSERT(!sim->readFlag(ConstraintSim::eCHECK_MAX_FORCE_EXCEEDED)); + } + } +} + +// PT: finally mBrokenConstraints is parsed and callbacks issued: + +void Sc::Scene::fireBrokenConstraintCallbacks() +{ + if(!mSimulationEventCallback) + return; + + const PxU32 count = mBrokenConstraints.size(); + for(PxU32 i=0;igetSim()); + + PxU32 typeID = 0xffffffff; + void* externalRef = c->getPxConnector()->getExternalReference(typeID); + PX_CHECK_MSG(typeID != 0xffffffff, "onConstraintBreak: Invalid constraint type ID."); + + PxConstraintInfo constraintInfo(c->getPxConstraint(), externalRef, typeID); + mSimulationEventCallback->onConstraintBreak(&constraintInfo, 1); + } +} diff --git a/physx/source/simulationcontroller/src/ScConstraintCore.cpp b/physx/source/simulationcontroller/src/ScConstraintCore.cpp index b5294af8c..c8e255a0a 100644 --- a/physx/source/simulationcontroller/src/ScConstraintCore.cpp +++ b/physx/source/simulationcontroller/src/ScConstraintCore.cpp @@ -38,7 +38,6 @@ Sc::ConstraintCore::ConstraintCore(PxConstraintConnector& connector, const PxCon mAppliedForce (PxVec3(0.0f)), mAppliedTorque (PxVec3(0.0f)), mConnector (&connector), - mProject (shaders.project), mSolverPrep (shaders.solverPrep), mVisualize (shaders.visualize), mDataSize (dataSize), diff --git a/physx/source/simulationcontroller/src/ScConstraintGroupNode.cpp b/physx/source/simulationcontroller/src/ScConstraintGroupNode.cpp deleted file mode 100644 index 68598c22e..000000000 --- a/physx/source/simulationcontroller/src/ScConstraintGroupNode.cpp +++ /dev/null @@ -1,136 +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-2023 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#include "ScConstraintGroupNode.h" -#include "ScConstraintProjectionManager.h" -#include "ScBodySim.h" -#include "ScConstraintSim.h" -#include "ScConstraintInteraction.h" - -using namespace physx; - -Sc::ConstraintGroupNode::ConstraintGroupNode(BodySim& b) : - body(&b), - parent(this), - tail(this), - rank(0), - next(NULL), - - projectionFirstRoot(NULL), - projectionNextRoot(NULL), - projectionParent(NULL), - projectionFirstChild(NULL), - projectionNextSibling(NULL), - projectionConstraint(NULL), - - flags(0) -{ -} - - -// -// Implementation of FIND of -// UNION-FIND algo. -// -Sc::ConstraintGroupNode& Sc::ConstraintGroupNode::getRoot() -{ - PX_ASSERT(parent); - - ConstraintGroupNode* root = parent; - - if (root->parent == root) - return *root; - else - { - PxU32 nbHops = 1; - root = root->parent; - - while(root != root->parent) - { - root = root->parent; - nbHops++; - } - - // Write root to all nodes on the path - ConstraintGroupNode* curr = this; - while(nbHops) - { - ConstraintGroupNode* n = curr->parent; - curr->parent = root; - curr = n; - nbHops--; - } - - return *root; - } -} - - -void Sc::ConstraintGroupNode::markForProjectionTreeRebuild(ConstraintProjectionManager& cpManager) -{ - ConstraintGroupNode& root = getRoot(); - if (!root.readFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE)) - { - cpManager.addToPendingTreeUpdates(root); - } -} - - -void Sc::ConstraintGroupNode::initProjectionData(ConstraintGroupNode* parent_, ConstraintSim* c) -{ - projectionConstraint = c; - - //add us to parent's child list: - if (parent_) - { - projectionNextSibling = parent_->projectionFirstChild; - parent_->projectionFirstChild = this; - - projectionParent = parent_; - } -} - - -void Sc::ConstraintGroupNode::clearProjectionData() -{ - projectionFirstRoot = NULL; - projectionNextRoot = NULL; - projectionParent = NULL; - projectionFirstChild = NULL; - projectionNextSibling = NULL; - projectionConstraint = NULL; -} - - -void Sc::ConstraintGroupNode::projectPose(ConstraintGroupNode& node, PxArray& projectedBodies) -{ - PX_ASSERT(node.hasProjectionTreeRoot()); - - Sc::ConstraintProjectionTree::projectPose(node, projectedBodies); -} diff --git a/physx/source/simulationcontroller/src/ScConstraintGroupNode.h b/physx/source/simulationcontroller/src/ScConstraintGroupNode.h deleted file mode 100644 index ba755a5c3..000000000 --- a/physx/source/simulationcontroller/src/ScConstraintGroupNode.h +++ /dev/null @@ -1,176 +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-2023 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef SC_CONSTRAINT_GROUP_NODE_H -#define SC_CONSTRAINT_GROUP_NODE_H - -#include "ScConstraintProjectionTree.h" -#include "foundation/PxUtilities.h" // for PxTo8() - -namespace physx -{ -namespace Sc -{ - class ConstraintSim; - class BodySim; - class ConstraintProjectionManager; - - // A 'simulation island' of constraints. Created by a union-find algorithm every time a new constraint is added to any of the involved bodies. - struct ConstraintGroupNode : public PxUserAllocated - { - enum StateFlags - { - eDISCOVERED = 1 << 0, // Used during projection tree generation to mark processed nodes. - eIN_PROJECTION_PASS_LIST = 1 << 1, // Temporarily used to avoid duplicate entries in the list of nodes that should project the pose after the solver - ePENDING_TREE_UPDATE = 1 << 2, // Marks the constraint groups that need their projection trees updated. Must only be set on the root group node. - eNEXT_FREE_SHIFT = 3, - eNEXT_FREE = 1 << eNEXT_FREE_SHIFT - }; - - // these flags should give a rough hint how many projecting constraints to expect in the constraint group. This will be used for - // load balancing when running projection in parallel. The intervals were chosen somewhat arbitrarily but the general motivation was - // to cover very simple constraint setups, simple ragdolls, complex ragdolls and very complex projection setups. Note that the load - // balancing is not waterproof since at the end it is the projection shader from the external constraint implementer (for example, a joint) - // which decides based on some thresholds whether projection runs or not. - enum ProjectionCountHintFlags - { - e1_TO_4 = eNEXT_FREE, - e5_TO_16 = eNEXT_FREE << 1, - e17_TO_64 = eNEXT_FREE << 2, - e65_TO_INF = eNEXT_FREE << 3, - eCLEAR_MASK = ~(0xffffffff << eNEXT_FREE_SHIFT) - }; - - ConstraintGroupNode(BodySim& b); - ~ConstraintGroupNode() - { - PX_ASSERT(!readFlag(ePENDING_TREE_UPDATE)); - PX_ASSERT(projectionFirstRoot == NULL); - } - - PX_FORCE_INLINE void raiseFlag(StateFlags f) { flags |= f; } - PX_FORCE_INLINE void clearFlag(StateFlags f) { flags &= ~f; } - PX_FORCE_INLINE bool readFlag(StateFlags f) const { return (flags & f) != 0; } - PX_FORCE_INLINE PxU32 getProjectionCountHint() const; - PX_FORCE_INLINE void setProjectionCountHint(PxU32 constraintsToProjectCount); - - ConstraintGroupNode& getRoot(); - - PX_FORCE_INLINE void buildProjectionTrees(); //build the projection trees for a constraint group. - void markForProjectionTreeRebuild(ConstraintProjectionManager&); - PX_FORCE_INLINE void purgeProjectionTrees(); - PX_FORCE_INLINE bool hasProjectionTreeRoot() { return projectionFirstRoot != NULL; } - PX_FORCE_INLINE void setProjectionTreeRoot(ConstraintGroupNode* root) { projectionFirstRoot = root; } - - void initProjectionData(ConstraintGroupNode* parent, ConstraintSim* c); - void clearProjectionData(); - - static void projectPose(ConstraintGroupNode& root, PxArray& projectedBodies); - - - BodySim* body; //the owner body of this node - - //tree for union/find: - ConstraintGroupNode* parent; - ConstraintGroupNode* tail; //only valid if this is root of group, points to LList tail node. - PxU32 rank; //rank counter for union/find. Initially zero. Is number of hops from root to furthest leaf in tree. This is just a hint to create more balanced trees. - - //linked list for traversal: - ConstraintGroupNode* next; //next in list, NULL at tail. - - //projection tree information - ConstraintGroupNode* projectionFirstRoot; //pointer to first projection tree root node. Only set for constraint group roots - ConstraintGroupNode* projectionNextRoot; //pointer to next projection root node. Only set for constraint group roots - //a constraint group can consist of multiple projection trees if kinematics are involved! Because a kinematic doesn't split - //the constraint group as a static anchor does. - ConstraintGroupNode* projectionParent; //node to project to - ConstraintGroupNode* projectionFirstChild; //first node which gets projected to this one - ConstraintGroupNode* projectionNextSibling; //the next sibling which gets projected to the same node as this one. NULL if projectionParent is NULL. - ConstraintSim* projectionConstraint; //the constraint to project (constraint to projection parent) - - private: - PxU8 flags; - }; - -} // namespace Sc - - -PX_FORCE_INLINE PxU32 Sc::ConstraintGroupNode::getProjectionCountHint() const -{ - // return the mean of the upper and lower bound - - if (flags & ConstraintGroupNode::e65_TO_INF) - return 128; - else if (flags & ConstraintGroupNode::e17_TO_64) - return 40; - else if (flags & ConstraintGroupNode::e5_TO_16) - return 10; - else if (flags & ConstraintGroupNode::e1_TO_4) - return 2; - - return 0; -} - - -PX_FORCE_INLINE void Sc::ConstraintGroupNode::setProjectionCountHint(PxU32 constraintsToProjectCount) -{ - PxU8 tmpFlags = flags; - tmpFlags &= PxU8(ConstraintGroupNode::eCLEAR_MASK); - - if (constraintsToProjectCount >= 65) - tmpFlags |= ConstraintGroupNode::e65_TO_INF; - else if (constraintsToProjectCount >= 17) - tmpFlags |= ConstraintGroupNode::e17_TO_64; - else if (constraintsToProjectCount >= 5) - tmpFlags |= ConstraintGroupNode::e5_TO_16; - else if (constraintsToProjectCount >= 1) - tmpFlags |= ConstraintGroupNode::e1_TO_4; - - flags = tmpFlags; -} - - -PX_FORCE_INLINE void Sc::ConstraintGroupNode::buildProjectionTrees() -{ - PX_ASSERT(this == parent); // Only call for group roots - PX_ASSERT(!hasProjectionTreeRoot()); - - ConstraintProjectionTree::buildProjectionTrees(*this); -} - - -PX_FORCE_INLINE void Sc::ConstraintGroupNode::purgeProjectionTrees() -{ - PX_ASSERT(this == parent); // Only call for group roots - PX_ASSERT(hasProjectionTreeRoot()); - ConstraintProjectionTree::purgeProjectionTrees(*this); -} - -} - -#endif diff --git a/physx/source/simulationcontroller/src/ScConstraintInteraction.cpp b/physx/source/simulationcontroller/src/ScConstraintInteraction.cpp index cf51bdf63..5fe27b980 100644 --- a/physx/source/simulationcontroller/src/ScConstraintInteraction.cpp +++ b/physx/source/simulationcontroller/src/ScConstraintInteraction.cpp @@ -40,7 +40,10 @@ ConstraintInteraction::ConstraintInteraction(ConstraintSim* constraint, RigidSim Interaction (r0, r1, InteractionType::eCONSTRAINTSHADER, InteractionFlag::eCONSTRAINT), mConstraint (constraint) { - registerInActors(); + { + onActivate(NULL); + registerInActors(); + } BodySim* b0 = mConstraint->getBody(0); BodySim* b1 = mConstraint->getBody(1); @@ -103,15 +106,15 @@ void ConstraintInteraction::updateState() // -> need to check whether to activate the constraint and whether constraint break testing // is now necessary // - // the transition from dynamic to kinematic will always trigger an onDeactivate_() (because the body gets deactivated) + // the transition from dynamic to kinematic will always trigger an onDeactivate() (because the body gets deactivated) // and thus there is no need to consider that case here. // - onActivate_(NULL); // note: this will not activate if the necessary conditions are not met, so it can be called even if the pair has been deactivated again before the - // simulation step started + onActivate(NULL); // note: this will not activate if the necessary conditions are not met, so it can be called even if the pair has been deactivated again before the + // simulation step started } -bool ConstraintInteraction::onActivate_(void*) +bool ConstraintInteraction::onActivate(void*) { PX_ASSERT(!mConstraint->isBroken()); @@ -140,7 +143,7 @@ bool ConstraintInteraction::onActivate_(void*) return false; } -bool ConstraintInteraction::onDeactivate_() +bool ConstraintInteraction::onDeactivate() { const BodySim* b0 = mConstraint->getBody(0); const BodySim* b1 = mConstraint->getBody(1); diff --git a/physx/source/simulationcontroller/src/ScConstraintInteraction.h b/physx/source/simulationcontroller/src/ScConstraintInteraction.h index fcafc56db..4d5f5d232 100644 --- a/physx/source/simulationcontroller/src/ScConstraintInteraction.h +++ b/physx/source/simulationcontroller/src/ScConstraintInteraction.h @@ -44,8 +44,8 @@ namespace Sc ConstraintInteraction(ConstraintSim* shader, RigidSim& r0, RigidSim& r1); ~ConstraintInteraction(); - bool onActivate_(void* data); - bool onDeactivate_(); + bool onActivate(void* data); + bool onDeactivate(); void updateState(); void destroy(); // disables the interaction and unregisters from the system. Does NOT delete the object. This is used on destruction but also when a constraint breaks. diff --git a/physx/source/simulationcontroller/src/ScConstraintProjectionManager.cpp b/physx/source/simulationcontroller/src/ScConstraintProjectionManager.cpp deleted file mode 100644 index c81d495c4..000000000 --- a/physx/source/simulationcontroller/src/ScConstraintProjectionManager.cpp +++ /dev/null @@ -1,504 +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-2023 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#include "PxcScratchAllocator.h" -#include "ScConstraintProjectionManager.h" -#include "ScBodySim.h" -#include "ScConstraintSim.h" -#include "ScConstraintInteraction.h" - -using namespace physx; - - -namespace physx -{ -namespace Sc -{ - -template -class ScratchAllocatorList -{ -private: - struct ElementBlock - { - PX_FORCE_INLINE ElementBlock() {} - PX_FORCE_INLINE void init(PxU32 countAtStart) { next = NULL; count = countAtStart; } - - ElementBlock* next; - PxU32 count; - T elements[elementsPerBlock]; - }; - - PX_FORCE_INLINE const ScratchAllocatorList& operator=(const ScratchAllocatorList&) {} - - -public: - class Iterator - { - friend class ScratchAllocatorList; - - public: - T const* getNext() - { - if (mCurrentBlock) - { - if (mIndex < mCurrentBlock->count) - { - return &mCurrentBlock->elements[mIndex++]; - } - else - { - if (mCurrentBlock->next) - { - PX_ASSERT(mCurrentBlock->count == elementsPerBlock); - mCurrentBlock = mCurrentBlock->next; - PX_ASSERT(mCurrentBlock->count > 0); - - mIndex = 1; - return &mCurrentBlock->elements[0]; - } - else - return NULL; - } - } - else - return NULL; - } - - private: - Iterator(const ElementBlock* startBlock) : mCurrentBlock(startBlock), mIndex(0) {} - - private: - const ElementBlock* mCurrentBlock; - PxU32 mIndex; - }; - - PX_FORCE_INLINE ScratchAllocatorList(PxcScratchAllocator& scratchAllocator) : mScratchAllocator(scratchAllocator) - { - mFirstBlock = reinterpret_cast(scratchAllocator.alloc(sizeof(ElementBlock), true)); - if (mFirstBlock) - mFirstBlock->init(0); - - mCurrentBlock = mFirstBlock; - } - - PX_FORCE_INLINE ~ScratchAllocatorList() - { - freeMemory(); - } - - PX_FORCE_INLINE bool add(const T& element) - { - if (mCurrentBlock) - { - if (mCurrentBlock->count < elementsPerBlock) - { - mCurrentBlock->elements[mCurrentBlock->count] = element; - mCurrentBlock->count++; - return true; - } - else - { - PX_ASSERT(mCurrentBlock->next == NULL); - PX_ASSERT(mCurrentBlock->count == elementsPerBlock); - - ElementBlock* newBlock = reinterpret_cast(mScratchAllocator.alloc(sizeof(ElementBlock), true)); - if (newBlock) - { - newBlock->init(1); - newBlock->elements[0] = element; - mCurrentBlock->next = newBlock; - mCurrentBlock = newBlock; - return true; - } - else - return false; - } - } - else - return false; - } - - PX_FORCE_INLINE Iterator getIterator() const - { - return Iterator(mFirstBlock); - } - - PX_FORCE_INLINE void freeMemory() - { - ElementBlock* block = mFirstBlock; - - while(block) - { - ElementBlock* blockToFree = block; - block = block->next; - - mScratchAllocator.free(blockToFree); - } - } - - -private: - PxcScratchAllocator& mScratchAllocator; - ElementBlock* mFirstBlock; - ElementBlock* mCurrentBlock; -}; - -} -} - - -Sc::ConstraintProjectionManager::ConstraintProjectionManager() : - mNodePool("projectionNodePool") -{ -} - - -void Sc::ConstraintProjectionManager::addToPendingGroupUpdates(Sc::ConstraintSim& s) -{ - PX_ASSERT(!s.readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)); - bool isNew = mPendingGroupUpdates.insert(&s); - PX_UNUSED(isNew); - PX_ASSERT(isNew); - - s.setFlag(ConstraintSim::ePENDING_GROUP_UPDATE); -} - - -void Sc::ConstraintProjectionManager::removeFromPendingGroupUpdates(Sc::ConstraintSim& s) -{ - PX_ASSERT(s.readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)); - bool didExist = mPendingGroupUpdates.erase(&s); - PX_UNUSED(didExist); - PX_ASSERT(didExist); - - s.clearFlag(ConstraintSim::ePENDING_GROUP_UPDATE); -} - - -void Sc::ConstraintProjectionManager::addToPendingTreeUpdates(ConstraintGroupNode& n) -{ - PX_ASSERT(&n == &n.getRoot()); - PX_ASSERT(!n.readFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE)); - bool isNew = mPendingTreeUpdates.insert(&n); - PX_UNUSED(isNew); - PX_ASSERT(isNew); - - n.raiseFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE); -} - - -void Sc::ConstraintProjectionManager::removeFromPendingTreeUpdates(ConstraintGroupNode& n) -{ - PX_ASSERT(&n == &n.getRoot()); - PX_ASSERT(n.readFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE)); - bool didExist = mPendingTreeUpdates.erase(&n); - PX_UNUSED(didExist); - PX_ASSERT(didExist); - - n.clearFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE); -} - - -PX_INLINE Sc::ConstraintGroupNode* Sc::ConstraintProjectionManager::createGroupNode(BodySim& b) -{ - ConstraintGroupNode* n = mNodePool.construct(b); - b.setConstraintGroup(n); - return n; -} - - -// -// Implementation of UNION of -// UNION-FIND algo. -// It also updates the group traversal -// linked list. -// -void Sc::ConstraintProjectionManager::groupUnion(ConstraintGroupNode& root0, ConstraintGroupNode& root1) -{ - // Should only get called for the roots - PX_ASSERT(&root0 == root0.parent); - PX_ASSERT(&root1 == root1.parent); - - if (&root0 != &root1) //different groups? If not, its already merged. - { - //UNION(this, other); //union-find algo unites groups. - ConstraintGroupNode* newRoot; - ConstraintGroupNode* otherRoot; - if (root0.rank > root1.rank) - { - //hisGroup appended to mygroup. - newRoot = &root0; - otherRoot = &root1; - } - else - { - //myGroup appended to hisGroup. - newRoot = &root1; - otherRoot = &root0; - //there is a chance that the two ranks were equal, in which case the tree depth just increased. - root1.rank++; - } - - PX_ASSERT(newRoot->parent == newRoot); - otherRoot->parent = newRoot; - - //update traversal linked list: - newRoot->tail->next = otherRoot; - newRoot->tail = otherRoot->tail; - } -} - - -// -// Add a body to a constraint projection group. -// -void Sc::ConstraintProjectionManager::addToGroup(BodySim& b, BodySim* other, ConstraintSim& c) -{ - // If both bodies of the constraint are defined, we want to fetch the reference to the group root - // from body 0 by default (allows to avoid checking both) - PX_ASSERT(&b == c.getBody(0) || (c.getBody(0) == NULL && &b == c.getBody(1))); - PX_UNUSED(c); - - ConstraintGroupNode* myRoot; - if (!b.getConstraintGroup()) - myRoot = createGroupNode(b); - else - { - myRoot = &b.getConstraintGroup()->getRoot(); - if (myRoot->hasProjectionTreeRoot()) - myRoot->purgeProjectionTrees(); // If a new constraint gets added to a constraint group, projection trees need to be recreated - } - - if (other) - { - ConstraintGroupNode* otherRoot; - if (!other->getConstraintGroup()) - otherRoot = createGroupNode(*other); - else - { - otherRoot = &other->getConstraintGroup()->getRoot(); - if (otherRoot->hasProjectionTreeRoot()) - otherRoot->purgeProjectionTrees(); // If a new constraint gets added to a constraint group, projection trees need to be recreated - } - - //merge the two groups, if disjoint. - groupUnion(*myRoot, *otherRoot); - } -} - - -// -// Add all projection constraints connected to the specified body to the pending update list but -// ignore the specified constraint. -// -void Sc::ConstraintProjectionManager::markConnectedConstraintsForUpdate(BodySim& b, ConstraintSim* c) -{ - PxU32 size = b.getActorInteractionCount(); - Interaction** interactions = b.getActorInteractions(); - while(size--) - { - Interaction* interaction = *interactions++; - if (interaction->getType() == InteractionType::eCONSTRAINTSHADER) - { - ConstraintSim* ct = static_cast(interaction)->getConstraint(); - - if ((ct != c) && ct->needsProjection() && (!ct->readFlag(ConstraintSim::ePENDING_GROUP_UPDATE))) - { - //mark constraint for pending update: - addToPendingGroupUpdates(*ct); - } - } - } -} - - -// -// Add all constraints connected to the specified body to an array but -// ignore the specified constraint. -// -PX_FORCE_INLINE static void dumpConnectedConstraints(Sc::BodySim& b, Sc::ConstraintSim* c, Sc::ScratchAllocatorList& constraintList) -{ - PxU32 size = b.getActorInteractionCount(); - Sc::Interaction** interactions = b.getActorInteractions(); - while(size--) - { - Sc::Interaction* interaction = *interactions++; - if (interaction->getType() == Sc::InteractionType::eCONSTRAINTSHADER) - { - Sc::ConstraintSim* ct = static_cast(interaction)->getConstraint(); - - if ((ct != c) && (!ct->readFlag(Sc::ConstraintSim::ePENDING_GROUP_UPDATE))) - { - bool success = constraintList.add(ct); - PX_UNUSED(success); - PX_ASSERT(success); - } - } - } -} - - -PX_FORCE_INLINE void Sc::ConstraintProjectionManager::processConstraintForGroupBuilding(ConstraintSim* c, ScratchAllocatorList& constraintList) -{ - c->clearFlag(ConstraintSim::ePENDING_GROUP_UPDATE); - - // Find all constraints connected to the two bodies of the dirty constraint. - // - Constraints to static anchors are ignored (note: kinematics can't be ignored because they might get switched to dynamics any time which - // does trigger a projection tree rebuild but not a constraint tree rebuild - // - Already processed bodies are ignored as well - BodySim* b0 = c->getBody(0); - if (b0 && !b0->getConstraintGroup()) - { - dumpConnectedConstraints(*b0, c, constraintList); - } - BodySim* b1 = c->getBody(1); - if (b1 && !b1->getConstraintGroup()) - { - dumpConnectedConstraints(*b1, c, constraintList); - } - - BodySim* b = c->getAnyBody(); - PX_ASSERT(b); - - addToGroup(*b, c->getOtherBody(b), *c); //this will eventually merge some body's constraint groups. -} - - -void Sc::ConstraintProjectionManager::processPendingUpdates(PxcScratchAllocator& scratchAllocator) -{ - // - // if there are dirty projection trees, then rebuild them - // - const PxU32 nbProjectionTreesToUpdate = mPendingTreeUpdates.size(); - if (nbProjectionTreesToUpdate) - { - ConstraintGroupNode* const* projectionTreesToUpdate = mPendingTreeUpdates.getEntries(); - for(PxU32 i=0; i < nbProjectionTreesToUpdate; i++) - { - ConstraintGroupNode* n = projectionTreesToUpdate[i]; - - PX_ASSERT(n == &n->getRoot()); // only root nodes should be in that list - PX_ASSERT(n->readFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE)); - - n->clearFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE); - - // note: it is valid to get here and not have a projection root. This is the case if all nodes of a constraint graph are kinematic - // at some point (hence no projection root) and later some of those get switched to dynamic. - if (n->hasProjectionTreeRoot()) - n->purgeProjectionTrees(); - n->buildProjectionTrees(); - } - - mPendingTreeUpdates.clear(); - } - - // - // if there are new/dirty constraints, update groups - // - const PxU32 nbProjectionConstraintsToUpdate = mPendingGroupUpdates.size(); - - if (nbProjectionConstraintsToUpdate) - { - ScratchAllocatorList nonProjectionConstraintList(scratchAllocator); - - ConstraintSim* const* projectionConstraintsToUpdate = mPendingGroupUpdates.getEntries(); - -#if PX_DEBUG - // At the beginning the list should only contain constraints with projection. - // Further below other constraints, connected to the constraints with projection, will be added too. - for(PxU32 i=0; i < nbProjectionConstraintsToUpdate; i++) - { - PX_ASSERT(projectionConstraintsToUpdate[i]->needsProjection()); - } -#endif - for(PxU32 i=0; i < nbProjectionConstraintsToUpdate; i++) - { - processConstraintForGroupBuilding(projectionConstraintsToUpdate[i], nonProjectionConstraintList); - } - - ScratchAllocatorList::Iterator iter = nonProjectionConstraintList.getIterator(); - ConstraintSim* const* nextConstraint = iter.getNext(); - while(nextConstraint) - { - processConstraintForGroupBuilding(*nextConstraint, nonProjectionConstraintList); - - nextConstraint = iter.getNext(); - } - - // Now find all the newly made groups and build projection trees. - // Don't need to iterate over the additionally constraints since the roots are supposed to be - // fetchable from any node. - for (PxU32 i=0; i < nbProjectionConstraintsToUpdate; i++) - { - ConstraintSim* c = projectionConstraintsToUpdate[i]; - BodySim* b = c->getAnyBody(); - PX_ASSERT(b); - PX_ASSERT(b->getConstraintGroup()); - - ConstraintGroupNode& root = b->getConstraintGroup()->getRoot(); - if (!root.hasProjectionTreeRoot()) // Build projection tree only once - root.buildProjectionTrees(); - } - - mPendingGroupUpdates.clear(); - } -} - - -// -// Called if a body or a constraint gets deleted. All projecting constraints of the -// group (except the deleted one) are moved to the dirty list and all group nodes are destroyed. -// -void Sc::ConstraintProjectionManager::invalidateGroup(ConstraintGroupNode& node, ConstraintSim* deletedConstraint) -{ - ConstraintGroupNode* n = &node.getRoot(); - - if (n->readFlag(ConstraintGroupNode::ePENDING_TREE_UPDATE)) - { - removeFromPendingTreeUpdates(*n); - } - - while (n) //go through nodes in constraint group - { - markConnectedConstraintsForUpdate(*n->body, deletedConstraint); - - //destroy the body's constraint group information - - ConstraintGroupNode* next = n->next; //save next node ptr before we destroy it! - - BodySim* b = n->body; - b->setConstraintGroup(NULL); - if (n->hasProjectionTreeRoot()) - n->purgeProjectionTrees(); - mNodePool.destroy(n); - - n = next; - } -} diff --git a/physx/source/simulationcontroller/src/ScConstraintProjectionManager.h b/physx/source/simulationcontroller/src/ScConstraintProjectionManager.h deleted file mode 100644 index 387a12714..000000000 --- a/physx/source/simulationcontroller/src/ScConstraintProjectionManager.h +++ /dev/null @@ -1,82 +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-2023 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef SC_CONSTRAINT_PROJECTION_MANAGER_H -#define SC_CONSTRAINT_PROJECTION_MANAGER_H - -#include "foundation/PxPool.h" -#include "foundation/PxHashSet.h" -#include "ScConstraintGroupNode.h" - -namespace physx -{ - class PxcScratchAllocator; - -namespace Sc -{ - class ConstraintSim; - class BodySim; - template class ScratchAllocatorList; - - class ConstraintProjectionManager : public PxUserAllocated - { - public: - ConstraintProjectionManager(); - ~ConstraintProjectionManager() {} - - void addToPendingGroupUpdates(ConstraintSim& s); - void removeFromPendingGroupUpdates(ConstraintSim& s); - - void addToPendingTreeUpdates(ConstraintGroupNode& n); - void removeFromPendingTreeUpdates(ConstraintGroupNode& n); - - void processPendingUpdates(PxcScratchAllocator&); - void invalidateGroup(ConstraintGroupNode& node, ConstraintSim* constraintDeleted); - - private: - PX_INLINE Sc::ConstraintGroupNode* createGroupNode(BodySim& b); - - void addToGroup(BodySim& b, BodySim* other, ConstraintSim& c); - void groupUnion(ConstraintGroupNode& root0, ConstraintGroupNode& root1); - void markConnectedConstraintsForUpdate(BodySim& b, ConstraintSim* c); - PX_FORCE_INLINE void processConstraintForGroupBuilding(ConstraintSim* c, ScratchAllocatorList&); - - - private: - PxPool mNodePool; - PxCoalescedHashSet mPendingGroupUpdates; //list of constraints for which constraint projection groups need to be generated/updated - PxCoalescedHashSet mPendingTreeUpdates; //list of constraint groups that need their projection trees rebuilt. Note: non of the - //constraints in those groups are allowed to be in mPendingGroupUpdates at the same time - //because a group update will automatically trigger tree rebuilds. - }; - -} // namespace Sc - -} - -#endif diff --git a/physx/source/simulationcontroller/src/ScConstraintProjectionTree.cpp b/physx/source/simulationcontroller/src/ScConstraintProjectionTree.cpp deleted file mode 100644 index 4e3ebd272..000000000 --- a/physx/source/simulationcontroller/src/ScConstraintProjectionTree.cpp +++ /dev/null @@ -1,565 +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-2023 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#include "ScConstraintProjectionTree.h" -#include "ScScene.h" -#include "ScBodySim.h" -#include "ScConstraintCore.h" -#include "ScConstraintSim.h" -#include "ScConstraintInteraction.h" - -#include "foundation/PxBasicTemplates.h" -#include "foundation/PxSort.h" -#include "foundation/PxArray.h" - -using namespace physx; - -//------------------------------------------------------------------------------------------ -// -// The projection tree related code -// -// Projection trees are built out of a constraint group/graph. The constraint group just tracks -// the constraint connectivity while the projection trees define the projection root and -// the projection order. -// A constraint group can contain multiple projection trees. -// -//------------------------------------------------------------------------------------------ - -class Sc::BodyRank -{ -public: - PX_INLINE bool operator>(const BodyRank & b) const - { - return rank > b.rank; - } - - Sc::ConstraintGroupNode* startingNode; - Sc::ConstraintSim* constraintToFixedAnchor; - PxU32 rank; - - // - // The following weights are defined to fulfill the projection priorities described further below - // - static const PxU32 sOneWayProjection = PxU32(1 << 31); - static const PxU32 sAttachedToStatic = (1 << 30); - static const PxU32 sAttachedToKinematic = (1 << 29); - static const PxU32 sAllDominantDynamic = (1 << 28); // if for a dynamic body all connections with projection, are one-way towards the body - static const PxU32 sDominantDynamic = (1 << 27); // almost the same as above but there is at least one two-way projection - static const PxU32 sAttachedToDynamic = 1; - static const PxU32 sPrimaryTreeRootMinRank = sOneWayProjection | sAllDominantDynamic; -}; - - -PX_INLINE bool isFixedBody(const Sc::BodySim* b) -{ - return (!b || (b->isKinematic())); -} - - -void Sc::ConstraintProjectionTree::getConstraintStatus(const ConstraintSim& c, const BodySim* b, BodySim*& otherBody, PxU32& projectToBody, PxU32& projectToOtherBody) -{ - const PxU32 isBroken = c.isBroken() ? 0 : 0xffffffff; - const PxU32 projFlags = c.getCore().getFlags() & PxConstraintFlag::ePROJECTION; - - if (b == c.getBody(0)) - { - projectToBody = isBroken & (projFlags & PxConstraintFlag::ePROJECT_TO_ACTOR0); - projectToOtherBody = isBroken & (projFlags & PxConstraintFlag::ePROJECT_TO_ACTOR1); - - otherBody = c.getBody(1); - } - else - { - projectToBody = isBroken & (projFlags & PxConstraintFlag::ePROJECT_TO_ACTOR1); - projectToOtherBody = isBroken & (projFlags & PxConstraintFlag::ePROJECT_TO_ACTOR0); - - otherBody = c.getBody(0); - } -} - - -void Sc::ConstraintProjectionTree::rankConstraint(ConstraintSim& c, BodyRank& br, PxU32& dominanceTracking, PxU32& constraintsToProjectCount) -{ - PxU32 projectToBody, projectToOtherBody; - BodySim* otherB; - getConstraintStatus(c, br.startingNode->body, otherB, projectToBody, projectToOtherBody); - - if (isFixedBody(otherB)) // joint to fixed anchor - { - PxU32 rank; - if (projectToOtherBody) - { - dominanceTracking = 0; // makes sure that the flags below will never get raised again for the body - br.rank &= ~(BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic); - rank = BodyRank::sOneWayProjection; //we should prefer picking projected constraints as the root over non-projected ones. - constraintsToProjectCount++; - } - else - rank = 0; - - if (!otherB) - rank |= BodyRank::sAttachedToStatic; - else - { - PX_ASSERT(otherB->isKinematic()); - rank |= BodyRank::sAttachedToKinematic; - } - - // the highest ranked fixed anchor constraint should get tracked - if ((!br.constraintToFixedAnchor) || (rank > br.rank)) - br.constraintToFixedAnchor = &c; - - br.rank |= rank; - } - else - { - if (projectToBody && projectToOtherBody) - { - dominanceTracking &= ~BodyRank::sAllDominantDynamic; // makes sure that from now on this will never get raised again for the body - br.rank &= ~BodyRank::sAllDominantDynamic; - constraintsToProjectCount++; - } - else if (projectToOtherBody) - { - dominanceTracking &= ~(BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic); // makes sure that from now on these will never get raised again for the body - br.rank &= ~(BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic); - constraintsToProjectCount++; - } - else if (projectToBody) - { - br.rank |= BodyRank::sOneWayProjection | (dominanceTracking & (BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic)); - constraintsToProjectCount++; - } - - br.rank += BodyRank::sAttachedToDynamic; - } -} - - -/* -the goal here is to take the constraint group whose root is passed, and create one or more projection trees. - -At the moment, the group has to be acyclic and have at most 1 constraint with the ground to be accepted -without being broken up into multiple trees. - -We 'flood fill' the constraint graph several times, starting at bodies where projection trees can be rooted. -Projection tree roots are always dynamic bodies which either need to get projected to a fixed anchor directly -or have projecting constraints between dynamics some way along the tree branches. Static and kinematic actors -are never roots and will not be explicitly part of any tree (but a tree root can project to at most one such fixed node). - -The algo looks like this: - -for all bodies -mark body as undiscovered -rank this body - -The rank of a body depends on the constraints it's connected to. It defines the projection priority which -should be (highest first): -- dynamic attached to static/world with projection -- dynamic attached to kinematic with projection -- all dominant dynamic (has projecting constraints and all of them are one-way towards this dynamic) ----- all the ones above are guaranteed tree roots -- dominant dynamic (same as above but there is at least one projecting two-way constraint as well) -- partially dominant dynamic (has at least one projecting one-way constraints towards this dynamic and at least one projecting one-way constraints towards an other body) -- dynamic attached to static/world without projection -- dynamic attached to kinematic without projection -- dynamic with or without two-way projecting constraints to other dynamics (among these, the one with the highest connectivity count wins) - -for the first three priority types sorted according to rank: -create a projection tree root and grow the tree one connectivity layer at a time - -do the same for dominant dynamic bodies that have not been visited/discovered yet - -for all remaining bodies sorted according to rank: -if the body still hasn't been visited/discovered start a projection tree there and build the whole tree in one go -before moving to the next potential root. -*/ -void Sc::ConstraintProjectionTree::buildProjectionTrees(ConstraintGroupNode& root) -{ - PX_ASSERT(&root == root.parent); - PX_ASSERT(!root.hasProjectionTreeRoot()); - - PxInlineArray bodyRankArray; - BodyRank br; - PxU32 constraintsToProjectCount = 0; - ConstraintGroupNode* node0 = &root; - while (node0) //for all nodes in group - { - PX_ASSERT(node0->body); - if (!node0->body->isKinematic()) - { - node0->clearFlag(ConstraintGroupNode::eDISCOVERED); - - //rank - br.startingNode = node0; - br.rank = 0; - br.constraintToFixedAnchor = 0; - PxU32 dominanceTracking = BodyRank::sAllDominantDynamic | BodyRank::sDominantDynamic; - - //go through all constraints connected to body - PxU32 size = node0->body->getActorInteractionCount(); - Sc::Interaction** interactions = node0->body->getActorInteractions(); - while(size--) - { - Interaction* interaction = *interactions++; - if (interaction->getType() == InteractionType::eCONSTRAINTSHADER) - { - ConstraintSim* c = static_cast(interaction)->getConstraint(); - rankConstraint(*c, br, dominanceTracking, constraintsToProjectCount); - } - } - - PX_ASSERT(br.rank); //if it has no constraints then why is it in the constraint group? - - if (br.rank >= BodyRank::sPrimaryTreeRootMinRank) - node0->raiseFlag(ConstraintGroupNode::eDISCOVERED); // we create a tree for each node attached to a fixed anchor, or a node which is an all dominating dynamic - // -> make sure they do not include each other - - bodyRankArray.pushBack(br); - } - else - node0->raiseFlag(ConstraintGroupNode::eDISCOVERED); // a kinematic does not get projected, it might only get projected to and it is never part of a tree. - - node0 = node0->next; - } - - root.setProjectionCountHint(constraintsToProjectCount); - - if (bodyRankArray.size()) // all of the bodies might have been switched to kinematic in which case there will be no ranked body - { - //sort bodyRankArray - - PxSort(&bodyRankArray.front(), bodyRankArray.size(), PxGreater()); - - ConstraintGroupNode** nodeQueue = PX_ALLOCATE(ConstraintGroupNode*, bodyRankArray.size(), "ProjectionNodeQueue"); - if (nodeQueue) - { - //build the projectionTree - - ConstraintGroupNode* firstProjectionTreeRoot = NULL; - - //go through it in sorted order - - // - // bodies attached to fixed anchors with projecting constraints or all dominant rigid dynamics should get processed first. - // For each of those we create a projection tree for sure, by extending one connectivity level from the root at a time. - // This way we make sure that scenarios like a bridge that is attached to fixed anchors at both ends breaks in the middle - // and not at one of the fixed anchors. - // - // this gets repeated for dominant dynamics. The reason for this is to cover cases where a dominant dynamic is connected to - // a higher ranked node by a chain of two-way constraints. In such a case the two-way constraint should project the dominant - // dynamic towards the higher ranked node and not start a tree on its own. - // - PxU32 brIdx = 0; - PxU32 stopIdx = bodyRankArray.size(); - PxU32 skipCount = 0; - PxU32 ranksToProcess = BodyRank::sPrimaryTreeRootMinRank; - ConstraintGroupNode** nodeQueueEnd; - ConstraintGroupNode** nodeQueueCurrent; - for(PxU32 i=0; i < 2; i++) - { - nodeQueueEnd = nodeQueue; - while((brIdx < stopIdx) && (bodyRankArray[brIdx].rank >= ranksToProcess)) - { - BodyRank& bRank = bodyRankArray[brIdx]; - PX_ASSERT((brIdx == 0) || (bRank.rank <= bodyRankArray[brIdx-1].rank)); - - ConstraintGroupNode& node = *bRank.startingNode; - PX_ASSERT(node.readFlag(ConstraintGroupNode::eDISCOVERED)); - - node.initProjectionData(NULL, bRank.constraintToFixedAnchor); - - if (bRank.rank & (BodyRank::sAttachedToStatic | BodyRank::sAttachedToKinematic)) - { - // for static/kinematic attached, the current node is already a child, so we must not traverse the neighborhood yet - // but rather add the current node to the queue. - PX_ASSERT(bRank.constraintToFixedAnchor); - *nodeQueueEnd = &node; - nodeQueueEnd++; - } - else - { - PX_ASSERT(!bRank.constraintToFixedAnchor); - PxU32 addedNodeCount = projectionTreeBuildStep(node, bRank.constraintToFixedAnchor, nodeQueueEnd); - nodeQueueEnd += addedNodeCount; - } - - node.projectionNextRoot = firstProjectionTreeRoot; - firstProjectionTreeRoot = &node; - - brIdx++; - } - - // first neighbor connectivity level has been pushed to a queue for all chosen tree roots. Now extend the trees one level at a time. - nodeQueueCurrent = nodeQueue; - while(nodeQueueCurrent != nodeQueueEnd) - { - ConstraintGroupNode* node = *nodeQueueCurrent; - PX_ASSERT(node->readFlag(ConstraintGroupNode::eDISCOVERED)); - nodeQueueCurrent++; - - PxU32 addedNodeCount = projectionTreeBuildStep(*node, node->projectionConstraint, nodeQueueEnd); - nodeQueueEnd += addedNodeCount; - } - - brIdx += skipCount; - skipCount = 0; - - // find dominant dynamics that have not been discovered yet and arrange them in a consecutive block - ranksToProcess = BodyRank::sOneWayProjection | BodyRank::sDominantDynamic; - stopIdx = brIdx; - PxU32 k = brIdx; - while((k < bodyRankArray.size()) && (bodyRankArray[k].rank >= ranksToProcess)) - { - ConstraintGroupNode* node = bodyRankArray[k].startingNode; - if (!node->readFlag(ConstraintGroupNode::eDISCOVERED)) - { - node->raiseFlag(ConstraintGroupNode::eDISCOVERED); - bodyRankArray[stopIdx] = bodyRankArray[k]; - stopIdx++; - } - else - skipCount++; - - k++; - } - } - - // - // for every body that has not been discovered yet, we build a tree. Here we do not advance one connectivity level - // at a time because there should be no fight over the nodes among equal roots anymore (or rather no fight that could - // break one-way projection in an unfair way). - // - PX_ASSERT((brIdx == 0) || (brIdx == bodyRankArray.size()) || (bodyRankArray[brIdx].rank < bodyRankArray[brIdx-1].rank)); - for(PxU32 i=brIdx; i < bodyRankArray.size(); i++) - { - nodeQueueEnd = nodeQueue; - - BodyRank& bRank = bodyRankArray[i]; - PX_ASSERT((i == brIdx) || (bRank.rank <= bodyRankArray[i-1].rank)); -#ifdef _DEBUG - if (bRank.rank & (BodyRank::sAttachedToStatic | BodyRank::sAttachedToKinematic)) - { PX_ASSERT(bRank.constraintToFixedAnchor); } - else - { PX_ASSERT(!bRank.constraintToFixedAnchor); } -#endif - - ConstraintGroupNode& node = *bRank.startingNode; - if (!node.readFlag(ConstraintGroupNode::eDISCOVERED)) - { - node.raiseFlag(ConstraintGroupNode::eDISCOVERED); - - PxU32 addedNodeCount = projectionTreeBuildStep(node, bRank.constraintToFixedAnchor, nodeQueueEnd); - nodeQueueEnd += addedNodeCount; - - nodeQueueCurrent = nodeQueue; - while(nodeQueueCurrent != nodeQueueEnd) - { - ConstraintGroupNode* n = *nodeQueueCurrent; - PX_ASSERT(n->readFlag(ConstraintGroupNode::eDISCOVERED)); - PX_ASSERT(n->projectionConstraint); - nodeQueueCurrent++; - - PxU32 nodeCount = projectionTreeBuildStep(*n, n->projectionConstraint, nodeQueueEnd); - nodeQueueEnd += nodeCount; - } - - node.projectionNextRoot = firstProjectionTreeRoot; - firstProjectionTreeRoot = &node; - } - } - - root.setProjectionTreeRoot(firstProjectionTreeRoot); - - PX_FREE(nodeQueue); - } - else - PxGetFoundation().error(PxErrorCode::eOUT_OF_MEMORY, __FILE__, __LINE__, "Allocating projection node queue failed!"); - } -} - - -PxU32 Sc::ConstraintProjectionTree::projectionTreeBuildStep(ConstraintGroupNode& node, ConstraintSim* cToParent, ConstraintGroupNode** nodeQueue) -{ - PX_ASSERT(node.readFlag(ConstraintGroupNode::eDISCOVERED)); - - PxU32 nodeQueueFillCount = 0; - - //go through all constraints attached to the body. - BodySim* body = node.body; - PxU32 size = body->getActorInteractionCount(); - Sc::Interaction** interactions = body->getActorInteractions(); - while(size--) - { - Interaction* interaction = *interactions++; - if (interaction->getType() == InteractionType::eCONSTRAINTSHADER) - { - ConstraintSim* c = static_cast(interaction)->getConstraint(); - - if (c != cToParent) //don't go back along the edge we came from (not really necessary I guess since the ConstraintGroupNode::eDISCOVERED marker should solve this) - { - PxU32 projectToBody, projectToOtherBody; - BodySim* neighbor; - getConstraintStatus(*c, body, neighbor, projectToBody, projectToOtherBody); - - if(!isFixedBody(neighbor) && (!projectToOtherBody || projectToBody)) //just ignore the eventual constraint with environment over here. Body might be attached to multiple fixed anchors. - //Also make sure to ignore one-way projection that goes the opposite way. - { - ConstraintGroupNode* neighborNode = neighbor->getConstraintGroup(); - PX_ASSERT(neighborNode); - - if (!neighborNode->readFlag(ConstraintGroupNode::eDISCOVERED)) - { - *nodeQueue = neighborNode; - - neighborNode->initProjectionData(&node, c); - neighborNode->raiseFlag(ConstraintGroupNode::eDISCOVERED); //flag body nodes that we process so we can detect loops - - nodeQueueFillCount++; - nodeQueue++; - } - } - } - } - } - - return nodeQueueFillCount; -} - - -void Sc::ConstraintProjectionTree::purgeProjectionTrees(ConstraintGroupNode& root) -{ - PX_ASSERT(&root == root.parent); - PX_ASSERT(root.hasProjectionTreeRoot()); - - // CA: New code (non recursive: recursive calls can cause stack overflow with huge trees) - ConstraintGroupNode* projRoot = root.projectionFirstRoot; - do - { - ConstraintGroupNode* currentNode = projRoot; - projRoot = projRoot->projectionNextRoot; // need to do it here because the info might get cleared below - - do - { - // Go down the tree until we find a leaf - if (currentNode->projectionFirstChild) - { - currentNode = currentNode->projectionFirstChild; - continue; - } - - // Delete current node and go to next sibling or parent - ConstraintGroupNode* nodeToDelete = currentNode; - ConstraintGroupNode* parent = currentNode->projectionParent; - currentNode = currentNode->projectionNextSibling; - - // Mark parent as leaf - if (nodeToDelete->projectionParent) - nodeToDelete->projectionParent->projectionFirstChild = NULL; - - // Clear projection info - nodeToDelete->clearProjectionData(); - - if (currentNode != NULL) - continue; - - // No more siblings jump back to parent - currentNode = parent; - - } while (currentNode != NULL); - - } while (projRoot != NULL); - - root.projectionFirstRoot = NULL; // it can happen that the constraint graph root is not part of a projection tree (if it is a kinematic, for example) but it still points to the - // first projection tree root and that needs to get cleaned up as well. - PX_ASSERT(!root.projectionNextRoot); - PX_ASSERT(!root.projectionParent); - PX_ASSERT(!root.projectionFirstChild); - PX_ASSERT(!root.projectionNextSibling); - PX_ASSERT(!root.projectionConstraint); -} - - -void Sc::ConstraintProjectionTree::projectPoseForTree(ConstraintGroupNode& node, PxArray& projectedBodies) -{ - // create a dummy node to keep the loops compact while covering the special case of the first node - PX_ASSERT(node.body); - ConstraintGroupNode dummyNode(*node.body); - dummyNode.projectionNextSibling = &node; - ConstraintGroupNode* currentNode = &dummyNode; - - // non recursive: recursive calls can cause stack overflow with huge trees - do - { - ConstraintGroupNode* nextSiblingNode = currentNode->projectionNextSibling; - - while (nextSiblingNode) - { - currentNode = nextSiblingNode; - ConstraintGroupNode* nextChildNode = currentNode; - - do - { - currentNode = nextChildNode; - - //----------------------------------------------------------------------------- - ConstraintSim* c = currentNode->projectionConstraint; - - if (c && c->hasDynamicBody() && c->needsProjection()) - { - c->projectPose(currentNode->body, projectedBodies); - } - //----------------------------------------------------------------------------- - - nextChildNode = currentNode->projectionFirstChild; - - } while (nextChildNode); - - nextSiblingNode = currentNode->projectionNextSibling; - } - - currentNode = currentNode->projectionParent; - - } while (currentNode != NULL); -} - - -void Sc::ConstraintProjectionTree::projectPose(ConstraintGroupNode& root, PxArray& projectedBodies) -{ - PX_ASSERT(&root == root.parent); - PX_ASSERT(root.hasProjectionTreeRoot()); - - ConstraintGroupNode* projRoot = root.projectionFirstRoot; - do - { - projectPoseForTree(*projRoot, projectedBodies); - projRoot = projRoot->projectionNextRoot; - - } while (projRoot != NULL); -} diff --git a/physx/source/simulationcontroller/src/ScConstraintSim.cpp b/physx/source/simulationcontroller/src/ScConstraintSim.cpp index cba1741b6..ced3d15d8 100644 --- a/physx/source/simulationcontroller/src/ScConstraintSim.cpp +++ b/physx/source/simulationcontroller/src/ScConstraintSim.cpp @@ -26,27 +26,29 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#include "ScConstraintProjectionManager.h" #include "ScBodySim.h" #include "ScStaticSim.h" #include "ScConstraintCore.h" #include "ScConstraintSim.h" #include "ScConstraintInteraction.h" #include "ScElementSimInteraction.h" -#include "CmVisualization.h" -#include "DyContext.h" using namespace physx; +using namespace Sc; -PX_FORCE_INLINE void invalidateConstraintGroupsOnAdd(Sc::ConstraintProjectionManager& cpm, Sc::BodySim* b0, Sc::BodySim* b1, Sc::ConstraintSim& constraint) +static ConstraintInteraction* createInteraction(ConstraintSim* sim, RigidCore* r0, RigidCore* r1, Scene& scene) { - // constraint groups get built by starting from dirty constraints that need projection. If a non-projecting constraint gets added - // we need to restart the whole process (we do not want to track dirty non-projecting constraints because of a scenario where - // all constraints of a group get switched to non-projecting which should kill the group and not rebuild a new one). - if (b0 && b0->getConstraintGroup()) - cpm.invalidateGroup(*b0->getConstraintGroup(), &constraint); - if (b1 && b1->getConstraintGroup()) - cpm.invalidateGroup(*b1->getConstraintGroup(), &constraint); + return scene.getConstraintInteractionPool()->construct( sim, + r0 ? *r0->getSim() : scene.getStaticAnchor(), + r1 ? *r1->getSim() : scene.getStaticAnchor()); +} + +static void releaseInteraction(ConstraintInteraction* interaction, const ConstraintSim* sim, Scene& scene) +{ + if(!sim->isBroken()) + interaction->destroy(); + + scene.getConstraintInteractionPool()->destroy(interaction); } Sc::ConstraintSim::ConstraintSim(ConstraintCore& core, RigidCore* r0, RigidCore* r1, Scene& scene) : @@ -58,17 +60,17 @@ Sc::ConstraintSim::ConstraintSim(ConstraintCore& core, RigidCore* r0, RigidCore* mBodies[0] = (r0 && (r0->getActorCoreType() != PxActorType::eRIGID_STATIC)) ? static_cast(r0->getSim()) : 0; mBodies[1] = (r1 && (r1->getActorCoreType() != PxActorType::eRIGID_STATIC)) ? static_cast(r1->getSim()) : 0; - mLowLevelConstraint.index = scene.getConstraintIDTracker().createID(); + const PxU32 id = scene.getConstraintIDTracker().createID(); + + mLowLevelConstraint.index = id; PxPinnedArray& writeBackPool = scene.getDynamicsContext()->getConstraintWriteBackPool(); - if (mLowLevelConstraint.index >= writeBackPool.capacity()) - { + if(id >= writeBackPool.capacity()) writeBackPool.reserve(writeBackPool.capacity() * 2); - } - writeBackPool.resize(PxMax(writeBackPool.size(), mLowLevelConstraint.index + 1)); - writeBackPool[mLowLevelConstraint.index].initialize(); + writeBackPool.resize(PxMax(writeBackPool.size(), id + 1)); + writeBackPool[id].initialize(); - if (!createLLConstraint()) + if(!createLLConstraint()) return; PxReal linBreakForce, angBreakForce; @@ -78,16 +80,7 @@ Sc::ConstraintSim::ConstraintSim(ConstraintCore& core, RigidCore* r0, RigidCore* core.setSim(this); - ConstraintProjectionManager& cpm = scene.getProjectionManager(); - if (!needsProjection()) - invalidateConstraintGroupsOnAdd(cpm, mBodies[0], mBodies[1], *this); - else - cpm.addToPendingGroupUpdates(*this); - - ConstraintSim* cs = this; // to make the Wii U compiler happy - mInteraction = mScene.getConstraintInteractionPool()->construct(cs, - r0 ? *r0->getSim() : scene.getStaticAnchor(), - r1 ? *r1->getSim() : scene.getStaticAnchor()); + mInteraction = createInteraction(this, r0, r1, scene); PX_ASSERT(!mInteraction->isRegistered()); // constraint interactions must not register in the scene, there is a list of Sc::ConstraintSim instead } @@ -97,54 +90,52 @@ Sc::ConstraintSim::~ConstraintSim() PX_ASSERT(mInteraction); // This is fine now, a body which gets removed from the scene removes all constraints automatically PX_ASSERT(!mInteraction->isRegistered()); // constraint interactions must not register in the scene, there is a list of Sc::ConstraintSim instead - if (readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)) - mScene.getProjectionManager().removeFromPendingGroupUpdates(*this); - - if (!isBroken()) - mInteraction->destroy(); + releaseInteraction(mInteraction, this, mScene); mScene.getConstraintIDTracker().releaseID(mLowLevelConstraint.index); - mScene.getConstraintInteractionPool()->destroy(mInteraction); - destroyLLConstraint(); mCore.setSim(NULL); } +static PX_FORCE_INLINE void setLLBodies(Dy::Constraint& c, BodySim* b0, BodySim* b1) +{ + PxsRigidBody* body0 = b0 ? &b0->getLowLevelBody() : NULL; + PxsRigidBody* body1 = b1 ? &b1->getLowLevelBody() : NULL; + + c.body0 = body0; + c.body1 = body1; + + c.bodyCore0 = body0 ? &body0->getCore() : NULL; + c.bodyCore1 = body1 ? &body1->getCore() : NULL; +} + bool Sc::ConstraintSim::createLLConstraint() { - Dy::Constraint& llc = mLowLevelConstraint; ConstraintCore& core = getCore(); - PxU32 constantBlockSize = core.getConstantBlockSize(); + const PxU32 constantBlockSize = core.getConstantBlockSize(); void* constantBlock = mScene.allocateConstraintBlock(constantBlockSize); if(!constantBlock) - { - PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, __FILE__, __LINE__, "Constraint: could not allocate low-level resources."); - return false; - } + return PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "Constraint: could not allocate low-level resources."); //Ensure the constant block isn't just random data because some functions may attempt to use it before it is //setup. Specifically pvd visualization of joints //-CN - PxMemZero( constantBlock, constantBlockSize); + PxMemZero(constantBlock, constantBlockSize); + Dy::Constraint& llc = mLowLevelConstraint; core.getBreakForce(llc.linBreakForce, llc.angBreakForce); llc.flags = core.getFlags(); llc.constantBlockSize = PxU16(constantBlockSize); llc.solverPrep = core.getSolverPrep(); - llc.project = core.getProject(); llc.constantBlock = constantBlock; + llc.minResponseThreshold = core.getMinResponseThreshold(); //llc.index = mLowLevelConstraint.index; - llc.body0 = mBodies[0] ? &mBodies[0]->getLowLevelBody() : 0; - llc.body1 = mBodies[1] ? &mBodies[1]->getLowLevelBody() : 0; - llc.bodyCore0 = mBodies[0] ? &llc.body0->getCore() : NULL; - llc.bodyCore1 = mBodies[1] ? &llc.body1->getCore() : NULL; - - llc.minResponseThreshold = core.getMinResponseThreshold(); + setLLBodies(llc, mBodies[0], mBodies[1]); return true; } @@ -152,77 +143,24 @@ bool Sc::ConstraintSim::createLLConstraint() void Sc::ConstraintSim::destroyLLConstraint() { if(mLowLevelConstraint.constantBlock) - { - mScene.deallocateConstraintBlock(mLowLevelConstraint.constantBlock, - mLowLevelConstraint.constantBlockSize); - } + mScene.deallocateConstraintBlock(mLowLevelConstraint.constantBlock, mLowLevelConstraint.constantBlockSize); } void Sc::ConstraintSim::setBodies(RigidCore* r0, RigidCore* r1) { PX_ASSERT(mInteraction); - BodySim* b = getConstraintGroupBody(); - if(b) - mScene.getProjectionManager().invalidateGroup(*b->getConstraintGroup(), this); - - if(!isBroken()) - mInteraction->destroy(); - - mScene.getConstraintInteractionPool()->destroy(mInteraction); - mInteraction = NULL; + releaseInteraction(mInteraction, this, mScene); BodySim* b0 = (r0 && (r0->getActorCoreType() != PxActorType::eRIGID_STATIC)) ? static_cast(r0->getSim()) : 0; BodySim* b1 = (r1 && (r1->getActorCoreType() != PxActorType::eRIGID_STATIC)) ? static_cast(r1->getSim()) : 0; - ConstraintProjectionManager& cpm = mScene.getProjectionManager(); - PxConstraintFlags::InternalType projectionNeeded = getCore().getFlags() & PxConstraintFlag::ePROJECTION; // can not use "needsProjection()" because that takes into account whether the constraint is broken - if (!projectionNeeded) - invalidateConstraintGroupsOnAdd(cpm, b0, b1, *this); - else if (!readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)) - cpm.addToPendingGroupUpdates(*this); - - Dy::Constraint& c = mLowLevelConstraint; - - c.body0 = b0 ? &b0->getLowLevelBody() : NULL; - c.body1 = b1 ? &b1->getLowLevelBody() : NULL; - - c.bodyCore0 = c.body0 ? &c.body0->getCore() : NULL; - c.bodyCore1 = c.body1 ? &c.body1->getCore() : NULL; + setLLBodies(mLowLevelConstraint, b0, b1); mBodies[0] = b0; mBodies[1] = b1; - ConstraintSim* cs = this; // to make the Wii U compiler happy - mInteraction = mScene.getConstraintInteractionPool()->construct(cs, - r0 ? *r0->getSim() : mScene.getStaticAnchor(), - r1 ? *r1->getSim() : mScene.getStaticAnchor()); -} - -void Sc::ConstraintSim::checkMaxForceExceeded() -{ - PX_ASSERT(readFlag(eCHECK_MAX_FORCE_EXCEEDED)); - - Dy::ConstraintWriteback& solverOutput = mScene.getDynamicsContext()->getConstraintWriteBackPool()[mLowLevelConstraint.index]; - if(solverOutput.broken) - { - setFlag(ConstraintSim::eBROKEN); - mScene.addBrokenConstraint(&mCore); - mCore.breakApart(); - mInteraction->destroy(); - - // update related SIPs - { - ActorSim& a0 = mInteraction->getActorSim0(); - ActorSim& a1 = mInteraction->getActorSim1(); - ActorSim& actor = (a0.getActorInteractionCount()< a1.getActorInteractionCount()) ? a0 : a1; - - actor.setActorsInteractionsDirty(InteractionDirtyFlag::eFILTER_STATE, NULL, InteractionFlag::eRB_ELEMENT); - // because broken constraints can re-enable contact response between the two bodies - } - - PX_ASSERT(!readFlag(eCHECK_MAX_FORCE_EXCEEDED)); - } + mInteraction = createInteraction(this, r0, r1, mScene); } void Sc::ConstraintSim::getForce(PxVec3& lin, PxVec3& ang) @@ -263,213 +201,7 @@ void Sc::ConstraintSim::setBreakForceLL(PxReal linear, PxReal angular) mLowLevelConstraint.angBreakForce = angular; } -void Sc::ConstraintSim::postFlagChange(PxConstraintFlags oldFlags, PxConstraintFlags newFlags) +void Sc::ConstraintSim::postFlagChange(PxConstraintFlags /*oldFlags*/, PxConstraintFlags newFlags) { mLowLevelConstraint.flags = newFlags; - - // PT: don't convert to bool if not needed - const PxU32 hadProjection = (oldFlags & PxConstraintFlag::ePROJECTION); - const PxU32 needsProjection = (newFlags & PxConstraintFlag::ePROJECTION); - - if(needsProjection && !hadProjection) - { - PX_ASSERT(!readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)); // Non-projecting constrainst should not be part of the update list - - Sc::BodySim* b0 = getBody(0); - Sc::BodySim* b1 = getBody(1); - if ((!b0 || b0->getConstraintGroup()) && (!b1 || b1->getConstraintGroup())) - { - // Already part of a constraint group but not as a projection constraint -> re-generate projection tree - PX_ASSERT(b0 != NULL || b1 != NULL); - if (b0) - b0->getConstraintGroup()->markForProjectionTreeRebuild(mScene.getProjectionManager()); - else - b1->getConstraintGroup()->markForProjectionTreeRebuild(mScene.getProjectionManager()); - } - else - { - // Not part of a constraint group yet - mScene.getProjectionManager().addToPendingGroupUpdates(*this); - } - } - else if(!needsProjection && hadProjection) - { - if (!readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)) - { - Sc::BodySim* b = getConstraintGroupBody(); - if (b) - { - PX_ASSERT(b->getConstraintGroup()); - mScene.getProjectionManager().invalidateGroup(*b->getConstraintGroup(), NULL); - } - // This is conservative but it could be the case that this constraint with projection was the only - // one in the group and thus the whole group must be killed. If we had a counter for the number of - // projecting constraints per group, we could just update the projection tree if the counter was - // larger than 1. But switching the projection flag does not seem likely anyway. - } - else - mScene.getProjectionManager().removeFromPendingGroupUpdates(*this); // Was part of a group which got invalidated - - PX_ASSERT(!readFlag(ConstraintSim::ePENDING_GROUP_UPDATE)); // make sure the expected post-condition is met for all paths - } } - -Sc::RigidSim& Sc::ConstraintSim::getRigid(PxU32 i) -{ - PX_ASSERT(mInteraction); - - if (i == 0) - return static_cast(mInteraction->getActorSim0()); - else - return static_cast(mInteraction->getActorSim1()); -} - -bool Sc::ConstraintSim::hasDynamicBody() -{ - return (mBodies[0] && (!mBodies[0]->isKinematic())) || (mBodies[1] && (!mBodies[1]->isKinematic())); -} - -static void constrainMotion(PxsRigidBody* body, PxTransform& targetPose) -{ - //Now constraint deltaPos and deltaRot - const PxU32 lockFlags = body->mCore->lockFlags; - - if (lockFlags) - { - const PxTransform& currBody2World = body->mCore->body2World; - - PxVec3 deltaPos = targetPose.p - currBody2World.p; - - PxQuat deltaQ = targetPose.q * currBody2World.q.getConjugate(); - - if (deltaQ.w < 0) //shortest angle. - deltaQ = -deltaQ; - - PxReal angle; - PxVec3 axis; - deltaQ.toRadiansAndUnitAxis(angle, axis); - PxVec3 deltaRot = axis * angle; - - if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_X) - deltaPos.x = 0.0f; - if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_Y) - deltaPos.y = 0.0f; - if (lockFlags & PxRigidDynamicLockFlag::eLOCK_LINEAR_Z) - deltaPos.z = 0.0f; - if (lockFlags & PxRigidDynamicLockFlag::eLOCK_ANGULAR_X) - deltaRot.x = 0.0f; - if (lockFlags & PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y) - deltaRot.y = 0.0f; - if (lockFlags & PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z) - deltaRot.z = 0.0f; - - targetPose.p = currBody2World.p + deltaPos; - - PxReal w2 = deltaRot.magnitudeSquared(); - if (w2 != 0.0f) - { - PxReal w = PxSqrt(w2); - - const PxReal v = w * 0.5f; - PxReal s, q; - PxSinCos(v, s, q); - s /= w; - - const PxVec3 pqr = deltaRot * s; - const PxQuat quatVel(pqr.x, pqr.y, pqr.z, 0); - PxQuat result = quatVel * currBody2World.q; - - result += currBody2World.q * q; - - targetPose.q = result.getNormalized(); - } - else - { - targetPose.q = currBody2World.q; - } - } -} - -void Sc::ConstraintSim::projectPose(BodySim* childBody, PxArray& projectedBodies) -{ -#if PX_DEBUG - // We expect bodies in low level constraints to have same order as high level counterpart - PxsRigidBody* b0 = mLowLevelConstraint.body0; - PxsRigidBody* b1 = mLowLevelConstraint.body1; - PX_ASSERT( (childBody == getBody(0) && &childBody->getLowLevelBody() == b0) || - (childBody == getBody(1) && &childBody->getLowLevelBody() == b1) ); -#endif - - Dy::Constraint& constraint = getLowLevelConstraint(); - bool projectToBody0 = childBody == getBody(1); - - PxsRigidBody* body0 = constraint.body0, - * body1 = constraint.body1; - - PxTransform body0ToWorld = body0 ? body0->getPose() : PxTransform(PxIdentity); - PxTransform body1ToWorld = body1 ? body1->getPose() : PxTransform(PxIdentity); - - (*constraint.project)(constraint.constantBlock, body0ToWorld, body1ToWorld, projectToBody0); - - if(projectToBody0) - { - PX_ASSERT(body1); - //Constrain new pose to valid world motion - constrainMotion(body1, body1ToWorld); - body1->setPose(body1ToWorld); - projectedBodies.pushBack(getBody(1)); - } - else - { - PX_ASSERT(body0); - //Constrain new pose to valid world motion - constrainMotion(body0, body0ToWorld); - body0->setPose(body0ToWorld); - projectedBodies.pushBack(getBody(0)); - } -} - -bool Sc::ConstraintSim::needsProjection() -{ - const Dy::ConstraintWriteback& solverOutput = mScene.getDynamicsContext()->getConstraintWriteBackPool()[mLowLevelConstraint.index]; - return (getCore().getFlags() & PxConstraintFlag::ePROJECTION ) && !solverOutput.broken; -} - -PX_INLINE Sc::BodySim* Sc::ConstraintSim::getConstraintGroupBody() -{ - BodySim* b = NULL; - if (mBodies[0] && mBodies[0]->getConstraintGroup()) - b = mBodies[0]; - else if (mBodies[1] && mBodies[1]->getConstraintGroup()) - b = mBodies[1]; - - return b; -} - -void Sc::ConstraintSim::visualize(PxRenderBuffer& output) -{ - if(!(getCore().getFlags() & PxConstraintFlag::eVISUALIZATION)) - return; - - PxsRigidBody* b0 = mLowLevelConstraint.body0; - PxsRigidBody* b1 = mLowLevelConstraint.body1; - - const PxTransform idt(PxIdentity); - const PxTransform& t0 = b0 ? b0->getPose() : idt; - const PxTransform& t1 = b1 ? b1->getPose() : idt; - - const PxReal frameScale = mScene.getVisualizationScale() * mScene.getVisualizationParameter(PxVisualizationParameter::eJOINT_LOCAL_FRAMES); - const PxReal limitScale = mScene.getVisualizationScale() * mScene.getVisualizationParameter(PxVisualizationParameter::eJOINT_LIMITS); - - PxRenderOutput renderOut(output); - Cm::ConstraintImmediateVisualizer viz(frameScale, limitScale, renderOut); - - PxU32 flags = 0; - if(frameScale!=0.0f) - flags |= PxConstraintVisualizationFlag::eLOCAL_FRAMES; - if(limitScale!=0.0f) - flags |= PxConstraintVisualizationFlag::eLIMITS; - - mCore.getVisualize()(viz, mLowLevelConstraint.constantBlock, t0, t1, flags); -} - diff --git a/physx/source/simulationcontroller/src/ScConstraintSim.h b/physx/source/simulationcontroller/src/ScConstraintSim.h index 6f20e1ec5..187db7c72 100644 --- a/physx/source/simulationcontroller/src/ScConstraintSim.h +++ b/physx/source/simulationcontroller/src/ScConstraintSim.h @@ -46,26 +46,19 @@ namespace Sc class ConstraintSim : public PxUserAllocated { + PX_NOCOPY(ConstraintSim) public: enum Enum { - ePENDING_GROUP_UPDATE = (1<<0), // For constraint projection an island of the bodies connected by constraints is generated. - // Schedule generation/update of the island this constraint is a part of. eBREAKABLE = (1<<1), // The constraint can break eCHECK_MAX_FORCE_EXCEEDED = (1<<2), // This constraint will get tested for breakage at the end of the sim step eBROKEN = (1<<3) }; - ConstraintSim(ConstraintCore& core, - RigidCore* r0, - RigidCore* r1, - Scene& scene); - + ConstraintSim(ConstraintCore& core, RigidCore* r0, RigidCore* r1, Scene& scene); ~ConstraintSim(); void setBodies(RigidCore* r0, RigidCore* r1); - void checkMaxForceExceeded(); - void setBreakForceLL(PxReal linear, PxReal angular); PX_FORCE_INLINE void setMinResponseThresholdLL(PxReal threshold) { mLowLevelConstraint.minResponseThreshold = threshold; } PX_FORCE_INLINE const void* getConstantsLL() const { return mLowLevelConstraint.constantBlock; } @@ -80,8 +73,6 @@ namespace Sc return mBodies[i]; } - RigidSim& getRigid(PxU32 i); - void getForce(PxVec3& force, PxVec3& torque); PX_FORCE_INLINE PxU8 readFlag(PxU8 flag) const { return PxU8(mFlags & flag); } @@ -91,30 +82,14 @@ namespace Sc PX_FORCE_INLINE const ConstraintInteraction* getInteraction() const { return mInteraction; } - //------------------------------------ Projection trees ----------------------------------------- private: - PX_INLINE BodySim* getConstraintGroupBody(); - - public: - bool hasDynamicBody(); - - void projectPose(BodySim* childBody, PxArray& projectedBodies); - PX_FORCE_INLINE BodySim* getOtherBody(BodySim* b) { return (b == mBodies[0]) ? mBodies[1] : mBodies[0]; } - PX_FORCE_INLINE BodySim* getAnyBody() { return mBodies[0] ? mBodies[0] : mBodies[1]; } - - bool needsProjection(); - //----------------------------------------------------------------------------------------------- - - void visualize(PxRenderBuffer &out); - private: - ConstraintSim& operator=(const ConstraintSim&); bool createLLConstraint(); void destroyLLConstraint(); - private: + Dy::Constraint mLowLevelConstraint; Scene& mScene; ConstraintCore& mCore; - ConstraintInteraction* mInteraction; + ConstraintInteraction* mInteraction; // PT: why do we have an interaction object here? BodySim* mBodies[2]; PxU8 mFlags; }; diff --git a/physx/source/simulationcontroller/src/ScContactStream.h b/physx/source/simulationcontroller/src/ScContactStream.h index e1887fc94..1f693d1c8 100644 --- a/physx/source/simulationcontroller/src/ScContactStream.h +++ b/physx/source/simulationcontroller/src/ScContactStream.h @@ -309,6 +309,7 @@ PX_FORCE_INLINE void Sc::ContactStreamManager::fillInContactReportExtraData(PxCo const BodySim& bs = static_cast(rs); const BodyCore& bc = bs.getBodyCore(); const PxTransform& src = (!isCCDPass && useCurrentTransform) ? bc.getBody2World() : bs.getLowLevelBody().getLastCCDTransform(); + // PT:: tag: scalar transform*transform cpPose->globalPose[index] = src * bc.getBody2Actor().getInverse(); } else diff --git a/physx/source/simulationcontroller/src/ScElementInteractionMarker.cpp b/physx/source/simulationcontroller/src/ScElementInteractionMarker.cpp index 8752aa386..2157444f3 100644 --- a/physx/source/simulationcontroller/src/ScElementInteractionMarker.cpp +++ b/physx/source/simulationcontroller/src/ScElementInteractionMarker.cpp @@ -34,11 +34,8 @@ using namespace physx; Sc::ElementInteractionMarker::~ElementInteractionMarker() { if(isRegistered()) - { - Scene& scene = getScene(); - scene.unregisterInteraction(this); - scene.getNPhaseCore()->unregisterInteraction(this); - } + getScene().unregisterInteraction(this); + unregisterFromActors(); } diff --git a/physx/source/simulationcontroller/src/ScElementInteractionMarker.h b/physx/source/simulationcontroller/src/ScElementInteractionMarker.h index ef1df77ca..0b58429d5 100644 --- a/physx/source/simulationcontroller/src/ScElementInteractionMarker.h +++ b/physx/source/simulationcontroller/src/ScElementInteractionMarker.h @@ -41,9 +41,6 @@ namespace Sc public: PX_INLINE ElementInteractionMarker(ElementSim& element0, ElementSim& element1, bool createParallel/* = false*/); ~ElementInteractionMarker(); - - bool onActivate_(void*) { return false; } - bool onDeactivate_() { return true; } }; } // namespace Sc @@ -54,11 +51,10 @@ PX_INLINE Sc::ElementInteractionMarker::ElementInteractionMarker(ElementSim& ele { if(!createParallel) { - bool active = registerInActors(); - PX_UNUSED(active); - PX_ASSERT(!active); - getScene().registerInteraction(this, false); - getScene().getNPhaseCore()->registerInteraction(this); + // PT: no call to onActivate() here, interaction markers are always inactive + registerInActors(); + Scene& scene = getScene(); + scene.registerInteraction(this, false); } } diff --git a/physx/source/simulationcontroller/src/ScElementSim.cpp b/physx/source/simulationcontroller/src/ScElementSim.cpp index 34280bf7c..02a208975 100644 --- a/physx/source/simulationcontroller/src/ScElementSim.cpp +++ b/physx/source/simulationcontroller/src/ScElementSim.cpp @@ -81,17 +81,17 @@ namespace ~ElemSimPtrTableStorageManager() {} // PtrTableStorageManager - virtual void** allocate(PxU32 capacity) + virtual void** allocate(PxU32 capacity) PX_OVERRIDE { return PX_ALLOCATE(void*, capacity, "CmPtrTable pointer array"); } - virtual void deallocate(void** addr, PxU32 /*capacity*/) + virtual void deallocate(void** addr, PxU32 /*capacity*/) PX_OVERRIDE { PX_FREE(addr); } - virtual bool canReuse(PxU32 /*originalCapacity*/, PxU32 /*newCapacity*/) + virtual bool canReuse(PxU32 /*originalCapacity*/, PxU32 /*newCapacity*/) PX_OVERRIDE { return false; } @@ -143,19 +143,6 @@ Sc::ElementSim::~ElementSim() mActor.onElementDetach(*this); } -void Sc::ElementSim::setElementInteractionsDirty(InteractionDirtyFlag::Enum flag, PxU8 interactionFlag) -{ - ElementSim::ElementInteractionIterator iter = getElemInteractions(); - ElementSimInteraction* interaction = iter.getNext(); - while(interaction) - { - if(interaction->readInteractionFlag(interactionFlag)) - interaction->setDirty(flag); - - interaction = iter.getNext(); - } -} - void Sc::ElementSim::addToAABBMgr(PxReal contactDistance, Bp::FilterGroup::Enum group, Bp::ElementType::Enum type) { Sc::Scene& scene = getScene(); diff --git a/physx/source/simulationcontroller/src/ScElementSim.h b/physx/source/simulationcontroller/src/ScElementSim.h index 39ce0c306..5c8af0f63 100644 --- a/physx/source/simulationcontroller/src/ScElementSim.h +++ b/physx/source/simulationcontroller/src/ScElementSim.h @@ -29,13 +29,13 @@ #ifndef SC_ELEMENT_SIM_H #define SC_ELEMENT_SIM_H -#include "foundation/PxUserAllocated.h" #include "PxFiltering.h" #include "PxvConfig.h" #include "ScActorSim.h" #include "ScInteraction.h" #include "BpAABBManager.h" #include "ScObjectIDTracker.h" +#include "ScScene.h" namespace physx { @@ -43,10 +43,8 @@ namespace Sc { class ElementSimInteraction; - /* - A ElementSim is a part of a ActorSim. It contributes to the activation framework by adding its - interactions to the actor. */ - class ElementSim : public PxUserAllocated + // A ElementSim is a part of a ActorSim. It contributes to the activation framework by adding its interactions to the actor. + class ElementSim { PX_NOCOPY(ElementSim) @@ -83,8 +81,12 @@ namespace Sc public: // Get an iterator to the interactions connected to the element - PX_FORCE_INLINE ElementInteractionIterator getElemInteractions() const { return ElementInteractionIterator(*this, mActor.getActorInteractionCount(), mActor.getActorInteractions()); } - PX_FORCE_INLINE ElementInteractionReverseIterator getElemInteractionsReverse() const { return ElementInteractionReverseIterator(*this, mActor.getActorInteractionCount(), mActor.getActorInteractions()); } + // PT: this may seem strange at first glance since the "element interactions" appear to use the "actor interactions". The thing that makes this work is hidden + // inside the iterator implementation: it does parse all the actor interactions indeed, but filters out the ones that do not contain "this", i.e. the desired element. + // So this is inefficient (parsing potentially many more interactions than needed, imagine in a large compound) but it works, and the iterator has a point - it isn't + // just the same as parsing the actor's array. + PX_FORCE_INLINE ElementInteractionIterator getElemInteractions() const { return ElementInteractionIterator(*this, mActor.getActorInteractionCount(), mActor.getActorInteractions()); } + PX_FORCE_INLINE ElementInteractionReverseIterator getElemInteractionsReverse() const { return ElementInteractionReverseIterator(*this, mActor.getActorInteractionCount(), mActor.getActorInteractions()); } PX_FORCE_INLINE ActorSim& getActor() const { return mActor; } @@ -93,13 +95,9 @@ namespace Sc PX_FORCE_INLINE PxU32 getElementID() const { return mElementID; } PX_FORCE_INLINE bool isInBroadPhase() const { return mInBroadPhase; } - //PX_FORCE_INLINE Bp::ElementType::Enum getElementType() const { return mType; } - void addToAABBMgr(PxReal contactDistance, Bp::FilterGroup::Enum group, Bp::ElementType::Enum type); bool removeFromAABBMgr(); - void setElementInteractionsDirty(InteractionDirtyFlag::Enum flag, PxU8 interactionFlag); - PX_FORCE_INLINE void initID() { Scene& scene = getScene(); @@ -114,9 +112,8 @@ namespace Sc protected: ActorSim& mActor; - PxU32 mElementID : 31; + PxU32 mElementID : 31; // PT: ID provided by Sc::Scene::mElementIDPool PxU32 mInBroadPhase : 1; - //Bp::ElementType::Enum mType; public: PxU32 mShapeArrayIndex; }; diff --git a/physx/source/simulationcontroller/src/ScElementSimInteraction.h b/physx/source/simulationcontroller/src/ScElementSimInteraction.h index 2edb19057..fc6c73484 100644 --- a/physx/source/simulationcontroller/src/ScElementSimInteraction.h +++ b/physx/source/simulationcontroller/src/ScElementSimInteraction.h @@ -42,9 +42,6 @@ namespace Sc PX_FORCE_INLINE ElementSim& getElement0() const { return mElement0; } PX_FORCE_INLINE ElementSim& getElement1() const { return mElement1; } - PX_FORCE_INLINE void setFilterPairIndex(PxU32 filterPairIndex) { mFilterPairIndex = filterPairIndex; } - PX_FORCE_INLINE PxU32 getFilterPairIndex() const { return mFilterPairIndex; } - protected: PX_INLINE ElementSimInteraction(ElementSim& element0, ElementSim& element1, InteractionType::Enum type, PxU8 flags); ~ElementSimInteraction() {} @@ -53,7 +50,6 @@ namespace Sc ElementSim& mElement0; ElementSim& mElement1; - PxU32 mFilterPairIndex; PxU32 mFlags; // PT: moved there in padding bytes, from ShapeInteraction }; @@ -62,10 +58,9 @@ namespace Sc ////////////////////////////////////////////////////////////////////////// PX_INLINE Sc::ElementSimInteraction::ElementSimInteraction(ElementSim& element0, ElementSim& element1, InteractionType::Enum type, PxU8 flags) : - Interaction (element0.getActor(), element1.getActor(), type, flags), - mElement0 (element0), - mElement1 (element1), - mFilterPairIndex(INVALID_FILTER_PAIR_INDEX) + Interaction (element0.getActor(), element1.getActor(), type, flags), + mElement0 (element0), + mElement1 (element1) { } diff --git a/physx/source/simulationcontroller/src/ScFEMClothCore.cpp b/physx/source/simulationcontroller/src/ScFEMClothCore.cpp index 337c1bca6..de5ae126e 100644 --- a/physx/source/simulationcontroller/src/ScFEMClothCore.cpp +++ b/physx/source/simulationcontroller/src/ScFEMClothCore.cpp @@ -38,6 +38,7 @@ #include "GuTetrahedronMesh.h" #include "GuBV4.h" #include "geometry/PxTetrahedronMesh.h" +#include "cudamanager/PxCudaContextManager.h" using namespace physx; @@ -51,24 +52,13 @@ Sc::FEMClothCore::FEMClothCore() : mCore.mFlags = PxFEMClothFlags(0); #endif - mCore.mClothPositionInvMass = NULL; - mCore.mClothVelocity = NULL; - mCore.mClothRestPosition = NULL; + mCore.mPositionInvMass = NULL; + mCore.mVelocity = NULL; + mCore.mRestPosition = NULL; mCore.wakeCounter = Physics::sWakeCounterOnCreation; } -Sc::FEMClothCore::~FEMClothCore() -{ - if (mCore.mClothPositionInvMass) - mCore.mClothPositionInvMass->release(); - - if (mCore.mClothVelocity) - mCore.mClothVelocity->release(); - - if (mCore.mClothRestPosition) - mCore.mClothRestPosition->release(); - -} +Sc::FEMClothCore::~FEMClothCore() { } PxFEMParameters Sc::FEMClothCore::getParameter() const { @@ -277,6 +267,14 @@ PxFilterData Sc::FEMClothCore::getSimulationFilterData() const return mFilterData; } +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +void Sc::FEMClothCore::setFlags(PxFEMClothFlags flags) +{ + mCore.mFlags = flags; + mCore.dirty = true; +} +#endif + void Sc::FEMClothCore::onShapeChange(ShapeCore& shape, ShapeChangeNotifyFlags notifyFlags) { diff --git a/physx/source/simulationcontroller/src/ScFEMClothShapeSim.h b/physx/source/simulationcontroller/src/ScFEMClothShapeSim.h index 235537282..3cb5c0cf6 100644 --- a/physx/source/simulationcontroller/src/ScFEMClothShapeSim.h +++ b/physx/source/simulationcontroller/src/ScFEMClothShapeSim.h @@ -27,12 +27,13 @@ #ifndef PX_PHYSICS_FEMCLOTH_SHAPE_SIM #define PX_PHYSICS_FEMCLOTH_SHAPE_SIM +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxPhysXConfig.h" #include "ScElementSim.h" #include "ScShapeSimBase.h" - namespace physx { namespace Sc @@ -78,5 +79,6 @@ namespace physx }; } // namespace Sc } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScFEMClothSim.cpp b/physx/source/simulationcontroller/src/ScFEMClothSim.cpp index eff0c834f..5f3c5a27d 100644 --- a/physx/source/simulationcontroller/src/ScFEMClothSim.cpp +++ b/physx/source/simulationcontroller/src/ScFEMClothSim.cpp @@ -41,8 +41,7 @@ using namespace physx::Dy; Sc::FEMClothSim::FEMClothSim(FEMClothCore& core, Scene& scene) : ActorSim(scene, core), - mShapeSim(*this), - mNumCountedInteractions(0) + mShapeSim(*this) { mLLFEMCloth = scene.createLLFEMCloth(this); @@ -86,19 +85,6 @@ bool Sc::FEMClothSim::isSleeping() const return sim.getActiveNodeIndex(mNodeIndex) == PX_INVALID_NODE; } -void Sc::FEMClothSim::setActive(const bool b, const PxU32 infoFlag) -{ - PX_UNUSED(infoFlag); - if (b) - { - activate(); - } - else - { - deactivate(); - } -} - void Sc::FEMClothSim::onSetWakeCounter() { getScene().getSimulationController()->setClothWakeCounter(mLLFEMCloth); @@ -116,19 +102,4 @@ void Sc::FEMClothSim::attachShapeCore(ShapeCore* core) mLLFEMCloth->setShapeCore(shapeCore); } - -void Sc::FEMClothSim::activate() -{ - mScene.getSimulationController()->activateCloth(mLLFEMCloth); - - activateInteractions(*this); -} - -void Sc::FEMClothSim::deactivate() -{ - mScene.getSimulationController()->deactivateCloth(mLLFEMCloth); - - deactivateInteractions(*this); -} - #endif //PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/simulationcontroller/src/ScFEMClothSim.h b/physx/source/simulationcontroller/src/ScFEMClothSim.h index c9636b1c3..fc1b7f42b 100644 --- a/physx/source/simulationcontroller/src/ScFEMClothSim.h +++ b/physx/source/simulationcontroller/src/ScFEMClothSim.h @@ -27,6 +27,8 @@ #ifndef PX_PHYSICS_FEMCLOTH_SIM #define PX_PHYSICS_FEMCLOTH_SIM +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "foundation/PxUserAllocated.h" #include "DyFEMCloth.h" #include "ScFEMClothCore.h" @@ -40,9 +42,9 @@ namespace physx class Scene; class FEMClothSim : public ActorSim { + PX_NOCOPY(FEMClothSim) public: FEMClothSim(FEMClothCore& core, Scene& scene); - ~FEMClothSim(); PX_INLINE Dy::FEMCloth* getLowLevelFEMCloth() const { return mLLFEMCloth; } @@ -56,34 +58,27 @@ namespace physx bool isSleeping() const; PX_FORCE_INLINE bool isActive() const { return !isSleeping(); } - void setActive(const bool b, const PxU32 infoFlag = 0); + void setActive(bool active, bool asPartOfCreation=false); void onSetWakeCounter(); void attachShapeCore(ShapeCore* core); - virtual void registerCountedInteraction() { mNumCountedInteractions++; } - virtual void unregisterCountedInteraction() { mNumCountedInteractions--; } - virtual PxU32 getNumCountedInteractions() const { return mNumCountedInteractions; } - - virtual void activate(); - virtual void deactivate(); - FEMClothShapeSim& getShapeSim() { return mShapeSim; } private: - //FEMClothSim& operator=(const FEMClothSim&); - Dy::FEMCloth* mLLFEMCloth; FEMClothShapeSim mShapeSim; - PxU32 mNumCountedInteractions; PxU32 mIslandNodeIndex; + void activate(); + void deactivate(); }; } // namespace Sc } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScFiltering.cpp b/physx/source/simulationcontroller/src/ScFiltering.cpp new file mode 100644 index 000000000..ac443a45d --- /dev/null +++ b/physx/source/simulationcontroller/src/ScFiltering.cpp @@ -0,0 +1,783 @@ +// 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. + +#include "ScFiltering.h" +#include "ScShapeInteraction.h" +#include "ScTriggerInteraction.h" +#include "ScConstraintCore.h" +#include "ScArticulationSim.h" + +using namespace physx; +using namespace Sc; + +/////////////////////////////////////////////////////////////////////////////// + +PX_IMPLEMENT_OUTPUT_ERROR + +/////////////////////////////////////////////////////////////////////////////// + +static PX_FORCE_INLINE PxU64 getPairID(const ShapeSimBase& s0, const ShapeSimBase& s1) +{ + PxU64 id0 = PxU64(s0.getElementID()); + PxU64 id1 = PxU64(s1.getElementID()); + if(id1 +static PxFilterObjectAttributes getFilterObjectAttributes(const ShapeSimBase& shape) +{ + const ActorSim& actorSim = shape.getActor(); + + PxFilterObjectAttributes filterAttr = actorSim.getFilterAttributes(); + + if(supportTriggers && (shape.getCore().getFlags() & PxShapeFlag::eTRIGGER_SHAPE)) + filterAttr |= PxFilterObjectFlag::eTRIGGER; + +#if PX_DEBUG + BodySim* b = shape.getBodySim(); + if(b) + { + if(!b->isArticulationLink()) + { + if(b->isKinematic()) + PX_ASSERT(filterAttr & PxFilterObjectFlag::eKINEMATIC); + + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::eRIGID_DYNAMIC); + } + else + { + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::eARTICULATION); + } + } + else + { + #if PX_SUPPORT_GPU_PHYSX + // For softbody and particle system, the bodySim is set to null + if(actorSim.isSoftBody()) + { + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::eSOFTBODY); + } + else if(actorSim.isParticleSystem()) + { + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::ePARTICLESYSTEM); + } + else if(actorSim.isFEMCloth()) + { + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::eFEMCLOTH); + } + else if(actorSim.isHairSystem()) + { + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::eHAIRSYSTEM); + } + else + #endif + { + PX_ASSERT(PxGetFilterObjectType(filterAttr)==PxFilterObjectType::eRIGID_STATIC); + } + } +#endif + return filterAttr; +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: checks that the kill & suppress flags are not both set, disable kill flag if they are. +static PX_INLINE void checkFilterFlags(PxFilterFlags& filterFlags) +{ + if((filterFlags & (PxFilterFlag::eKILL | PxFilterFlag::eSUPPRESS)) == (PxFilterFlag::eKILL | PxFilterFlag::eSUPPRESS)) + { +#if PX_CHECKED + outputError(__LINE__, "Filtering: eKILL and eSUPPRESS must not be set simultaneously. eSUPPRESS will be used."); +#endif + filterFlags.clear(PxFilterFlag::eKILL); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +static PX_INLINE PxPairFlags checkRbPairFlags( const ShapeSimBase& s0, const ShapeSimBase& s1, bool isKinePair, + PxPairFlags pairFlags, PxFilterFlags filterFlags, bool isNonRigid) +{ + if(filterFlags & (PxFilterFlag::eSUPPRESS | PxFilterFlag::eKILL)) + return pairFlags; + + if(isKinePair && (pairFlags & PxPairFlag::eSOLVE_CONTACT)) + { +#if PX_CHECKED + outputError(__LINE__, "Filtering: Resolving contacts between two kinematic objects is invalid. Contacts will not get resolved."); +#endif + pairFlags.clear(PxPairFlag::eSOLVE_CONTACT); + } + + if(isNonRigid && (pairFlags & PxPairFlag::eDETECT_CCD_CONTACT)) + pairFlags.clear(PxPairFlag::eDETECT_CCD_CONTACT); + +#if PX_CHECKED + // we want to avoid to run contact generation for pairs that should not get resolved or have no contact/trigger reports + if (!(PxU32(pairFlags) & (PxPairFlag::eSOLVE_CONTACT | ShapeInteraction::CONTACT_REPORT_EVENTS))) + outputError(__LINE__, "Filtering: Pair with no contact/trigger reports detected, nor is PxPairFlag::eSOLVE_CONTACT set. It is recommended to suppress/kill such pairs for performance reasons."); + else if(!(pairFlags & (PxPairFlag::eDETECT_DISCRETE_CONTACT | PxPairFlag::eDETECT_CCD_CONTACT))) + outputError(__LINE__, "Filtering: Pair did not request either eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT. It is recommended to suppress/kill such pairs for performance reasons."); + + if(((s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)!=0 || (s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)!=0) && + (pairFlags & PxPairFlag::eTRIGGER_DEFAULT) && (pairFlags & PxPairFlag::eDETECT_CCD_CONTACT)) + outputError(__LINE__, "Filtering: CCD isn't supported on Triggers yet"); +#else + PX_UNUSED(s0); + PX_UNUSED(s1); +#endif + return pairFlags; +} + +/////////////////////////////////////////////////////////////////////////////// + +static PX_FORCE_INLINE bool createFilterInfo(FilterInfo& filterInfo, const PxFilterFlags filterFlags) +{ + filterInfo = FilterInfo(filterFlags); + return true; +} + +static void filterRbCollisionPairSecondStage(FilterInfo& filterInfo, const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, bool isKinePair, + const PxFilterObjectAttributes fa0, const PxFilterObjectAttributes fa1, bool runCallbacks, bool isNonRigid) +{ + // Run filter shader + const PxFilterData& fd0 = s0.getCore().getSimulationFilterData(); + const PxFilterData& fd1 = s1.getCore().getSimulationFilterData(); + filterInfo.filterFlags = context.mFilterShader(fa0, fd0, fa1, fd1, filterInfo.pairFlags, context.mFilterShaderData, context.mFilterShaderDataSize); + + if(filterInfo.filterFlags & PxFilterFlag::eCALLBACK) + { + if(context.mFilterCallback) + { + if(!runCallbacks) + { + return; + } + else + { + // If a FilterPair is provided, then we use it, else we create a new one + // (A FilterPair is provided in the case for a pairLost()-pairFound() sequence after refiltering) + + struct Local + { + static PX_FORCE_INLINE PxShape* fetchActorAndShape(const ShapeSimBase& sim, const PxFilterObjectAttributes fa, PxActor*& a) + { + a = sim.getActor().getPxActor(); + +#if PX_SUPPORT_GPU_PHYSX + if(PxGetFilterObjectType(fa)==PxFilterObjectType::ePARTICLESYSTEM) + return NULL; // Particle system does not have a valid shape so set it to null +#endif + PX_UNUSED(fa); + return sim.getPxShape(); + } + }; + + PxActor* a0, *a1; + PxShape* shape0 = Local::fetchActorAndShape(s0, fa0, a0); + PxShape* shape1 = Local::fetchActorAndShape(s1, fa1, a1); + + filterInfo.filterFlags = context.mFilterCallback->pairFound(getPairID(s0, s1), fa0, fd0, a0, shape0, fa1, fd1, a1, shape1, filterInfo.pairFlags); + filterInfo.hasPairID = true; + } + } + else + { + filterInfo.filterFlags.clear(PxFilterFlag::eNOTIFY); + outputError(__LINE__, "Filtering: eCALLBACK set but no filter callback defined."); + } + } + + checkFilterFlags(filterInfo.filterFlags); + + const bool hasNotify = (filterInfo.filterFlags & PxFilterFlag::eNOTIFY) == PxFilterFlag::eNOTIFY; + const bool hasKill = filterInfo.filterFlags & PxFilterFlag::eKILL; + + { + if(filterInfo.hasPairID && (hasKill || !hasNotify)) + { + if(hasKill && hasNotify) + context.mFilterCallback->pairLost(getPairID(s0, s1), fa0, fd0, fa1, fd1, false); + if(!hasNotify) + { + // No notification, hence we don't need to treat it as a filter callback pair anymore. + // Make sure that eCALLBACK gets removed as well + filterInfo.filterFlags.clear(PxFilterFlag::eNOTIFY); + } + + filterInfo.hasPairID = false; + } + } + + // Sanity checks + PX_ASSERT((!hasKill) || (hasKill && (!filterInfo.hasPairID))); + PX_ASSERT((!hasNotify) || (hasNotify && filterInfo.hasPairID)); + + if(runCallbacks || (!(filterInfo.filterFlags & PxFilterFlag::eCALLBACK))) + filterInfo.pairFlags = checkRbPairFlags(s0, s1, isKinePair, filterInfo.pairFlags, filterInfo.filterFlags, isNonRigid); +} + +static bool filterArticulationLinks(const BodySim* bs0, const BodySim* bs1) +{ + //It's the same articulation, so we can filter based on flags... + const ArticulationSim* articulationSim0 = bs0->getArticulation(); + const ArticulationSim* articulationSim1 = bs1->getArticulation(); + if(articulationSim0 == articulationSim1) + { + if(articulationSim0->getCore().getArticulationFlags() & PxArticulationFlag::eDISABLE_SELF_COLLISION) + return true; + + //check to see if one link is the parent of the other link, if so disable collision + const PxU32 linkId0 = bs0->getNodeIndex().articulationLinkId(); + const PxU32 linkId1 = bs1->getNodeIndex().articulationLinkId(); + + if(linkId1 < linkId0) + return articulationSim0->getLink(linkId0).parent == linkId1; + else + return articulationSim1->getLink(linkId1).parent == linkId0; + } + + return false; +} + +static PX_FORCE_INLINE bool filterJointedBodies(const ActorSim& rbActor0, const ActorSim& rbActor1) +{ + // If the bodies of the shape pair are connected by a joint, we need to check whether this connection disables the collision. + // Note: As an optimization, the dynamic bodies have a flag which specifies whether they have any constraints at all. That works + // because a constraint has at least one dynamic body and an interaction is tracked by both objects. + + // PT: the BF_HAS_CONSTRAINTS flag is only raised on dynamic actors in the BodySim class, but it's not raised on static actors. + // Thus the only reliable way to use the flag (without casting to BodySim etc) is when both actors don't have the flag set, in + // which case we're sure we're not dealing with a jointed pair. + if(!rbActor0.readInternalFlag(ActorSim::BF_HAS_CONSTRAINTS) && !rbActor1.readInternalFlag(ActorSim::BF_HAS_CONSTRAINTS)) + return false; + + ConstraintCore* core = rbActor0.getScene().findConstraintCore(&rbActor0, &rbActor1); + return core ? !(core->getFlags() & PxConstraintFlag::eCOLLISION_ENABLED) : false; +} + +static PX_FORCE_INLINE bool hasForceNotifEnabled(const BodySim* bs, PxRigidBodyFlag::Enum flag) +{ + if(!bs) + return false; + + const PxsRigidCore& core = bs->getBodyCore().getCore(); + return core.mFlags.isSet(flag); +} + +static PX_FORCE_INLINE bool validateSuppress(const BodySim* b0, const BodySim* b1, PxRigidBodyFlag::Enum flag) +{ + if(hasForceNotifEnabled(b0, flag)) + return false; + + if(hasForceNotifEnabled(b1, flag)) + return false; + + return true; +} + +static PX_FORCE_INLINE bool filterKinematics(const BodySim* b0, const BodySim* b1, bool kine0, bool kine1, + PxPairFilteringMode::Enum kineKineFilteringMode, PxPairFilteringMode::Enum staticKineFilteringMode) +{ + const bool kinematicPair = kine0 | kine1; + if(kinematicPair) + { + if(staticKineFilteringMode != PxPairFilteringMode::eKEEP) + { + if(!b0 || !b1) + return validateSuppress(b0, b1, PxRigidBodyFlag::eFORCE_STATIC_KINE_NOTIFICATIONS); + } + + if(kineKineFilteringMode != PxPairFilteringMode::eKEEP) + { + if(kine0 && kine1) + return validateSuppress(b0, b1, PxRigidBodyFlag::eFORCE_KINE_KINE_NOTIFICATIONS); + } + } + return false; +} + +template +static bool filterRbCollisionPairShared( FilterInfo& filterInfo, bool& isNonRigid, bool& isKinePair, + const FilteringContext& context, + const ShapeSimBase& s0, const ShapeSimBase& s1, + const PxFilterObjectAttributes filterAttr0, const PxFilterObjectAttributes filterAttr1) +{ + const bool kine0 = PxFilterObjectIsKinematic(filterAttr0); + const bool kine1 = PxFilterObjectIsKinematic(filterAttr1); + + const ActorSim& rbActor0 = s0.getActor(); + const BodySim* bs0 = NULL; + if(filterAttr0 & PxFilterObjectFlagEx::eRIGID_DYNAMIC) + bs0 = static_cast(&rbActor0); + else if(filterAttr0 & PxFilterObjectFlagEx::eNON_RIGID) + isNonRigid = true; + + const ActorSim& rbActor1 = s1.getActor(); + const BodySim* bs1 = NULL; + if(filterAttr1 & PxFilterObjectFlagEx::eRIGID_DYNAMIC) + bs1 = static_cast(&rbActor1); + else if(filterAttr1 & PxFilterObjectFlagEx::eNON_RIGID) + isNonRigid = true; + + if(!isNonRigid && filterKinematics(bs0, bs1, kine0, kine1, context.mKineKineFilteringMode, context.mStaticKineFilteringMode)) + return createFilterInfo(filterInfo, PxFilterFlag::eSUPPRESS); + + if(filterJointedBodies(rbActor0, rbActor1)) + return createFilterInfo(filterInfo, PxFilterFlag::eSUPPRESS); + + const PxFilterObjectType::Enum filterType0 = PxGetFilterObjectType(filterAttr0); + const PxFilterObjectType::Enum filterType1 = PxGetFilterObjectType(filterAttr1); + + // PT: For unknown reasons the filtering code was not the same for triggers/refiltered pairs and for regular "shape sim" pairs + // out of the BP. The tests on "runAllTests" below capture that. I did not change what the code + // was doing, although it might very well be wrong - we might want to run all these tests in both codepaths. + + if(runAllTests) + { +#if PX_SUPPORT_GPU_PHYSX + if(filterType0==PxFilterObjectType::ePARTICLESYSTEM && filterType1==PxFilterObjectType::ePARTICLESYSTEM) + return createFilterInfo(filterInfo, PxFilterFlag::eKILL); + + if(filterType0==PxFilterObjectType::eHAIRSYSTEM && filterType1==PxFilterObjectType::eHAIRSYSTEM ) + return createFilterInfo(filterInfo, PxFilterFlag::eKILL); +#endif + } + + const bool link0 = filterType0==PxFilterObjectType::eARTICULATION; + const bool link1 = filterType1==PxFilterObjectType::eARTICULATION; + + if(runAllTests) + { + if(link0 ^ link1) + { + if(link0) + { + const PxU8 fixedBaseLink = bs0->getLowLevelBody().mCore->fixedBaseLink; + const bool isStaticOrKinematic = (filterType1 == PxFilterObjectType::eRIGID_STATIC) || kine1; + if(fixedBaseLink && isStaticOrKinematic) + return createFilterInfo(filterInfo, PxFilterFlag::eSUPPRESS); + } + + if(link1) + { + const PxU8 fixedBaseLink = bs1->getLowLevelBody().mCore->fixedBaseLink; + const bool isStaticOrKinematic = (filterType0 == PxFilterObjectType::eRIGID_STATIC) || kine0; + if(fixedBaseLink && isStaticOrKinematic) + return createFilterInfo(filterInfo, PxFilterFlag::eSUPPRESS); + } + } + } + + if(link0 && link1) + { + if(runAllTests) + { + const PxU8 fixedBaseLink0 = bs0->getLowLevelBody().mCore->fixedBaseLink; + const PxU8 fixedBaseLink1 = bs1->getLowLevelBody().mCore->fixedBaseLink; + + if(fixedBaseLink0 && fixedBaseLink1) + return createFilterInfo(filterInfo, PxFilterFlag::eSUPPRESS); + } + + if(filterArticulationLinks(bs0, bs1)) + return createFilterInfo(filterInfo, PxFilterFlag::eKILL); + } + isKinePair = kine0 && kine1; + return false; +} + +static void filterRbCollisionPair(FilterInfo& filterInfo, const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, bool& isTriggerPair, bool runCallbacks) +{ + const PxFilterObjectAttributes filterAttr0 = getFilterObjectAttributes(s0); + const PxFilterObjectAttributes filterAttr1 = getFilterObjectAttributes(s1); + + const bool trigger0 = PxFilterObjectIsTrigger(filterAttr0); + const bool trigger1 = PxFilterObjectIsTrigger(filterAttr1); + isTriggerPair = trigger0 || trigger1; + + bool isNonRigid = false; + bool isKinePair = false; + + if(isTriggerPair) + { + if(trigger0 && trigger1) // trigger-trigger pairs are not supported + { + createFilterInfo(filterInfo, PxFilterFlag::eKILL); + return; + } + + // PT: I think we need to do this here to properly handle kinematic triggers. + const bool kine0 = PxFilterObjectIsKinematic(filterAttr0); + const bool kine1 = PxFilterObjectIsKinematic(filterAttr1); + isKinePair = kine0 && kine1; + } + else + { + if(filterRbCollisionPairShared(filterInfo, isNonRigid, isKinePair, context, s0, s1, filterAttr0, filterAttr1)) + return; + } + + filterRbCollisionPairSecondStage(filterInfo, context, s0, s1, isKinePair, filterAttr0, filterAttr1, runCallbacks, isNonRigid); +} + +static PX_FORCE_INLINE void filterRbCollisionPairAllTests(FilterInfo& filterInfo, const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1) +{ + PX_ASSERT(!(s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); + PX_ASSERT(!(s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); + + const PxFilterObjectAttributes filterAttr0 = getFilterObjectAttributes(s0); + const PxFilterObjectAttributes filterAttr1 = getFilterObjectAttributes(s1); + + bool isNonRigid = false; + bool isKinePair = false; + + if(filterRbCollisionPairShared(filterInfo, isNonRigid, isKinePair, context, s0, s1, filterAttr0, filterAttr1)) + return; + + filterRbCollisionPairSecondStage(filterInfo, context, s0, s1, isKinePair, filterAttr0, filterAttr1, true, isNonRigid); +} + +static PX_FORCE_INLINE bool testElementSimPointers(const ElementSim* e0, const ElementSim* e1) +{ + PX_ASSERT(e0); + PX_ASSERT(e1); + + // PT: a bit of defensive coding added for OM-74224. In theory this should not be needed, as the broadphase is not + // supposed to return null pointers here. But there seems to be an issue somewhere, most probably in the GPU BP kernels, + // and this is an attempt at preventing a crash. We could/should remove this eventually. + if(!e0 || !e1) + return outputError(__LINE__, "NPhaseCore::runOverlapFilters: found null elements!"); + return true; +} + +// PT: called from OverlapFilterTask +void NPhaseCore::runOverlapFilters( PxU32 nbToProcess, const Bp::AABBOverlap* PX_RESTRICT pairs, FilterInfo* PX_RESTRICT filterInfo, + PxU32& nbToKeep_, PxU32& nbToSuppress_, PxU32* PX_RESTRICT keepMap +) +{ + PxU32 nbToKeep = 0; + PxU32 nbToSuppress = 0; + + const FilteringContext context(mOwnerScene); + + for(PxU32 i=0; i(pair.mUserData0); + const ElementSim* e1 = reinterpret_cast(pair.mUserData1); + + if(!testElementSimPointers(e0, e1)) + continue; + + PX_ASSERT(!findInteraction(e0, e1)); + + const ShapeSimBase* s0 = static_cast(e0); + const ShapeSimBase* s1 = static_cast(e1); + PX_ASSERT(&s0->getActor() != &s1->getActor()); // No actor internal interactions + + filterInfo[i].filterFlags = PxFilterFlags(0); + filterInfo[i].pairFlags = PxPairFlags(0); + filterInfo[i].hasPairID = false; + filterRbCollisionPairAllTests(filterInfo[i], context, *s0, *s1); + + const PxFilterFlags filterFlags = filterInfo[i].filterFlags; + + if(!(filterFlags & PxFilterFlag::eKILL)) + { + if(!(filterFlags & PxFilterFlag::eSUPPRESS)) + nbToKeep++; + else + nbToSuppress++; + keepMap[i / 32] |= (1 << (i & 31)); + } + } + + nbToKeep_ = nbToKeep; + nbToSuppress_ = nbToSuppress; +} + +ElementSimInteraction* NPhaseCore::createTriggerElementInteraction(ShapeSimBase& s0, ShapeSimBase& s1) +{ + PX_ASSERT((s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE) || (s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); + + const FilteringContext context(mOwnerScene); + + bool isTriggerPair; + FilterInfo filterInfo; + filterRbCollisionPair(filterInfo, context, s0, s1, isTriggerPair, false); + PX_ASSERT(isTriggerPair); + + if(filterInfo.filterFlags & PxFilterFlag::eKILL) + { + PX_ASSERT(!filterInfo.hasPairID); // No filter callback pair info for killed pairs + return NULL; + } + + return createRbElementInteraction(filterInfo, s0, s1, NULL, NULL, NULL, isTriggerPair); +} + +void NPhaseCore::onTriggerOverlapCreated(const Bp::AABBOverlap* PX_RESTRICT pairs, PxU32 pairCount) +{ + for(PxU32 i=0; i(pairs[i].mUserData0); + ElementSim* volume1 = reinterpret_cast(pairs[i].mUserData1); + + if(!testElementSimPointers(volume0, volume1)) + continue; + + PX_ASSERT(!findInteraction(volume0, volume1)); + + ShapeSimBase* shapeHi = static_cast(volume1); + ShapeSimBase* shapeLo = static_cast(volume0); + + // No actor internal interactions + PX_ASSERT(&shapeHi->getActor() != &shapeLo->getActor()); + + // PT: this case is only for triggers these days + PX_ASSERT((shapeLo->getFlags() & PxShapeFlag::eTRIGGER_SHAPE) || (shapeHi->getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); + + createTriggerElementInteraction(*shapeHi, *shapeLo); + } +} + +void NPhaseCore::callPairLost(const ShapeSimBase& s0, const ShapeSimBase& s1, bool objVolumeRemoved) +{ + const PxFilterObjectAttributes fa0 = getFilterObjectAttributes(s0); + const PxFilterObjectAttributes fa1 = getFilterObjectAttributes(s1); + + const PxFilterData& fd0 = s0.getCore().getSimulationFilterData(); + const PxFilterData& fd1 = s1.getCore().getSimulationFilterData(); + + mOwnerScene.getFilterCallbackFast()->pairLost(getPairID(s0, s1), fa0, fd0, fa1, fd1, objVolumeRemoved); +} + +ElementSimInteraction* NPhaseCore::refilterInteraction(ElementSimInteraction* pair, const FilterInfo* filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs) +{ + const InteractionType::Enum oldType = pair->getType(); + + switch (oldType) + { + case InteractionType::eTRIGGER: + case InteractionType::eMARKER: + case InteractionType::eOVERLAP: + { + ShapeSimBase& s0 = static_cast(pair->getElement0()); + ShapeSimBase& s1 = static_cast(pair->getElement1()); + + FilterInfo finfo; + if(filterInfo) + { + // The filter changes are provided by an outside source (the user filter callback) + + finfo = *filterInfo; + PX_ASSERT(finfo.hasPairID); + + if((finfo.filterFlags & PxFilterFlag::eKILL) && + ((finfo.filterFlags & PxFilterFlag::eNOTIFY) == PxFilterFlag::eNOTIFY) ) + { + callPairLost(s0, s1, false); + finfo.hasPairID = false; + } + + ActorSim& bs0 = s0.getActor(); + ActorSim& bs1 = s1.getActor(); + + const bool isKinePair = PxFilterObjectIsKinematic(bs0.getFilterAttributes()) && PxFilterObjectIsKinematic(bs1.getFilterAttributes()); + finfo.pairFlags = checkRbPairFlags(s0, s1, isKinePair, finfo.pairFlags, finfo.filterFlags, s0.getActor().isNonRigid() || s1.getActor().isNonRigid()); + } + else + { + if(pair->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR)) + callPairLost(s0, s1, false); + + const FilteringContext context(mOwnerScene); + + bool isTriggerPair; + filterRbCollisionPair(finfo, context, s0, s1, isTriggerPair, true); + PX_UNUSED(isTriggerPair); + } + + if(pair->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR) && + ((finfo.filterFlags & PxFilterFlag::eNOTIFY) != PxFilterFlag::eNOTIFY) ) + { + // The pair was a filter callback pair but not any longer + pair->clearInteractionFlag(InteractionFlag::eIS_FILTER_PAIR); + + finfo.hasPairID = false; + } + + struct Local + { + static InteractionType::Enum getRbElementInteractionType(const ShapeSimBase* primitive0, const ShapeSimBase* primitive1, PxFilterFlags filterFlag) + { + if(filterFlag & PxFilterFlag::eKILL) + return InteractionType::eINVALID; + + if(filterFlag & PxFilterFlag::eSUPPRESS) + return InteractionType::eMARKER; + + if(primitive0->getFlags() & PxShapeFlag::eTRIGGER_SHAPE + || primitive1->getFlags() & PxShapeFlag::eTRIGGER_SHAPE) + return InteractionType::eTRIGGER; + + PX_ASSERT( (primitive0->getGeometryType() != PxGeometryType::eTRIANGLEMESH) || + (primitive1->getGeometryType() != PxGeometryType::eTRIANGLEMESH)); + + return InteractionType::eOVERLAP; + } + }; + + const InteractionType::Enum newType = Local::getRbElementInteractionType(&s0, &s1, finfo.filterFlags); + if(pair->getType() != newType) //Only convert interaction type if the type has changed + { + return convert(pair, newType, finfo, removeFromDirtyList, outputs); + } + else + { + //The pair flags might have changed, we need to forward the new ones + if(oldType == InteractionType::eOVERLAP) + { + ShapeInteraction* si = static_cast(pair); + + const PxU32 newPairFlags = finfo.pairFlags; + const PxU32 oldPairFlags = si->getPairFlags(); + PX_ASSERT((newPairFlags & ShapeInteraction::PAIR_FLAGS_MASK) == newPairFlags); + PX_ASSERT((oldPairFlags & ShapeInteraction::PAIR_FLAGS_MASK) == oldPairFlags); + + if(newPairFlags != oldPairFlags) + { + if(!(oldPairFlags & ShapeInteraction::CONTACT_REPORT_EVENTS) && (newPairFlags & ShapeInteraction::CONTACT_REPORT_EVENTS) && (si->getActorPair() == NULL || !si->getActorPair()->isReportPair())) + { + // for this actor pair there was no shape pair that requested contact reports but now there is one + // -> all the existing shape pairs need to get re-adjusted to point to an ActorPairReport instance instead. + ActorPair* actorPair = findActorPair(&s0, &s1, PxIntTrue); + if (si->getActorPair() == NULL) + { + actorPair->incRefCount(); + si->setActorPair(*actorPair); + } + } + + if(si->readFlag(ShapeInteraction::IN_PERSISTENT_EVENT_LIST) && (!(newPairFlags & PxPairFlag::eNOTIFY_TOUCH_PERSISTS))) + { + // the new report pair flags don't require persistent checks anymore -> remove from persistent list + // Note: The pair might get added to the force threshold list later + if(si->readFlag(ShapeInteraction::IS_IN_PERSISTENT_EVENT_LIST)) + removeFromPersistentContactEventPairs(si); + else + si->clearFlag(ShapeInteraction::WAS_IN_PERSISTENT_EVENT_LIST); + } + + if(newPairFlags & ShapeInteraction::CONTACT_FORCE_THRESHOLD_PAIRS) + { + PX_ASSERT((si->mReportPairIndex == INVALID_REPORT_PAIR_ID) || (!si->readFlag(ShapeInteraction::WAS_IN_PERSISTENT_EVENT_LIST))); + + if(si->mReportPairIndex == INVALID_REPORT_PAIR_ID && si->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) + { + PX_ASSERT(!si->readFlag(ShapeInteraction::WAS_IN_PERSISTENT_EVENT_LIST)); // sanity check: an active pair should never have this flag set + + if(si->hasTouch()) + addToForceThresholdContactEventPairs(si); + } + } + else if((oldPairFlags & ShapeInteraction::CONTACT_FORCE_THRESHOLD_PAIRS)) + { + // no force threshold events needed any longer -> clear flags + si->clearFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_FLAGS); + + if(si->readFlag(ShapeInteraction::IS_IN_FORCE_THRESHOLD_EVENT_LIST)) + removeFromForceThresholdContactEventPairs(si); + } + } + si->setPairFlags(finfo.pairFlags); + } + else if(oldType == InteractionType::eTRIGGER) + static_cast(pair)->setTriggerFlags(finfo.pairFlags); + + return pair; + } + } + case InteractionType::eCONSTRAINTSHADER: + case InteractionType::eARTICULATION: + case InteractionType::eTRACKED_IN_SCENE_COUNT: + case InteractionType::eINVALID: + PX_ASSERT(0); + break; + } + return NULL; +} + +void NPhaseCore::fireCustomFilteringCallbacks(PxsContactManagerOutputIterator& outputs) +{ + PX_PROFILE_ZONE("Sim.fireCustomFilteringCallbacks", mOwnerScene.getContextId()); + + PxSimulationFilterCallback* callback = mOwnerScene.getFilterCallbackFast(); + + if(callback) + { + // Ask user for pair filter status changes + PxU64 pairID; + PxFilterFlags filterFlags; + PxPairFlags pairFlags; + while(callback->statusChange(pairID, pairFlags, filterFlags)) + { + const PxU32 id0 = PxU32(pairID); + const PxU32 id1 = PxU32(pairID>>32); + const PxHashMap::Entry* pair = mElementSimMap.find(ElementSimKey(id0, id1)); + ElementSimInteraction* ei = pair ? pair->second : NULL; + PX_ASSERT(ei); + // Check if the user tries to update a pair even though he deleted it earlier in the same frame + + checkFilterFlags(filterFlags); + + PX_ASSERT(ei->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR)); + + FilterInfo finfo; + finfo.filterFlags = filterFlags; + finfo.pairFlags = pairFlags; + finfo.hasPairID = true; + ElementSimInteraction* refInt = refilterInteraction(ei, &finfo, true, outputs); + + // this gets called at the end of the simulation -> there should be no dirty interactions around + PX_ASSERT(!refInt->readInteractionFlag(InteractionFlag::eIN_DIRTY_LIST)); + PX_ASSERT(!refInt->getDirtyFlags()); + + if((refInt == ei) && (refInt->getType() == InteractionType::eOVERLAP)) // No interaction conversion happened, the pairFlags were just updated + static_cast(refInt)->updateState(InteractionDirtyFlag::eFILTER_STATE); + } + } +} + diff --git a/physx/source/geomutils/src/intersection/GuIntersectionRayBoxSIMD.h b/physx/source/simulationcontroller/src/ScFiltering.h similarity index 78% rename from physx/source/geomutils/src/intersection/GuIntersectionRayBoxSIMD.h rename to physx/source/simulationcontroller/src/ScFiltering.h index 7e157815d..54ec51ddd 100644 --- a/physx/source/geomutils/src/intersection/GuIntersectionRayBoxSIMD.h +++ b/physx/source/simulationcontroller/src/ScFiltering.h @@ -26,23 +26,25 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef GU_INTERSECTION_RAY_BOX_SIMD_H -#define GU_INTERSECTION_RAY_BOX_SIMD_H +#ifndef SC_FILTERING_H +#define SC_FILTERING_H -#include "foundation/PxMathIntrinsics.h" -#include "common/PxPhysXCommonConfig.h" -#include "foundation/PxVecMath.h" +#include "PxFiltering.h" namespace physx { -namespace Gu +namespace Sc { - bool PX_PHYSX_COMMON_API intersectRayAABB2( const aos::Vec3VArg minimum, const aos::Vec3VArg maximum, - const aos::Vec3VArg ro, const aos::Vec3VArg rd, const aos::FloatVArg maxDist, - aos::FloatV& tnear, aos::FloatV& tfar); - -} // namespace Gu + struct FilterInfo + { + PX_FORCE_INLINE FilterInfo() : filterFlags(0), pairFlags(0), hasPairID(false) {} + PX_FORCE_INLINE FilterInfo(PxFilterFlags filterFlags_) : filterFlags(filterFlags_), pairFlags(0), hasPairID(false) {} + PxFilterFlags filterFlags; + PxPairFlags pairFlags; + bool hasPairID; + }; +} } #endif diff --git a/physx/source/simulationcontroller/src/ScHairSystemCore.cpp b/physx/source/simulationcontroller/src/ScHairSystemCore.cpp index 6217b1ac9..8d80c61f8 100644 --- a/physx/source/simulationcontroller/src/ScHairSystemCore.cpp +++ b/physx/source/simulationcontroller/src/ScHairSystemCore.cpp @@ -29,126 +29,130 @@ #if PX_SUPPORT_GPU_PHYSX #include "ScHairSystemCore.h" + #include "ScHairSystemSim.h" #include "ScPhysics.h" -#include "DyHairSystem.h" namespace physx { - namespace Sc +namespace Sc +{ + +HairSystemCore::HairSystemCore() +: ActorCore(PxActorType::eHAIRSYSTEM, PxActorFlag::eVISUALIZATION, PX_DEFAULT_CLIENT, 0) +{ +} + +HairSystemCore::~HairSystemCore() {} + +void HairSystemCore::setMaterial(const PxU16 handle) { mShapeCore.getLLCore().setMaterial(handle); } + +void HairSystemCore::clearMaterials() { mShapeCore.getLLCore().clearMaterials(); } + +void HairSystemCore::setSleepThreshold(const PxReal v) +{ + mShapeCore.getLLCore().mSleepThreshold = v; + mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; +} + +void HairSystemCore::setSolverIterationCounts(const PxU16 c) +{ + mShapeCore.getLLCore().mSolverIterationCounts = c; + mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; +} + +void HairSystemCore::setWakeCounter(const PxReal v) +{ + mShapeCore.getLLCore().mWakeCounter = v; + mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; + + HairSystemSim* sim = getSim(); + if(sim) + { + sim->onSetWakeCounter(); + } +} + +bool HairSystemCore::isSleeping() const +{ + HairSystemSim* sim = getSim(); + return sim ? sim->isSleeping() : (mShapeCore.getLLCore().mWakeCounter == 0.0f); +} + +void HairSystemCore::wakeUp(PxReal wakeCounter) +{ + mShapeCore.getLLCore().mWakeCounter = wakeCounter; + mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; +} + +void HairSystemCore::putToSleep() +{ + mShapeCore.getLLCore().mWakeCounter = 0.0f; + mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; +} + +PxActor* HairSystemCore::getPxActor() const +{ + return PxPointerOffset(const_cast(this), gOffsetTable.scCore2PxActor[getActorCoreType()]); +} + +HairSystemSim* HairSystemCore::getSim() const { return static_cast(ActorCore::getSim()); } + +PxReal HairSystemCore::getContactOffset() const { return mShapeCore.getContactOffset(); } + +void HairSystemCore::setContactOffset(PxReal v) +{ + mShapeCore.setContactOffset(v); + HairSystemSim* sim = getSim(); + if(sim) { - HairSystemCore::HairSystemCore() : - ActorCore(PxActorType::eHAIRSYSTEM, PxActorFlag::eVISUALIZATION, PX_DEFAULT_CLIENT, 0) - { - } - - HairSystemCore::~HairSystemCore() - { - } - - void HairSystemCore::setMaterial(const PxU16 handle) - { - mShapeCore.getLLCore().setMaterial(handle); - } - - void HairSystemCore::clearMaterials() - { - mShapeCore.getLLCore().clearMaterials(); - } - - void HairSystemCore::setSleepThreshold(const PxReal v) - { - mShapeCore.getLLCore().mSleepThreshold = v; - mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; - } - - void HairSystemCore::setSolverIterationCounts(const PxU16 c) - { - mShapeCore.getLLCore().mSolverIterationCounts = c; - mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; - } - - void HairSystemCore::setWakeCounter(const PxReal v) - { - mShapeCore.getLLCore().mWakeCounter = v; - mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; - - HairSystemSim* sim = getSim(); - if (sim) - { - sim->onSetWakeCounter(); - } - } - - bool HairSystemCore::isSleeping() const - { - HairSystemSim* sim = getSim(); - return sim ? sim->isSleeping() : (mShapeCore.getLLCore().mWakeCounter == 0.0f); - } - - void HairSystemCore::wakeUp(PxReal wakeCounter) - { - mShapeCore.getLLCore().mWakeCounter = wakeCounter; - mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; - } - - void HairSystemCore::putToSleep() - { - mShapeCore.getLLCore().mWakeCounter = 0.0f; - mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; - } - - PxActor* HairSystemCore::getPxActor() const - { - return PxPointerOffset(const_cast(this), gOffsetTable.scCore2PxActor[getActorCoreType()]); - } - - HairSystemSim* HairSystemCore::getSim() const - { - return static_cast(ActorCore::getSim()); - } - - PxReal Sc::HairSystemCore::getContactOffset() const - { - return mShapeCore.getContactOffset(); - } - - void Sc::HairSystemCore::setContactOffset(PxReal v) - { - mShapeCore.setContactOffset(v); - Sc::HairSystemSim* sim = getSim(); - if (sim) - { - sim->getScene().updateContactDistance(sim->getShapeSim().getElementID(), v); - } - } - - void Sc::HairSystemCore::addRigidAttachment(const Sc::BodyCore* core) - { - const Sc::HairSystemSim* sim = getSim(); - if (sim) - { - sim->getScene().addRigidAttachment(core, *sim); - } - } - - void Sc::HairSystemCore::removeRigidAttachment(const Sc::BodyCore* core) - { - const Sc::HairSystemSim* sim = getSim(); - if (sim) - { - sim->getScene().removeRigidAttachment(core, *sim); - } - } - - void Sc::HairSystemCore::setFlags(PxHairSystemFlags flags) - { - mShapeCore.getLLCore().mParams.mFlags = flags; - mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; - } - - - } // namespace Sc + sim->getScene().updateContactDistance(sim->getShapeSim().getElementID(), v); + } +} + +void HairSystemCore::addAttachment(const BodySim& bodySim) +{ + const HairSystemSim* sim = getSim(); + if(sim) + { + sim->getScene().addAttachment(bodySim, *sim); + } +} + +void HairSystemCore::removeAttachment(const BodySim& bodySim) +{ + const HairSystemSim* sim = getSim(); + if(sim) + { + sim->getScene().removeAttachment(bodySim, *sim); + } +} + +void HairSystemCore::addAttachment(const SoftBodySim& sbSim) +{ + const Sc::HairSystemSim* sim = getSim(); + if(sim) + { + sim->getScene().addAttachment(sbSim, *sim); + } +} + +void HairSystemCore::removeAttachment(const SoftBodySim& sbSim) +{ + const Sc::HairSystemSim* sim = getSim(); + if(sim) + { + sim->getScene().removeAttachment(sbSim, *sim); + } +} + +void Sc::HairSystemCore::setFlags(PxHairSystemFlags flags) +{ + mShapeCore.getLLCore().mParams.mFlags = flags; + mShapeCore.getLLCore().mDirtyFlags |= Dy::HairSystemDirtyFlag::ePARAMETERS; +} + +} // namespace Sc } // namespace physx -#endif //PX_SUPPORT_GPU_PHYSX +#endif // PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/simulationcontroller/src/ScHairSystemShapeCore.cpp b/physx/source/simulationcontroller/src/ScHairSystemShapeCore.cpp index 9457dc50b..97ed0a7b3 100644 --- a/physx/source/simulationcontroller/src/ScHairSystemShapeCore.cpp +++ b/physx/source/simulationcontroller/src/ScHairSystemShapeCore.cpp @@ -24,7 +24,6 @@ // // Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. - #include "foundation/PxPreprocessor.h" #if PX_SUPPORT_GPU_PHYSX @@ -44,76 +43,25 @@ namespace physx namespace Sc { - HairSystemShapeCore::HairSystemShapeCore() - : ShapeCore(PxEmpty) - , mGpuMemStat(0) - { - mSimulationFilterData = PxFilterData(); - - mCore = PxsShapeCore(); - - const PxTolerancesScale& scale = Physics::getInstance().getTolerancesScale(); - mCore.setTransform(PxTransform(PxIdentity)); - mCore.mContactOffset = 0.0f; - mCore.mShapeFlags = 0; - - mCore.mMinTorsionalPatchRadius = 0.f; - mCore.mTorsionalRadius = 0.f; - - mLLCore.mSleepThreshold = 5e-5f * scale.speed * scale.speed; - mLLCore.mWakeCounter = Physics::sWakeCounterOnCreation; - mLLCore.mSolverIterationCounts = 8; - mLLCore.mDirtyFlags = PX_MAX_U32; - mLLCore.mParams.mFlags = PxHairSystemFlags(0); - - // parameters - mLLCore.mParams.mShapeCompliance = PxVec2(-1.0f); - - mLLCore.mNumVertices = 0; - mLLCore.mNumStrands = 0; - - // must be powers of two - mLLCore.mParams.mGridSize[0] = 32; - mLLCore.mParams.mGridSize[1] = 64; - mLLCore.mParams.mGridSize[2] = 32; - - mLLCore.mParams.mSegmentLength = 0.1f; - mLLCore.mParams.mSegmentRadius = 0.02f; - - mLLCore.mParams.mInterHairRepulsion = 0.0f; - mLLCore.mParams.mInterHairVelocityDamping = 0.03f; - mLLCore.mParams.mFrictionCoeff = 0.0f; - mLLCore.mParams.mBendingCompliance = -1.0f; - mLLCore.mParams.mTwistingCompliance = -1.0f; - mLLCore.mParams.mSelfCollisionContactDist = 1.5f; - mLLCore.mParams.mSelfCollisionRelaxation = 0.7f; - mLLCore.mParams.mLraRelaxation = 1.0f; - mLLCore.mParams.mShapeMatchingCompliance = -1.0f; - mLLCore.mParams.mShapeMatchingBeta = 0.0f; - mLLCore.mParams.mShapeMatchingNumVertsPerGroup = 10; - mLLCore.mParams.mShapeMatchingNumVertsOverlap = 5; - - mLLCore.mBendingRestAngles = NULL; - - mLLCore.mWind = PxVec4(0.0f); - - mLLCore.mPositionInvMass = NULL; - mLLCore.mVelocity = NULL; - - mLLCore.mStrandPastEndIndicesGpuSim = NULL; - mLLCore.mPositionInvMassGpuSim = NULL; - mLLCore.mTwistingRestPositionsGpuSim = NULL; - mLLCore.mRestPositions = NULL; - mLLCore.mRestPositionsTransform = NULL; - mLLCore.mRestPositionBodyNodeIdx = PxNodeIndex().getInd(); - - mLLCore.mRigidAttachments = NULL; - mLLCore.mNumRigidAttachments = 0; - - mLLCore.mLodLevel = 0; - mLLCore.mLodNumLevels = 0; - mLLCore.mLodProportionOfStrands = NULL; - mLLCore.mLodProportionOfVertices = NULL; +HairSystemShapeCore::HairSystemShapeCore() + : ShapeCore(PxEmpty) + , mGpuMemStat(0) +{ + mSimulationFilterData = PxFilterData(); + + mCore = PxsShapeCore(); + + const PxTolerancesScale& scale = Physics::getInstance().getTolerancesScale(); + mCore.setTransform(PxTransform(PxIdentity)); + mCore.mContactOffset = 0.0f; + mCore.mRestOffset = 0.0f; + mCore.mShapeFlags = 0; + + mCore.mMinTorsionalPatchRadius = 0.f; + mCore.mTorsionalRadius = 0.f; + + mLLCore.mSleepThreshold = 5e-5f * scale.speed * scale.speed; + mLLCore.mWakeCounter = Physics::sWakeCounterOnCreation; } // PX_SERIALIZATION diff --git a/physx/source/simulationcontroller/src/ScHairSystemShapeCore.h b/physx/source/simulationcontroller/src/ScHairSystemShapeCore.h index 02e70418b..7f9b143b2 100644 --- a/physx/source/simulationcontroller/src/ScHairSystemShapeCore.h +++ b/physx/source/simulationcontroller/src/ScHairSystemShapeCore.h @@ -27,6 +27,8 @@ #ifndef SC_HAIRSYSTEM_SHAPECORE_H #define SC_HAIRSYSTEM_SHAPECORE_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "foundation/PxUserAllocated.h" #include "DyHairSystemCore.h" #include "ScShapeCore.h" @@ -38,15 +40,8 @@ namespace physx namespace Sc { - class HairSystemShapeCore : public Sc::ShapeCore { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION HairSystemShapeCore(const PxEMPTY); @@ -71,5 +66,6 @@ namespace physx } // namespace Sc } // namespace physx +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScHairSystemShapeSim.h b/physx/source/simulationcontroller/src/ScHairSystemShapeSim.h index 9577ba237..4b33b2b10 100644 --- a/physx/source/simulationcontroller/src/ScHairSystemShapeSim.h +++ b/physx/source/simulationcontroller/src/ScHairSystemShapeSim.h @@ -27,11 +27,12 @@ #ifndef SC_HAIRSYSTEM_SHAPE_SIM_H #define SC_HAIRSYSTEM_SHAPE_SIM_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxPhysXConfig.h" #include "ScElementSim.h" #include "ScShapeSimBase.h" - namespace physx { namespace Sc @@ -66,8 +67,8 @@ namespace physx }; } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScHairSystemSim.cpp b/physx/source/simulationcontroller/src/ScHairSystemSim.cpp index 7625405ea..97643bff2 100644 --- a/physx/source/simulationcontroller/src/ScHairSystemSim.cpp +++ b/physx/source/simulationcontroller/src/ScHairSystemSim.cpp @@ -40,8 +40,7 @@ using namespace physx::Dy; Sc::HairSystemSim::HairSystemSim(HairSystemCore& core, Scene& scene) : ActorSim(scene, core), - mShapeSim(*this, &core.getShapeCore()), - mNumCountedInteractions(0) + mShapeSim(*this, &core.getShapeCore()) { mLLHairSystem = scene.createLLHairSystem(this); @@ -89,18 +88,6 @@ bool Sc::HairSystemSim::isSleeping() const return sim.getActiveNodeIndex(mNodeIndex) == PX_INVALID_NODE; } -void Sc::HairSystemSim::setActive(const bool b, const PxU32 /*infoFlag*/) -{ - if (b) - { - getScene().getSimulationController()->activateHairSystem(mLLHairSystem); - } - else - { - getScene().getSimulationController()->deactivateHairSystem(mLLHairSystem); - } -} - void Sc::HairSystemSim::onSetWakeCounter() { getScene().getSimulationController()->setHairSystemWakeCounter(mLLHairSystem); @@ -113,7 +100,7 @@ void Sc::HairSystemSim::onSetWakeCounter() } } -void Sc::HairSystemSim::activate() +/*void Sc::HairSystemSim::activate() { activateInteractions(*this); } @@ -121,6 +108,6 @@ void Sc::HairSystemSim::activate() void Sc::HairSystemSim::deactivate() { deactivateInteractions(*this); -} +}*/ #endif //PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/simulationcontroller/src/ScHairSystemSim.h b/physx/source/simulationcontroller/src/ScHairSystemSim.h index 98301fb2e..a4e55078b 100644 --- a/physx/source/simulationcontroller/src/ScHairSystemSim.h +++ b/physx/source/simulationcontroller/src/ScHairSystemSim.h @@ -27,6 +27,8 @@ #ifndef SC_HAIR_SYSTEM_SIM_H #define SC_HAIR_SYSTEM_SIM_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "DyHairSystem.h" #include "ScHairSystemCore.h" #include "ScHairSystemShapeSim.h" @@ -40,6 +42,7 @@ namespace physx class HairSystemSim : public ActorSim { + PX_NOCOPY(HairSystemSim) public: HairSystemSim(HairSystemCore& core, Scene& scene); ~HairSystemSim(); @@ -56,29 +59,23 @@ namespace physx bool isSleeping() const; bool isActive() const { return !isSleeping(); } - void setActive(const bool b, const PxU32 infoFlag = 0); + void setActive(bool active, bool asPartOfCreation=false); void onSetWakeCounter(); - virtual void registerCountedInteraction() { mNumCountedInteractions++; } - virtual void unregisterCountedInteraction() { mNumCountedInteractions--; } - virtual PxU32 getNumCountedInteractions() const { return mNumCountedInteractions; } - - virtual void activate(); - virtual void deactivate(); - HairSystemShapeSim& getShapeSim() { return mShapeSim; } private: - //HairSystemSim& operator=(const HairSystemSim&); - Dy::HairSystem* mLLHairSystem; HairSystemShapeSim mShapeSim; - PxU32 mNumCountedInteractions; +// PT: as far as I can tell these are never actually called +// void activate(); +// void deactivate(); }; } // namespace Sc } // namespace physx +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScInteraction.h b/physx/source/simulationcontroller/src/ScInteraction.h index 27a3165b9..671d320ec 100644 --- a/physx/source/simulationcontroller/src/ScInteraction.h +++ b/physx/source/simulationcontroller/src/ScInteraction.h @@ -31,7 +31,6 @@ #include "foundation/Px.h" #include "ScInteractionFlags.h" -#include "ScScene.h" #include "ScActorSim.h" #include "foundation/PxUserAllocated.h" #include "foundation/PxUtilities.h" @@ -43,19 +42,34 @@ namespace physx namespace Sc { + struct InteractionType + { + enum Enum + { + eOVERLAP = 0, // corresponds to ShapeInteraction + eTRIGGER, // corresponds to TriggerInteraction + eMARKER, // corresponds to ElementInteractionMarker + eTRACKED_IN_SCENE_COUNT, // not a real type, interactions above this limit are tracked in the scene + eCONSTRAINTSHADER, // corresponds to ConstraintInteraction + eARTICULATION, // corresponds to ArticulationJointSim + + eINVALID + }; + }; + // Interactions are used for connecting actors into activation groups. An interaction always connects exactly two actors. // An interaction is implicitly active if at least one of the two actors it connects is active. + // PT: we need PxUserAllocated only for ArticulationJointSim, which for some reason doesn't follow the same design as the others. + // The others are allocated from pools in NphaseCore. class Interaction : public PxUserAllocated { PX_NOCOPY(Interaction) - - protected: Interaction(ActorSim& actor0, ActorSim& actor1, InteractionType::Enum interactionType, PxU8 flags); ~Interaction() { PX_ASSERT(!readInteractionFlag(InteractionFlag::eIN_DIRTY_LIST)); } public: // Interactions automatically register themselves in the actors here - PX_FORCE_INLINE bool registerInActors(void* data = NULL); + PX_FORCE_INLINE void registerInActors(); // Interactions automatically unregister themselves from the actors here PX_FORCE_INLINE void unregisterFromActors(); @@ -89,14 +103,6 @@ namespace Sc PX_FORCE_INLINE PxIntBool isElementInteraction() const; - // Called when an interaction is activated or created. - // Return true if activation should proceed else return false (for example: joint interaction between two kinematics should not get activated) -// virtual bool onActivate_(void* data) = 0; - - // Called when an interaction is deactivated. - // Return true if deactivation should proceed else return false (for example: joint interaction between two kinematics can ignore deactivation because it always is deactivated) -// virtual bool onDeactivate_() = 0; - PX_FORCE_INLINE void setInteractionId(PxU32 id) { mSceneId = id; } PX_FORCE_INLINE PxU32 getInteractionId() const { return mSceneId; } PX_FORCE_INLINE bool isRegistered() const { return mSceneId != PX_INVALID_INTERACTION_SCENE_ID; } @@ -131,14 +137,10 @@ namespace Sc ////////////////////////////////////////////////////////////////////////// -PX_FORCE_INLINE bool Sc::Interaction::registerInActors(void* data) +PX_FORCE_INLINE void Sc::Interaction::registerInActors() { - bool active = activateInteraction(this, data); - mActor0.registerInteractionInActor(this); mActor1.registerInteractionInActor(this); - - return active; } PX_FORCE_INLINE void Sc::Interaction::unregisterFromActors() @@ -201,7 +203,6 @@ PX_FORCE_INLINE void Sc::Interaction::setDirty(PxU32 dirtyFlags) // mDirtyFlags = 0; //} - } #endif diff --git a/physx/source/simulationcontroller/src/ScKinematics.cpp b/physx/source/simulationcontroller/src/ScKinematics.cpp new file mode 100644 index 000000000..70d8e40df --- /dev/null +++ b/physx/source/simulationcontroller/src/ScKinematics.cpp @@ -0,0 +1,470 @@ +// 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. + +#include "common/PxProfileZone.h" +#include "ScScene.h" +#include "ScBodySim.h" +#include "ScShapeSim.h" +#include "PxsSimulationController.h" +#include "BpAABBManagerBase.h" + +using namespace physx; +using namespace Sc; + +//PX_IMPLEMENT_OUTPUT_ERROR + +/////////////////////////////////////////////////////////////////////////////// + +// PT: TODO: consider using a non-member function for this one +void BodySim::calculateKinematicVelocity(PxReal oneOverDt) +{ + PX_ASSERT(isKinematic()); + + /*------------------------------------------------\ + | kinematic bodies are moved directly by the user and are not influenced by external forces + | we simply determine the distance moved since the last simulation frame and + | assign the appropriate delta to the velocity. This vel will be used to shove dynamic + | objects in the solver. + | We have to do this like so in a delayed way, because when the user sets the target pos the dt is not + | yet known. + \------------------------------------------------*/ + PX_ASSERT(isActive()); + + BodyCore& core = getBodyCore(); + + if (readInternalFlag(BF_KINEMATIC_MOVED)) + { + clearInternalFlag(InternalFlags(BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2)); + const SimStateData* kData = getSimStateData(true); + PX_ASSERT(kData); + PX_ASSERT(kData->isKine()); + PX_ASSERT(kData->getKinematicData()->targetValid); + PxVec3 linVelLL, angVelLL; + const PxTransform targetPose = kData->getKinematicData()->targetPose; + const PxTransform& currBody2World = getBody2World(); + + //the kinematic target pose is now the target of the body (CoM) and not the actor. + + PxVec3 deltaPos = targetPose.p; + deltaPos -= currBody2World.p; + linVelLL = deltaPos * oneOverDt; + + PxQuat q = targetPose.q * currBody2World.q.getConjugate(); + + if (q.w < 0) //shortest angle. + q = -q; + + PxReal angle; + PxVec3 axis; + q.toRadiansAndUnitAxis(angle, axis); + angVelLL = axis * angle * oneOverDt; + + core.getCore().linearVelocity = linVelLL; + core.getCore().angularVelocity = angVelLL; + + // Moving a kinematic should trigger a wakeUp call on a higher level. + PX_ASSERT(core.getWakeCounter()>0); + PX_ASSERT(isActive()); + + } + else if (!readInternalFlag(BF_KINEMATIC_SURFACE_VELOCITY)) + { + core.setLinearVelocity(PxVec3(0.0f), true); + core.setAngularVelocity(PxVec3(0.0f), true); + } +} + +namespace +{ +class ScKinematicUpdateTask : public Cm::Task +{ + Sc::BodyCore*const* mKinematics; + const PxU32 mNbKinematics; + const PxReal mOneOverDt; + + PX_NOCOPY(ScKinematicUpdateTask) +public: + + static const PxU32 NbKinematicsPerTask = 1024; + + ScKinematicUpdateTask(Sc::BodyCore*const* kinematics, PxU32 nbKinematics, PxReal oneOverDt, PxU64 contextID) : + Cm::Task(contextID), mKinematics(kinematics), mNbKinematics(nbKinematics), mOneOverDt(oneOverDt) + { + } + + virtual void runInternal() + { + Sc::BodyCore*const* kinematics = mKinematics; + PxU32 nb = mNbKinematics; + const float oneOverDt = mOneOverDt; + + while(nb--) + { + Sc::BodyCore* b = *kinematics++; + PX_ASSERT(b->getSim()->isKinematic()); + PX_ASSERT(b->getSim()->isActive()); + + b->getSim()->calculateKinematicVelocity(oneOverDt); + } + } + + virtual const char* getName() const + { + return "ScScene.KinematicUpdateTask"; + } +}; +} + +void Sc::Scene::kinematicsSetup(PxBaseTask* continuation) +{ + const PxU32 nbKinematics = getActiveKinematicBodiesCount(); + if(!nbKinematics) + return; + + BodyCore*const* kinematics = getActiveKinematicBodies(); + + // PT: create a copy of active bodies for the taks to operate on while the main array is + // potentially resized by operations running in parallel. + if(mActiveKinematicsCopyCapacitygetTaskPool(); + + // PT: TASK-CREATION TAG + // PT: TODO: better load balancing? This will be single threaded for less than 1K kinematics + for(PxU32 i = 0; i < nbKinematics; i += ScKinematicUpdateTask::NbKinematicsPerTask) + { + ScKinematicUpdateTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScKinematicUpdateTask)), ScKinematicUpdateTask) + (kinematics + i, PxMin(ScKinematicUpdateTask::NbKinematicsPerTask, nbKinematics - i), mOneOverDt, mContextId); + + task->setContinuation(continuation); + task->removeReference(); + } + + if((mPublicFlags & PxSceneFlag::eENABLE_GPU_DYNAMICS)) + { + // PT: running this serially for now because it's unsafe: mNPhaseCore->updateDirtyInteractions() (called after this) + // can also call mSimulationController.updateDynamic() via BodySim::internalWakeUpBase + PxU32 nb = nbKinematics; + while(nb--) + { + Sc::BodyCore* b = *kinematics++; + Sc::BodySim* bodySim = b->getSim(); + PX_ASSERT(!bodySim->getArticulation()); + mSimulationController->updateDynamic(NULL, bodySim->getNodeIndex()); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: TODO: consider using a non-member function for this one +void BodySim::updateKinematicPose() +{ + /*------------------------------------------------\ + | kinematic bodies are moved directly by the user and are not influenced by external forces + | we simply determine the distance moved since the last simulation frame and + | assign the appropriate delta to the velocity. This vel will be used to shove dynamic + | objects in the solver. + | We have to do this like so in a delayed way, because when the user sets the target pos the dt is not + | yet known. + \------------------------------------------------*/ + + PX_ASSERT(isKinematic()); + PX_ASSERT(isActive()); + + if(readInternalFlag(BF_KINEMATIC_MOVED)) + { + clearInternalFlag(InternalFlags(BF_KINEMATIC_SETTLING | BF_KINEMATIC_SETTLING_2)); + const SimStateData* kData = getSimStateData(true); + PX_ASSERT(kData); + PX_ASSERT(kData->isKine()); + PX_ASSERT(kData->getKinematicData()->targetValid); + + const PxTransform targetPose = kData->getKinematicData()->targetPose; + getBodyCore().getCore().body2World = targetPose; + } +} + +namespace +{ +class ScKinematicPoseUpdateTask : public Cm::Task +{ + Sc::BodyCore*const* mKinematics; + const PxU32 mNbKinematics; + + PX_NOCOPY(ScKinematicPoseUpdateTask) +public: + static const PxU32 NbKinematicsPerTask = 1024; + + ScKinematicPoseUpdateTask(Sc::BodyCore*const* kinematics, PxU32 nbKinematics, PxU64 contextID) : + Cm::Task(contextID), mKinematics(kinematics), mNbKinematics(nbKinematics) + { + } + + virtual void runInternal() + { + const PxU32 nb = mNbKinematics; + + for(PxU32 a=0; a(mKinematics[a + 16])); + + if ((a + 4) < nb) + { + PxPrefetchLine(static_cast(mKinematics[a + 4])->getSim()); + PxPrefetchLine(static_cast(mKinematics[a + 4])->getSim()->getSimStateData_Unchecked()); + } + } + Sc::BodyCore* b = static_cast(mKinematics[a]); + PX_ASSERT(b->getSim()->isKinematic()); + PX_ASSERT(b->getSim()->isActive()); + b->getSim()->updateKinematicPose(); + } + } + + virtual const char* getName() const + { + return "ScScene.ScKinematicPoseUpdateTask"; + } +}; +} + +void Sc::Scene::integrateKinematicPose() +{ + PX_PROFILE_ZONE("Sim.integrateKinematicPose", mContextId); + + const PxU32 nbKinematics = getActiveKinematicBodiesCount(); + BodyCore*const* kinematics = getActiveKinematicBodies(); + + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + // PT: TASK-CREATION TAG + for(PxU32 i=0; isetContinuation(&mAfterIntegration); + task->removeReference(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +namespace +{ +class ScKinematicShapeUpdateTask : public Cm::Task +{ + Sc::BodyCore*const* mKinematics; + const PxU32 mNbKinematics; + PxsTransformCache& mCache; + Bp::BoundsArray& mBoundsArray; + + PX_NOCOPY(ScKinematicShapeUpdateTask) +public: + static const PxU32 NbKinematicsShapesPerTask = 1024; + + ScKinematicShapeUpdateTask(Sc::BodyCore*const* kinematics, PxU32 nbKinematics, PxsTransformCache& cache, Bp::BoundsArray& boundsArray, PxU64 contextID) : + Cm::Task(contextID), mKinematics(kinematics), mNbKinematics(nbKinematics), mCache(cache), mBoundsArray(boundsArray) + { + } + + virtual void runInternal() + { + const PxU32 nb = mNbKinematics; + for(PxU32 a=0; a(mKinematics[a]); + PX_ASSERT(b->getSim()->isKinematic()); + PX_ASSERT(b->getSim()->isActive()); + + b->getSim()->updateCached(mCache, mBoundsArray); + } + } + + virtual const char* getName() const + { + return "ScScene.KinematicShapeUpdateTask"; + } +}; +} + +void Sc::Scene::updateKinematicCached(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.updateKinematicCached", mContextId); + + const PxU32 nbKinematics = getActiveKinematicBodiesCount(); + if(!nbKinematics) + return; + + BodyCore*const* kinematics = getActiveKinematicBodies(); + + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + PxU32 startIndex = 0; + PxU32 nbShapes = 0; + + { + PX_PROFILE_ZONE("ShapeUpdate", mContextId); + + // PT: TASK-CREATION TAG + for(PxU32 i=0; i(kinematics[i])->getSim(); + PX_ASSERT(sim->isKinematic()); + PX_ASSERT(sim->isActive()); + + nbShapes += sim->getNbShapes(); + + if (nbShapes >= ScKinematicShapeUpdateTask::NbKinematicsShapesPerTask) + { + ScKinematicShapeUpdateTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScKinematicShapeUpdateTask)), ScKinematicShapeUpdateTask) + (kinematics + startIndex, (i + 1) - startIndex, mLLContext->getTransformCache(), *mBoundsArray, mContextId); + + task->setContinuation(continuation); + task->removeReference(); + startIndex = i + 1; + nbShapes = 0; + } + } + + if(nbShapes) + { + ScKinematicShapeUpdateTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScKinematicShapeUpdateTask)), ScKinematicShapeUpdateTask) + (kinematics + startIndex, nbKinematics - startIndex, mLLContext->getTransformCache(), *mBoundsArray, mContextId); + + task->setContinuation(continuation); + task->removeReference(); + } + } + + { + PxBitMapPinned& changedAABBMap = mAABBManager->getChangedAABBMgActorHandleMap(); + mLLContext->getTransformCache().setChangedState(); + mBoundsArray->setChangedState(); + for (PxU32 i = 0; i < nbKinematics; ++i) + { + Sc::BodySim* bodySim = static_cast(kinematics[i])->getSim(); + + if ((i+16) < nbKinematics) + { + PxPrefetchLine(kinematics[i + 16]); + if ((i + 8) < nbKinematics) + { + PxPrefetchLine(kinematics[i + 8]->getSim()); + } + } + + // PT: ### changedMap pattern #1 + PxU32 nbElems = bodySim->getNbElements(); + Sc::ElementSim** elems = bodySim->getElements(); + while (nbElems--) + { + Sc::ShapeSim* sim = static_cast(*elems++); + //KS - TODO - can we parallelize this? The problem with parallelizing is that it's a bit operation, + //so we would either need to use atomic operations or have some high-level concept that guarantees + //that threads don't write to the same word in the map simultaneously + if (sim->getFlags()&PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) + changedAABBMap.set(sim->getElementID()); + } + + mSimulationController->updateDynamic(NULL, bodySim->getNodeIndex()); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: TODO: consider using a non-member function for this one +bool BodySim::deactivateKinematic() +{ + BodyCore& core = getBodyCore(); + if(readInternalFlag(BF_KINEMATIC_SETTLING_2)) + { + clearInternalFlag(BF_KINEMATIC_SETTLING_2); + core.setWakeCounterFromSim(0); // For sleeping objects the wake counter must be 0. This needs to hold for kinematics too. + notifyReadyForSleeping(); + notifyPutToSleep(); + setActive(false); + return true; + } + else if (readInternalFlag(BF_KINEMATIC_SETTLING)) + { + clearInternalFlag(BF_KINEMATIC_SETTLING); + raiseInternalFlag(BF_KINEMATIC_SETTLING_2); + } + else if (!readInternalFlag(BF_KINEMATIC_SURFACE_VELOCITY)) + { + clearInternalFlag(BF_KINEMATIC_MOVED); + raiseInternalFlag(BF_KINEMATIC_SETTLING); + } + return false; +} + +// PT: called during fetchResults() +void Sc::Scene::postCallbacksPreSyncKinematics() +{ + PX_PROFILE_ZONE("Sim.postCallbacksPreSyncKinematics", mContextId); + + // Put/prepare kinematics to/for sleep and invalidate target pose + // note: this needs to get done after the contact callbacks because + // the target might get read there. + // + PxU32 nbKinematics = getActiveKinematicBodiesCount(); + BodyCore*const* kinematics = getActiveKinematicBodies(); + + //KS - this method must run over the kinematic actors in reverse. + while(nbKinematics--) + { + if(nbKinematics > 16) + { + PxPrefetchLine(static_cast(kinematics[nbKinematics-16])); + } + if (nbKinematics > 4) + { + PxPrefetchLine((static_cast(kinematics[nbKinematics - 4]))->getSim()); + PxPrefetchLine((static_cast(kinematics[nbKinematics - 4]))->getSim()->getSimStateData_Unchecked()); + } + + BodyCore* b = static_cast(kinematics[nbKinematics]); + //kinematics++; + PX_ASSERT(b->getSim()->isKinematic()); + PX_ASSERT(b->getSim()->isActive()); + + b->invalidateKinematicTarget(); + b->getSim()->deactivateKinematic(); + } +} diff --git a/physx/source/simulationcontroller/src/ScMetaData.cpp b/physx/source/simulationcontroller/src/ScMetaData.cpp index a4c0fb365..f631f293b 100644 --- a/physx/source/simulationcontroller/src/ScMetaData.cpp +++ b/physx/source/simulationcontroller/src/ScMetaData.cpp @@ -115,7 +115,7 @@ namespace PX_DEF_BIN_METADATA_ITEM(stream, ShadowPxsBodyCore, PxU8, isFastMoving, 0) PX_DEF_BIN_METADATA_ITEM(stream, ShadowPxsBodyCore, PxU8, disableGravity, 0) PX_DEF_BIN_METADATA_ITEM(stream, ShadowPxsBodyCore, PxU8, lockFlags, 0) - PX_DEF_BIN_METADATA_ITEM(stream, ShadowPxsBodyCore, PxU8, kinematicLink, 0) + PX_DEF_BIN_METADATA_ITEM(stream, ShadowPxsBodyCore, PxU8, fixedBaseLink, 0) } }; } @@ -185,7 +185,6 @@ void Sc::ConstraintCore::getBinaryMetaData(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxVec3, mAppliedForce, 0) PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxVec3, mAppliedTorque, 0) PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxConstraintConnector, mConnector, PxMetaDataFlag::ePTR) - PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxConstraintProject, mProject, PxMetaDataFlag::ePTR) PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxConstraintSolverPrep, mSolverPrep, PxMetaDataFlag::ePTR) PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxConstraintVisualize, mVisualize, PxMetaDataFlag::ePTR) PX_DEF_BIN_METADATA_ITEM(stream, ConstraintCore, PxU32, mDataSize, 0) @@ -265,7 +264,7 @@ void Sc::ShapeCore::getBinaryMetaData(PxOutputStream& stream) PX_DEF_BIN_METADATA_ITEM(stream, ShapeCore, PxFilterData, mSimulationFilterData, 0) PX_DEF_BIN_METADATA_ITEM(stream, ShapeCore, PxsShapeCore, mCore, 0) - PX_DEF_BIN_METADATA_ITEM(stream, ShapeCore, ShapeSim, mSimAndIsExclusive, PxMetaDataFlag::ePTR) + PX_DEF_BIN_METADATA_ITEM(stream, ShapeCore, ShapeSim, mExclusiveSim, PxMetaDataFlag::ePTR) PX_DEF_BIN_METADATA_ITEM(stream, ShapeCore, char, mName, PxMetaDataFlag::ePTR) PX_DEF_BIN_METADATA_EXTRA_NAME(stream, ShapeCore, mName, 0) diff --git a/physx/source/simulationcontroller/src/ScNPhaseCore.cpp b/physx/source/simulationcontroller/src/ScNPhaseCore.cpp index 2bfbb856a..219e15e18 100644 --- a/physx/source/simulationcontroller/src/ScNPhaseCore.cpp +++ b/physx/source/simulationcontroller/src/ScNPhaseCore.cpp @@ -31,22 +31,10 @@ #include "ScTriggerInteraction.h" #include "ScElementInteractionMarker.h" #include "ScConstraintInteraction.h" -#include "ScConstraintSim.h" -#include "ScConstraintCore.h" #include "ScSimStats.h" -#include "ScObjectIDTracker.h" -#include "ScSimStats.h" - -#include "foundation/PxThread.h" -#include "BpBroadPhase.h" -#include "common/PxProfileZone.h" -#include "ScSoftBodyShapeSim.h" -#include "ScParticleSystemShapeSim.h" -#include "ScArticulationSim.h" using namespace physx; using namespace Sc; -using namespace Gu; /////////////////////////////////////////////////////////////////////////////// @@ -54,695 +42,6 @@ PX_IMPLEMENT_OUTPUT_ERROR /////////////////////////////////////////////////////////////////////////////// -class Sc::FilterPairManager : public PxUserAllocated -{ - PX_NOCOPY(FilterPairManager) -public: - FilterPairManager() - : mPairs("FilterPairManager Array") - , mFree(INVALID_FILTER_PAIR_INDEX) - {} - - PxU32 acquireIndex() - { - PxU32 index; - if(mFree == INVALID_FILTER_PAIR_INDEX) - { - index = mPairs.size(); - mPairs.pushBack(NULL); - } - else - { - index = PxU32(mFree); - mFree = reinterpret_cast(mPairs[index]); - mPairs[index] = NULL; - } - return index; - } - - void releaseIndex(PxU32 index) - { - mPairs[index] = reinterpret_cast(mFree); - mFree = index; - } - - void setPair(PxU32 index, Sc::ElementSimInteraction* ptr) - { - mPairs[index] = ptr; - } - - Sc::ElementSimInteraction* operator[](PxU32 index) - { - return mPairs[index]; - } - - PxU32 findIndex(Sc::ElementSimInteraction* ptr) - { - return ptr->getFilterPairIndex(); - } - -private: - PxArray mPairs; - uintptr_t mFree; -}; - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -static PX_FORCE_INLINE PxU32 hasTriggerFlags(PxShapeFlags flags) { return PxU32(flags) & PxU32(PxShapeFlag::eTRIGGER_SHAPE); } -static void getFilterInfo_ShapeSim(PxFilterObjectAttributes& filterAttr, PxFilterData& filterData, const Sc::ShapeSim& shape) -{ - filterAttr = hasTriggerFlags(shape.getCore().getFlags()) ? PxFilterObjectFlag::eTRIGGER : PxFilterObjectFlag::Enum(0); - - BodySim* b = shape.getBodySim(); - if(b) - { - if(!b->isArticulationLink()) - { - if(b->isKinematic()) - filterAttr |= PxFilterObjectFlag::eKINEMATIC; - - setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eRIGID_DYNAMIC); - } - else - setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eARTICULATION); - } - else - { - // For softbody and particle system, the bodySim is set to null - if (shape.getActor().isSoftBody()) - setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eSOFTBODY); - else if (shape.getActor().isParticleSystem()) - setFilterObjectAttributeType(filterAttr, PxFilterObjectType::ePARTICLESYSTEM); - else if (shape.getActor().isHairSystem()) - setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eHAIRSYSTEM); - else - setFilterObjectAttributeType(filterAttr, PxFilterObjectType::eRIGID_STATIC); - } - - filterData = shape.getCore().getSimulationFilterData(); -} - -static PX_FORCE_INLINE void getFilterInfo(PxFilterData& fd, PxFilterObjectAttributes& fa, const ElementSim& e) -{ - getFilterInfo_ShapeSim(fa, fd, static_cast(e)); -} - -static void getFilterInfo(PxFilterData& fd0, PxFilterData& fd1, PxFilterObjectAttributes& fa0, PxFilterObjectAttributes& fa1, const ElementSim& e0, const ElementSim& e1) -{ - getFilterInfo(fd0, fa0, e0); - getFilterInfo(fd1, fa1, e1); -} - -static PX_INLINE void callPairLost(Scene& scene, const ElementSim& e0, const ElementSim& e1, PxU32 pairID, bool objVolumeRemoved) -{ - PxFilterData fd0(PxEmpty), fd1(PxEmpty); - PxFilterObjectAttributes fa0, fa1; - getFilterInfo(fd0, fd1, fa0, fa1, e0, e1); - - scene.getFilterCallbackFast()->pairLost(pairID, fa0, fd0, fa1, fd1, objVolumeRemoved); -} - -// Filtering - -static PX_INLINE void checkFilterFlags(PxFilterFlags& filterFlags) -{ - if((filterFlags & (PxFilterFlag::eKILL | PxFilterFlag::eSUPPRESS)) == (PxFilterFlag::eKILL | PxFilterFlag::eSUPPRESS)) - { -#if PX_CHECKED - outputError(__LINE__, "Filtering: eKILL and eSUPPRESS must not be set simultaneously. eSUPPRESS will be used."); -#endif - filterFlags.clear(PxFilterFlag::eKILL); - } -} - -static PX_FORCE_INLINE PxPairFlags checkRbPairFlags(const ShapeSimBase& s0, const ShapeSimBase& s1, PxPairFlags pairFlags) -{ -#if PX_CHECKED - // we want to avoid to run contact generation for pairs that should not get resolved or have no contact/trigger reports - if (!(PxU32(pairFlags) & (PxPairFlag::eSOLVE_CONTACT | ShapeInteraction::CONTACT_REPORT_EVENTS))) - outputError(__LINE__, "Filtering: Pair with no contact/trigger reports detected, nor is PxPairFlag::eSOLVE_CONTACT set. It is recommended to suppress/kill such pairs for performance reasons."); - else if(!(pairFlags & (PxPairFlag::eDETECT_DISCRETE_CONTACT | PxPairFlag::eDETECT_CCD_CONTACT))) - outputError(__LINE__, "Filtering: Pair did not request either eDETECT_DISCRETE_CONTACT or eDETECT_CCD_CONTACT. It is recommended to suppress/kill such pairs for performance reasons."); - - if(((s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)!=0 || (s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)!=0) && - (pairFlags & PxPairFlag::eTRIGGER_DEFAULT) && (pairFlags & PxPairFlag::eDETECT_CCD_CONTACT)) - outputError(__LINE__, "Filtering: CCD isn't supported on Triggers yet"); -#else - PX_UNUSED(s0); - PX_UNUSED(s1); -#endif - return pairFlags; -} - -static PX_INLINE PxPairFlags checkRbPairFlags( const ShapeSimBase& s0, const ShapeSimBase& s1, - const ActorSim& bs0, const ActorSim& bs1, - PxPairFlags pairFlags, PxFilterFlags filterFlags, - bool isNonRigid) -{ - if(filterFlags & (PxFilterFlag::eSUPPRESS | PxFilterFlag::eKILL)) - return pairFlags; - - if (bs0.isDynamicRigid() && static_cast(bs0).isKinematic() && - bs1.isDynamicRigid() && static_cast(bs1).isKinematic() && - (pairFlags & PxPairFlag::eSOLVE_CONTACT)) - { -#if PX_CHECKED - outputError(__LINE__, "Filtering: Resolving contacts between two kinematic objects is invalid. Contacts will not get resolved."); -#endif - pairFlags.clear(PxPairFlag::eSOLVE_CONTACT); - } - - if (isNonRigid && (pairFlags & PxPairFlag::eDETECT_CCD_CONTACT)) - pairFlags.clear(PxPairFlag::eDETECT_CCD_CONTACT); - - return checkRbPairFlags(s0, s1, pairFlags); -} - -// PT: version specialized for ShapeSim/ShapeSim -static PX_INLINE PxPairFlags checkRbPairFlags( const ShapeSimBase& s0, const ShapeSimBase& s1, - bool kine0, bool kine1, - PxPairFlags pairFlags, PxFilterFlags filterFlags, - bool isNonRigid) -{ - if(filterFlags & (PxFilterFlag::eSUPPRESS | PxFilterFlag::eKILL)) - return pairFlags; - - if(kine0 && kine1 && (pairFlags & PxPairFlag::eSOLVE_CONTACT)) - { -#if PX_CHECKED - outputError(__LINE__, "Filtering: Resolving contacts between two kinematic objects is invalid. Contacts will not get resolved."); -#endif - pairFlags.clear(PxPairFlag::eSOLVE_CONTACT); - } - - if (pairFlags & PxPairFlag::eDETECT_CCD_CONTACT && isNonRigid) - { - pairFlags.clear(PxPairFlag::eDETECT_CCD_CONTACT); - } - - return checkRbPairFlags(s0, s1, pairFlags); -} - -static PX_FORCE_INLINE void fetchActorAndShape(const ElementSim& e, PxActor*& a, PxShape*& s) -{ - const ShapeSimBase& sim = static_cast(e); - a = sim.getActor().getPxActor(); - - PxActorType::Enum type = sim.getActor().getActorType(); - if (type == PxActorType::ePBD_PARTICLESYSTEM || - type == PxActorType::eFLIP_PARTICLESYSTEM || - type == PxActorType::eMPM_PARTICLESYSTEM || - type == PxActorType::eCUSTOM_PARTICLESYSTEM) - s = NULL; // Particle system does not have a valid shape so set it to null - else - s = sim.getPxShape(); -} - -static void runFilter(PxFilterInfo& filterInfo, const FilteringContext& context, const ElementSim& e0, const ElementSim& e1, PxU32 filterPairIndex, bool doCallbacks) -{ - PxFilterData fd0(PxEmpty), fd1(PxEmpty); - PxFilterObjectAttributes fa0, fa1; - getFilterInfo(fd0, fd1, fa0, fa1, e0, e1); - - // Run filter shader - filterInfo.filterFlags = context.mFilterShader(fa0, fd0, fa1, fd1, filterInfo.pairFlags, context.mFilterShaderData, context.mFilterShaderDataSize); - - if(filterInfo.filterFlags & PxFilterFlag::eCALLBACK) - { - if(context.mFilterCallback) - { - if(!doCallbacks) - { - return; - } - else - { - if(filterPairIndex == INVALID_FILTER_PAIR_INDEX) - filterPairIndex = context.mFilterPairManager->acquireIndex(); - // If a FilterPair is provided, then we use it, else we create a new one - // (A FilterPair is provided in the case for a pairLost()-pairFound() sequence after refiltering) - - PxActor* a0, *a1; - PxShape* s0, *s1; - fetchActorAndShape(e0, a0, s0); - fetchActorAndShape(e1, a1, s1); - - filterInfo.filterFlags = context.mFilterCallback->pairFound(filterPairIndex, fa0, fd0, a0, s0, fa1, fd1, a1, s1, filterInfo.pairFlags); - filterInfo.filterPairIndex = filterPairIndex; - } - } - else - { - filterInfo.filterFlags.clear(PxFilterFlag::eNOTIFY); - outputError(__LINE__, "Filtering: eCALLBACK set but no filter callback defined."); - } - } - - checkFilterFlags(filterInfo.filterFlags); - - if(filterPairIndex!=INVALID_FILTER_PAIR_INDEX && ((filterInfo.filterFlags & PxFilterFlag::eKILL) || ((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) != PxFilterFlag::eNOTIFY))) - { - if((filterInfo.filterFlags & PxFilterFlag::eKILL) && ((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) == PxFilterFlag::eNOTIFY)) - context.mFilterCallback->pairLost(filterPairIndex, fa0, fd0, fa1, fd1, false); - - if((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) != PxFilterFlag::eNOTIFY) - { - // No notification, hence we don't need to treat it as a filter callback pair anymore. - // Make sure that eCALLBACK gets removed as well - filterInfo.filterFlags.clear(PxFilterFlag::eNOTIFY); - } - - context.mFilterPairManager->releaseIndex(filterPairIndex); - filterInfo.filterPairIndex = INVALID_FILTER_PAIR_INDEX; - } - - // Sanity checks - PX_ASSERT( (filterInfo.filterFlags != PxFilterFlag::eKILL) || - ((filterInfo.filterFlags == PxFilterFlag::eKILL) && (filterInfo.filterPairIndex == INVALID_FILTER_PAIR_INDEX)) ); - PX_ASSERT( ((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) != PxFilterFlag::eNOTIFY) || - (((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) == PxFilterFlag::eNOTIFY) && filterInfo.filterPairIndex!=INVALID_FILTER_PAIR_INDEX) ); -} - -// PT: version specialized for ShapeSim/ShapeSim -static PX_FORCE_INLINE void runFilterShapeSim(PxFilterInfo& filterInfo, const FilteringContext& context, const ShapeSimBase& e0, const ShapeSimBase& e1, const PxFilterObjectAttributes fa0, const PxFilterObjectAttributes fa1) -{ - // Run filter shader - { - const PxFilterData fd0 = e0.getCore().getSimulationFilterData(); - const PxFilterData fd1 = e1.getCore().getSimulationFilterData(); - filterInfo.filterFlags = context.mFilterShader(fa0, fd0, fa1, fd1, filterInfo.pairFlags, context.mFilterShaderData, context.mFilterShaderDataSize); - } - - if(filterInfo.filterFlags & PxFilterFlag::eCALLBACK) - { - if(context.mFilterCallback) - { - return; - } - else - { - filterInfo.filterFlags.clear(PxFilterFlag::eNOTIFY); - outputError(__LINE__, "Filtering: eCALLBACK set but no filter callback defined."); - } - } - - checkFilterFlags(filterInfo.filterFlags); - - // Sanity checks - PX_ASSERT( (filterInfo.filterFlags != PxFilterFlag::eKILL) || - ((filterInfo.filterFlags == PxFilterFlag::eKILL) && (filterInfo.filterPairIndex == INVALID_FILTER_PAIR_INDEX)) ); - PX_ASSERT( ((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) != PxFilterFlag::eNOTIFY) || - (((filterInfo.filterFlags & PxFilterFlag::eNOTIFY) == PxFilterFlag::eNOTIFY) && filterInfo.filterPairIndex!=INVALID_FILTER_PAIR_INDEX) ); -} - -// helper method for some cleanup code that is used multiple times for early outs in case a rigid body collision pair gets filtered out due to some hardwired filter criteria -static PX_FORCE_INLINE PxFilterInfo filterOutRbCollisionPair(FilterPairManager* filterPairManager, PxU32 filterPairIndex, const PxFilterFlags filterFlags) -{ - if(filterPairIndex!=INVALID_FILTER_PAIR_INDEX) - filterPairManager->releaseIndex(filterPairIndex); - - return PxFilterInfo(filterFlags); -} - -PxFilterInfo Sc::filterRbCollisionPairSecondStage(const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, const ActorSim& b0, const ActorSim& b1, PxU32 filterPairIndex, bool runCallbacks, - bool isNonRigid) -{ - PxFilterInfo filterInfo; - - runFilter(filterInfo, context, s0, s1, filterPairIndex, runCallbacks); - - if(runCallbacks || (!(filterInfo.filterFlags & PxFilterFlag::eCALLBACK))) - filterInfo.pairFlags = checkRbPairFlags(s0, s1, b0, b1, filterInfo.pairFlags, filterInfo.filterFlags, isNonRigid); - - return filterInfo; -} - -// PT: version specialized for ShapeSim/ShapeSim -static PX_FORCE_INLINE PxFilterInfo filterRbCollisionPairSecondStage(const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, bool kine0, bool kine1, const PxFilterObjectAttributes fa0, const PxFilterObjectAttributes fa1, - bool isNonRigid) -{ - PxFilterInfo filterInfo; - runFilterShapeSim(filterInfo, context, s0, s1, fa0, fa1); - - if(!(filterInfo.filterFlags & PxFilterFlag::eCALLBACK)) - filterInfo.pairFlags = checkRbPairFlags(s0, s1, kine0, kine1, filterInfo.pairFlags, filterInfo.filterFlags, isNonRigid); - - return filterInfo; -} - -static bool filterArticulationLinks(const ActorSim& rbActor0, const ActorSim& rbActor1) -{ - { - //It's the same articulation, so we can filter based on flags... - const BodySim& bs0 = static_cast(rbActor0); - const BodySim& bs1 = static_cast(rbActor1); - - const ArticulationSim* articulationSim0 = bs0.getArticulation(); - const ArticulationSim* articulationSim1 = bs1.getArticulation(); - if (articulationSim0 == articulationSim1) - { - if (articulationSim0->getCore().getArticulationFlags() & PxArticulationFlag::eDISABLE_SELF_COLLISION) - return true; - - //check to see if one link is the parent of the other link, if so disable collision - PxU32 linkId0 = bs0.getNodeIndex().articulationLinkId(); - PxU32 linkId1 = bs1.getNodeIndex().articulationLinkId(); - - - const Dy::ArticulationLink& link0 = articulationSim0->getLink(linkId0); - const Dy::ArticulationLink& link1 = articulationSim1->getLink(linkId1); - - if (linkId1 < linkId0) - return link0.parent == linkId1; - - return link1.parent == linkId0; - } - } - - return false; -} - -static bool filterJointedBodies2(const ActorSim& actor, const ActorSim& other) -{ - if(!actor.isDynamicRigid()) - return false; - - ConstraintCore* core = actor.getScene().findConstraintCore(&actor, &other); - - if(core) - return !(core->getFlags() & PxConstraintFlag::eCOLLISION_ENABLED); - return false; - - /*const Sc::ActorSim* actorToMatch; - PxU32 size; - Interaction** interactions; - - if(actor.getActorInteractionCount() <= other.getActorInteractionCount()) - { - size = actor.getActorInteractionCount(); - interactions = actor.getActorInteractions(); - actorToMatch = &other; - } - else - { - size = other.getActorInteractionCount(); - interactions = other.getActorInteractions(); - actorToMatch = &actor; - } - - while(size--) - { - Interaction* interaction = *interactions++; - if(interaction->getType() == InteractionType::eCONSTRAINTSHADER) - { - ConstraintInteraction* csi = static_cast(interaction); - if((&csi->getActorSim0() == actorToMatch) || (&csi->getActorSim1() == actorToMatch)) - return !(csi->getConstraint()->getCore().getFlags() & PxConstraintFlag::eCOLLISION_ENABLED); - } - } - return false;*/ -} - -static PX_FORCE_INLINE bool filterJointedBodies(const ActorSim& rbActor0, const ActorSim& rbActor1) -{ - // If the bodies of the shape pair are connected by a joint, we need to check whether this connection disables the collision. - // Note: As an optimization, the dynamic bodies have a flag which specifies whether they have any constraints at all. That works - // because a constraint has at least one dynamic body and an interaction is tracked by both objects. - - if(rbActor0.isDynamicRigid()) - return filterJointedBodies2(rbActor0, rbActor1); - return filterJointedBodies2(rbActor1, rbActor0); -} - -static PX_FORCE_INLINE bool hasForceNotifEnabled(const BodySim* bs, PxRigidBodyFlag::Enum flag) -{ - if(!bs) - return false; - - const PxsRigidCore& core = bs->getBodyCore().getCore(); - return core.mFlags.isSet(flag); -} - -static PX_FORCE_INLINE bool validateSuppress(const BodySim* b0, const BodySim* b1, PxRigidBodyFlag::Enum flag) -{ - if(hasForceNotifEnabled(b0, flag)) - return false; - - if(hasForceNotifEnabled(b1, flag)) - return false; - - return true; -} - -static PX_FORCE_INLINE bool filterKinematics(const BodySim* b0, const BodySim* b1, bool kine0, bool kine1, - const PxPairFilteringMode::Enum kineKineFilteringMode, const PxPairFilteringMode::Enum staticKineFilteringMode) -{ - const bool kinematicPair = kine0 | kine1; - if(kinematicPair) - { - if(staticKineFilteringMode != PxPairFilteringMode::eKEEP) - { - if(!b0 || !b1) - return validateSuppress(b0, b1, PxRigidBodyFlag::eFORCE_STATIC_KINE_NOTIFICATIONS); - } - - if(kineKineFilteringMode != PxPairFilteringMode::eKEEP) - { - if(kine0 && kine1) - return validateSuppress(b0, b1, PxRigidBodyFlag::eFORCE_KINE_KINE_NOTIFICATIONS); - } - } - return false; -} - -static const BodySim* isKinematic(const ActorSim& actorSim, bool& kine) -{ - if(actorSim.isDynamicRigid()) - { - const BodySim* bs = static_cast(&actorSim); - kine = bs->isKinematic(); - return bs; - } - else - { - kine = false; - return NULL; - } -} - -static PxFilterInfo filterRbCollisionPair(const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, PxU32 filterPairIndex, bool& isTriggerPair, bool runCallbacks) -{ - const ActorSim& b0 = s0.getActor(); - const ActorSim& b1 = s1.getActor(); - - const PxU32 trigger0 = s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE; - const PxU32 trigger1 = s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE; - isTriggerPair = (trigger0 | trigger1)!=0; - - bool isNonRigid = false; - - if(isTriggerPair) - { - if(trigger0 && trigger1) // trigger-trigger pairs are not supported - return filterOutRbCollisionPair(context.mFilterPairManager, filterPairIndex, PxFilterFlag::eKILL); - } - else - { - bool kine0, kine1; - const BodySim* bs0 = isKinematic(b0, kine0); - const BodySim* bs1 = isKinematic(b1, kine1); - - isNonRigid = b0.isNonRigid() || b1.isNonRigid(); - - if(!isNonRigid && filterKinematics(bs0, bs1, kine0, kine1, context.mKineKineFilteringMode, context.mStaticKineFilteringMode)) - return filterOutRbCollisionPair(context.mFilterPairManager, filterPairIndex, PxFilterFlag::eSUPPRESS); - - if(filterJointedBodies(b0, b1)) - return filterOutRbCollisionPair(context.mFilterPairManager, filterPairIndex, PxFilterFlag::eSUPPRESS); - - if((b0.getActorType() == PxActorType::eARTICULATION_LINK) && (b1.getActorType() == PxActorType::eARTICULATION_LINK)) - { - if(filterArticulationLinks(b0, b1)) - return filterOutRbCollisionPair(context.mFilterPairManager, filterPairIndex, PxFilterFlag::eKILL); - } - } - return filterRbCollisionPairSecondStage(context, s0, s1, b0, b1, filterPairIndex, runCallbacks, isNonRigid); -} - -// PT: indexed by PxActorType -static const PxU32 gTypeData[] = { - PxFilterObjectType::eRIGID_STATIC<<1, - (PxFilterObjectType::eRIGID_DYNAMIC<<1)|1, - (PxFilterObjectType::eARTICULATION<<1)|1, - (PxFilterObjectType::eSOFTBODY<<1)|1, - (PxFilterObjectType::eFEMCLOTH << 1) | 1, - (PxFilterObjectType::ePARTICLESYSTEM<<1)|1, //PBD - (PxFilterObjectType::ePARTICLESYSTEM<<1)|1, //FLIP - (PxFilterObjectType::ePARTICLESYSTEM<<1)|1, //MPM - (PxFilterObjectType::ePARTICLESYSTEM<<1)|1, //Custom - (PxFilterObjectType::eHAIRSYSTEM<<1)|1, -}; - -static PX_FORCE_INLINE bool isParticleSystem(const PxActorType::Enum actorType) -{ - return actorType == PxActorType::ePBD_PARTICLESYSTEM || actorType == PxActorType::eFLIP_PARTICLESYSTEM - || actorType == PxActorType::eMPM_PARTICLESYSTEM || actorType == PxActorType::eCUSTOM_PARTICLESYSTEM; -} - -// PT: version specialized for ShapeSim/ShapeSim (no triggers) -static PX_FORCE_INLINE PxFilterInfo filterRbCollisionPair(const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1) -{ - const ActorSim& rbActor0 = s0.getActor(); - const PxActorType::Enum actorType0 = rbActor0.getActorType(); - const PxU32 typeData0 = gTypeData[actorType0]; - PxFilterObjectAttributes filterAttr0 = typeData0>>1; - bool kine0 = false; - bool isNonRigid = false; - const BodySim* bs0 = NULL; - if (rbActor0.isDynamicRigid()) - { - bs0 = static_cast(&rbActor0); - kine0 = bs0->isKinematic(); - filterAttr0 |= kine0 ? PxFilterObjectFlag::eKINEMATIC : 0; - } - else if (rbActor0.isNonRigid()) - { - isNonRigid = true; - } - - const ActorSim& rbActor1 = s1.getActor(); - const PxActorType::Enum actorType1 = rbActor1.getActorType(); - const PxU32 typeData1 = gTypeData[actorType1]; - PxFilterObjectAttributes filterAttr1 = typeData1 >> 1; - bool kine1 = false; - const BodySim* bs1 = NULL; - if (rbActor1.isDynamicRigid()) - { - bs1 = static_cast(&rbActor1); - kine1 = bs1->isKinematic(); - filterAttr0 |= kine1 ? PxFilterObjectFlag::eKINEMATIC : 0; - } - else if (rbActor1.isNonRigid()) - { - isNonRigid = true; - } - - PX_ASSERT(!(s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); - PX_ASSERT(!(s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); - - if (!isNonRigid && filterKinematics(bs0, bs1, kine0, kine1, context.mKineKineFilteringMode, context.mStaticKineFilteringMode)) - return PxFilterInfo(PxFilterFlag::eSUPPRESS); - - if(filterJointedBodies(rbActor0, rbActor1)) - return PxFilterInfo(PxFilterFlag::eSUPPRESS); - - if(isParticleSystem(actorType0) && isParticleSystem(actorType1)) - return PxFilterInfo(PxFilterFlag::eKILL); - - if(actorType0 == PxActorType::eHAIRSYSTEM && actorType1 == PxActorType::eHAIRSYSTEM) - return PxFilterInfo(PxFilterFlag::eKILL); - - - if ((actorType0 == PxActorType::eARTICULATION_LINK) ^ (actorType1 == PxActorType::eARTICULATION_LINK)) - { - if(actorType0 == PxActorType::eARTICULATION_LINK) - { - const BodySim& b0 = static_cast(rbActor0); - const PxU8 kinematicLink = b0.getLowLevelBody().mCore->kinematicLink; - const bool isStaticOrKinematic = (actorType1 == PxActorType::eRIGID_STATIC) || kine1; - if (kinematicLink && isStaticOrKinematic) - return PxFilterInfo(PxFilterFlag::eSUPPRESS); - } - - if (actorType1 == PxActorType::eARTICULATION_LINK) - { - const BodySim& b1 = static_cast(rbActor1); - const PxU8 kinematicLink = b1.getLowLevelBody().mCore->kinematicLink; - const bool isStaticOrKinematic = (actorType0 == PxActorType::eRIGID_STATIC) || kine0; - if (kinematicLink && isStaticOrKinematic) - return PxFilterInfo(PxFilterFlag::eSUPPRESS); - } - } - - if((actorType0 == PxActorType::eARTICULATION_LINK) && (actorType1 == PxActorType::eARTICULATION_LINK)) - { - const BodySim& b0 = static_cast(rbActor0); - const BodySim& b1 = static_cast(rbActor1); - const PxU8 kinematicLink0 = b0.getLowLevelBody().mCore->kinematicLink; - const PxU8 kinematicLink1 = b1.getLowLevelBody().mCore->kinematicLink; - if (kinematicLink0 && kinematicLink1) - return PxFilterInfo(PxFilterFlag::eSUPPRESS); - - if(filterArticulationLinks(rbActor0, rbActor1)) - return PxFilterInfo(PxFilterFlag::eKILL); - } - - return filterRbCollisionPairSecondStage(context, s0, s1, kine0, kine1, filterAttr0, filterAttr1, isNonRigid); -} - -void NPhaseCore::runOverlapFilters( PxU32 nbToProcess, const Bp::AABBOverlap* PX_RESTRICT pairs, PxFilterInfo* PX_RESTRICT filterInfo, - PxU32& nbToKeep_, PxU32& nbToSuppress_, PxU32& nbToCallback_, PxU32* PX_RESTRICT keepMap, PxU32* PX_RESTRICT callbackMap) -{ - PxU32 nbToKeep = 0; - PxU32 nbToSuppress = 0; - PxU32 nbToCallback = 0; - - const FilteringContext context(mOwnerScene, mFilterPairManager); - - for(PxU32 i=0; i(pair.mUserData0); - ElementSim* e1 = reinterpret_cast(pair.mUserData1); - - PX_ASSERT(e0); - PX_ASSERT(e1); - - // PT: a bit of defensive coding added for OM-74224. In theory this should not be needed, as the broadphase is not - // supposed to return null pointers here. But there seems to be an issue somewhere, most probably in the GPU BP kernels, - // and this is an attempt at preventing a crash. We could/should remove this eventually. - if(!e0 || !e1) - { - PxGetFoundation().error(PxErrorCode::eINTERNAL_ERROR, PX_FL, "NPhaseCore::runOverlapFilters: found null elements!"); - continue; - } - - PX_ASSERT(!findInteraction(e0, e1)); - - ShapeSimBase* s0 = static_cast(e0); - ShapeSimBase* s1 = static_cast(e1); - PX_ASSERT(&s0->getActor() != &s1->getActor()); // No actor internal interactions - - filterInfo[i] = filterRbCollisionPair(context, *s0, *s1); - - const PxFilterFlags filterFlags = filterInfo[i].filterFlags; - - if(!(filterFlags & PxFilterFlag::eKILL)) - { - if(filterFlags & PxFilterFlag::eCALLBACK) - { - nbToCallback++; - callbackMap[i / 32] |= (1 << (i & 31)); - } - else - { - if(!(filterFlags & PxFilterFlag::eSUPPRESS)) - nbToKeep++; - else - nbToSuppress++; - keepMap[i / 32] |= (1 << (i & 31)); - } - } - } - - nbToKeep_ = nbToKeep; - nbToSuppress_ = nbToSuppress; - nbToCallback_ = nbToCallback; -} - -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - NPhaseCore::NPhaseCore(Scene& scene, const PxSceneDesc& sceneDesc) : mOwnerScene (scene), mContactReportActorPairSet ("contactReportPairSet"), @@ -755,19 +54,17 @@ NPhaseCore::NPhaseCore(Scene& scene, const PxSceneDesc& sceneDesc) : mShapeInteractionPool (PxAllocatorTraits::Type("shapeInteractionPool"), 4096), mTriggerInteractionPool ("triggerInteractionPool"), mActorPairContactReportDataPool ("actorPairContactReportPool"), - mInteractionMarkerPool ("interactionMarkerPool") - ,mMergeProcessedTriggerInteractions (scene.getContextId(), this, "ScNPhaseCore.mergeProcessedTriggerInteractions") - ,mTmpTriggerProcessingBlock (NULL) - ,mTriggerPairsToDeactivateCount (0) + mInteractionMarkerPool ("interactionMarkerPool"), + mMergeProcessedTriggerInteractions (scene.getContextId(), this, "ScNPhaseCore.mergeProcessedTriggerInteractions"), + mTmpTriggerProcessingBlock (NULL), + mTriggerPairsToDeactivateCount (0) { - mFilterPairManager = PX_NEW(FilterPairManager); } NPhaseCore::~NPhaseCore() { // Clear pending actor pairs (waiting on contact report callback) clearContactReportActorPairs(false); - PX_DELETE(mFilterPairManager); } PxU32 NPhaseCore::getDefaultContactReportStreamBufferSize() const @@ -775,59 +72,23 @@ PxU32 NPhaseCore::getDefaultContactReportStreamBufferSize() const return mContactReportBuffer.getDefaultBufferSize(); } -ElementSimInteraction* NPhaseCore::findInteraction(ElementSim* _element0, ElementSim* _element1) +ElementSimInteraction* NPhaseCore::findInteraction(const ElementSim* element0, const ElementSim* element1) { - const PxHashMap::Entry* pair = mElementSimMap.find(ElementSimKey(_element0, _element1)); + const PxHashMap::Entry* pair = mElementSimMap.find(ElementSimKey(element0->getElementID(), element1->getElementID())); return pair ? pair->second : NULL; } -void NPhaseCore::onTriggerOverlapCreated(const Bp::AABBOverlap* PX_RESTRICT pairs, PxU32 pairCount) -{ - for(PxU32 i=0; i(pairs[i].mUserData0); - ElementSim* volume1 = reinterpret_cast(pairs[i].mUserData1); - PX_ASSERT(!findInteraction(volume0, volume1)); - - ShapeSimBase* shapeHi = static_cast(volume1); - ShapeSimBase* shapeLo = static_cast(volume0); - - // No actor internal interactions - PX_ASSERT(&shapeHi->getActor() != &shapeLo->getActor()); - - // PT: this case is only for triggers these days - PX_ASSERT((shapeLo->getFlags() & PxShapeFlag::eTRIGGER_SHAPE) || (shapeHi->getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); - - createTriggerElementInteraction(*shapeHi, *shapeLo); - } -} - -void NPhaseCore::reserveInteraction(PxU32 nbNewInteractions) -{ - if ((mElementSimMap.size() + nbNewInteractions) > mElementSimMap.capacity()) - { - PX_PROFILE_ZONE("Reserve", 0); - PxU32 newSize = PxMax(mElementSimMap.size() + nbNewInteractions, mElementSimMap.capacity()); - mElementSimMap.reserve(newSize); - } -} - void NPhaseCore::registerInteraction(ElementSimInteraction* interaction) { - mElementSimMap.insert(ElementSimKey(&interaction->getElement0(), &interaction->getElement1()), interaction); + mElementSimMap.insert(ElementSimKey(interaction->getElement0().getElementID(), interaction->getElement1().getElementID()), interaction); } void NPhaseCore::unregisterInteraction(ElementSimInteraction* interaction) { - mElementSimMap.erase(ElementSimKey(&interaction->getElement0(), &interaction->getElement1())); -} - -ElementSimInteraction* NPhaseCore::onOverlapRemovedStage1(ElementSim* volume0, ElementSim* volume1) -{ - return findInteraction(volume0, volume1); + mElementSimMap.erase(ElementSimKey(interaction->getElement0().getElementID(), interaction->getElement1().getElementID())); } -void NPhaseCore::onOverlapRemoved(ElementSim* volume0, ElementSim* volume1, const PxU32 ccdPass, void* elemSim, PxsContactManagerOutputIterator& outputs) +void NPhaseCore::onOverlapRemoved(ElementSim* volume0, ElementSim* volume1, PxU32 ccdPass, void* elemSim, PxsContactManagerOutputIterator& outputs) { ElementSim* elementHi = volume1; ElementSim* elementLo = volume0; @@ -870,7 +131,7 @@ void NPhaseCore::onVolumeRemoved(ElementSim* volume, PxU32 flags, PxsContactMana } } -ElementSimInteraction* NPhaseCore::createRbElementInteraction(const PxFilterInfo& finfo, ShapeSimBase& s0, ShapeSimBase& s1, PxsContactManager* contactManager, ShapeInteraction* shapeInteraction, +ElementSimInteraction* NPhaseCore::createRbElementInteraction(const FilterInfo& finfo, ShapeSimBase& s0, ShapeSimBase& s1, PxsContactManager* contactManager, ShapeInteraction* shapeInteraction, ElementInteractionMarker* interactionMarker, bool isTriggerPair) { ElementSimInteraction* pair = NULL; @@ -891,38 +152,15 @@ ElementSimInteraction* NPhaseCore::createRbElementInteraction(const PxFilterInfo else pair = createElementInteractionMarker(s0, s1, interactionMarker); - if(finfo.filterPairIndex != INVALID_FILTER_PAIR_INDEX) + if(finfo.hasPairID) { // Mark the pair as a filter callback pair pair->raiseInteractionFlag(InteractionFlag::eIS_FILTER_PAIR); - - // Filter callback pair: Set the link to the interaction - mFilterPairManager->setPair(finfo.filterPairIndex, pair); - pair->setFilterPairIndex(finfo.filterPairIndex); } return pair; } -ElementSimInteraction* NPhaseCore::createTriggerElementInteraction(ShapeSimBase& s0, ShapeSimBase& s1) -{ - PX_ASSERT((s0.getFlags() & PxShapeFlag::eTRIGGER_SHAPE) || (s1.getFlags() & PxShapeFlag::eTRIGGER_SHAPE)); - - const FilteringContext context(mOwnerScene, mFilterPairManager); - - bool isTriggerPair; - const PxFilterInfo finfo = filterRbCollisionPair(context, s0, s1, INVALID_FILTER_PAIR_INDEX, isTriggerPair, false); - PX_ASSERT(isTriggerPair); - - if(finfo.filterFlags & PxFilterFlag::eKILL) - { - PX_ASSERT(finfo.filterPairIndex == INVALID_FILTER_PAIR_INDEX); // No filter callback pair info for killed pairs - return NULL; - } - - return createRbElementInteraction(finfo, s0, s1, NULL, NULL, NULL, isTriggerPair); -} - void NPhaseCore::managerNewTouch(ShapeInteraction& interaction) { //(1) if the pair hasn't already been assigned, look it up! @@ -939,11 +177,8 @@ void NPhaseCore::managerNewTouch(ShapeInteraction& interaction) } } -ShapeInteraction* NPhaseCore::createShapeInteraction(ShapeSimBase& s0, ShapeSimBase& s1, PxPairFlags pairFlags, PxsContactManager* contactManager, ShapeInteraction* shapeInteraction) +static bool shouldSwapBodies(const ShapeSimBase& s0, const ShapeSimBase& s1) { - ShapeSimBase* _s0 = &s0; - ShapeSimBase* _s1 = &s1; - /* This tries to ensure that if one of the bodies is static or kinematic, it will be body B There is a further optimization to force all pairs that share the same bodies to have @@ -953,38 +188,80 @@ ShapeInteraction* NPhaseCore::createShapeInteraction(ShapeSimBase& s0, ShapeSimB If bodyA is rigidDynamic and bodyB is articulation, swap If bodyA is in an earlier BP group than bodyB, swap */ - { - ActorSim& rs0 = s0.getActor(); - ActorSim& rs1 = s1.getActor(); + // PT: some of these swaps are here to fulfill requirements from the solver code, and we + // will get asserts and failures without them. Some others are only optimizations. + + // PT: generally speaking we want the "static" actor to be second in the pair. + // "Static" can mean either: + // - a proper static body + // - a kinematic dynamic body + // - an articulation link with a fixed base + ActorSim& rs0 = s0.getActor(); + const PxActorType::Enum actorType0 = rs0.getActorType(); + if(actorType0 == PxActorType::eRIGID_STATIC) + return true; + + ActorSim& rs1 = s1.getActor(); + const PxActorType::Enum actorType1 = rs1.getActorType(); - const PxActorType::Enum actorType0 = rs0.getActorType(); - const PxActorType::Enum actorType1 = rs1.getActorType(); + const bool isDyna0 = actorType0 == PxActorType::eRIGID_DYNAMIC; + const bool isDyna1 = actorType1 == PxActorType::eRIGID_DYNAMIC; - bool articulationLinkSwap = false; - if (actorType0 == PxActorType::eARTICULATION_LINK && actorType1 == PxActorType::eARTICULATION_LINK) + if(actorType0 == PxActorType::eARTICULATION_LINK) + { + if(isDyna1 || actorType1 == PxActorType::eARTICULATION_LINK) { - BodySim& bodySim0 = static_cast(rs0); + if(static_cast(rs0).getLowLevelBody().mCore->fixedBaseLink) + return true; + } + } + else if(isDyna0) + { + // PT: this tries to implement this requirement: "If bodyA is rigidDynamic and bodyB is articulation, swap" + // But we do NOT do that if bodyB has a fixed base. It is unclear whether this particular swap is really needed. + if(actorType1 == PxActorType::eARTICULATION_LINK) + { + if(!static_cast(rs1).getLowLevelBody().mCore->fixedBaseLink) + return true; + } + } - const PxU8 kinematicLink0 = bodySim0.getLowLevelBody().mCore->kinematicLink; + // PT: initial code was: + // if((actorType0 == PxActorType::eRIGID_DYNAMIC && actorType1 == PxActorType::eRIGID_DYNAMIC) && actorAKinematic) + // But actorAKinematic true implies isDyna0 true, so this is equivalent to + // if(isDyna1 && actorAKinematic) + // And we only need actorAKinematic in this expression so it's faster to move its computation inside the if: + // if(isDyna1 && isDyna0 && static_cast(rs0).isKinematic()) + if(isDyna1 && isDyna0 && static_cast(rs0).isKinematic()) + return true; - if (kinematicLink0) - { - articulationLinkSwap = true; - } - } + // PT: initial code was: + // if(actorType0 == actorType1 && rs0.getActorID() < rs1.getActorID() && !actorBKinematic) + // We refactor the code a bit to avoid computing actorBKinematic. We could also test actorBKinematic + // first and avoid reading actor IDs. Unclear what's best, arbitrary choice for now. + if((actorType0 == actorType1) && (rs0.getActorID() < rs1.getActorID())) + { + const bool actorBKinematic = isDyna1 && static_cast(rs1).isKinematic(); + if(!actorBKinematic) + return true; + } - bool actorAKinematic = actorType0 == PxActorType::eRIGID_DYNAMIC && static_cast(rs0).isKinematic(); - bool actorBKinematic = actorType1 == PxActorType::eRIGID_DYNAMIC && static_cast(rs1).isKinematic(); +#if PX_SUPPORT_GPU_PHYSX + // PT: using rs0.isParticleSystem() instead of isParticleSystem(actorType0) is faster. + if(actorType1 != PxActorType::eRIGID_STATIC && rs0.isParticleSystem()) + return true; +#endif + return false; +} - if( actorType0 == PxActorType::eRIGID_STATIC - || (actorType1 == PxActorType::eRIGID_DYNAMIC && actorType0 == PxActorType::eARTICULATION_LINK) - || articulationLinkSwap - || (isParticleSystem(actorType0) && actorType1 != PxActorType::eRIGID_STATIC) - || ((actorType0 == PxActorType::eRIGID_DYNAMIC && actorType1 == PxActorType::eRIGID_DYNAMIC) && actorAKinematic) - || (actorType0 == actorType1 && rs0.getActorID() < rs1.getActorID() && !actorBKinematic)) - PxSwap(_s0, _s1); - } +ShapeInteraction* NPhaseCore::createShapeInteraction(ShapeSimBase& s0, ShapeSimBase& s1, PxPairFlags pairFlags, PxsContactManager* contactManager, ShapeInteraction* shapeInteraction) +{ + ShapeSimBase* _s0 = &s0; + ShapeSimBase* _s1 = &s1; + + if(shouldSwapBodies(s0, s1)) + PxSwap(_s0, _s1); ShapeInteraction* si = shapeInteraction ? shapeInteraction : mShapeInteractionPool.allocate(); PX_PLACEMENT_NEW(si, ShapeInteraction)(*_s0, *_s1, pairFlags, contactManager); @@ -1021,171 +298,6 @@ ElementInteractionMarker* NPhaseCore::createElementInteractionMarker(ElementSim& return pair; } -ElementSimInteraction* NPhaseCore::refilterInteraction(ElementSimInteraction* pair, const PxFilterInfo* filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs) -{ - const InteractionType::Enum oldType = pair->getType(); - - switch (oldType) - { - case InteractionType::eTRIGGER: - case InteractionType::eMARKER: - case InteractionType::eOVERLAP: - { - ShapeSimBase& s0 = static_cast(pair->getElement0()); - ShapeSimBase& s1 = static_cast(pair->getElement1()); - - PxFilterInfo finfo; - if(filterInfo) - { - // The filter changes are provided by an outside source (the user filter callback) - - finfo = *filterInfo; - PX_ASSERT(finfo.filterPairIndex!=INVALID_FILTER_PAIR_INDEX); - - if((finfo.filterFlags & PxFilterFlag::eKILL) && - ((finfo.filterFlags & PxFilterFlag::eNOTIFY) == PxFilterFlag::eNOTIFY) ) - { - callPairLost(mOwnerScene, pair->getElement0(), pair->getElement1(), finfo.filterPairIndex, false); - mFilterPairManager->releaseIndex(finfo.filterPairIndex); - finfo.filterPairIndex = INVALID_FILTER_PAIR_INDEX; - } - - ActorSim& bs0 = s0.getActor(); - ActorSim& bs1 = s1.getActor(); - finfo.pairFlags = checkRbPairFlags(s0, s1, bs0, bs1, finfo.pairFlags, finfo.filterFlags, s0.getActor().isNonRigid() || s1.getActor().isNonRigid()); - } - else - { - PxU32 filterPairIndex = INVALID_FILTER_PAIR_INDEX; - if(pair->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR)) - { - filterPairIndex = mFilterPairManager->findIndex(pair); - PX_ASSERT(filterPairIndex!=INVALID_FILTER_PAIR_INDEX); - - callPairLost(mOwnerScene, pair->getElement0(), pair->getElement1(), filterPairIndex, false); - } - - const FilteringContext context(mOwnerScene, mFilterPairManager); - - bool isTriggerPair; - finfo = filterRbCollisionPair(context, s0, s1, filterPairIndex, isTriggerPair, true); - PX_UNUSED(isTriggerPair); - } - - if(pair->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR) && - ((finfo.filterFlags & PxFilterFlag::eNOTIFY) != PxFilterFlag::eNOTIFY) ) - { - // The pair was a filter callback pair but not any longer - pair->clearInteractionFlag(InteractionFlag::eIS_FILTER_PAIR); - - if(finfo.filterPairIndex!=INVALID_FILTER_PAIR_INDEX) - { - mFilterPairManager->releaseIndex(finfo.filterPairIndex); - finfo.filterPairIndex = INVALID_FILTER_PAIR_INDEX; - } - } - - struct Local - { - static InteractionType::Enum getRbElementInteractionType(const ShapeSimBase* primitive0, const ShapeSimBase* primitive1, PxFilterFlags filterFlag) - { - if(filterFlag & PxFilterFlag::eKILL) - return InteractionType::eINVALID; - - if(filterFlag & PxFilterFlag::eSUPPRESS) - return InteractionType::eMARKER; - - if(primitive0->getFlags() & PxShapeFlag::eTRIGGER_SHAPE - || primitive1->getFlags() & PxShapeFlag::eTRIGGER_SHAPE) - return InteractionType::eTRIGGER; - - PX_ASSERT( (primitive0->getGeometryType() != PxGeometryType::eTRIANGLEMESH) || - (primitive1->getGeometryType() != PxGeometryType::eTRIANGLEMESH)); - - return InteractionType::eOVERLAP; - } - }; - - const InteractionType::Enum newType = Local::getRbElementInteractionType(&s0, &s1, finfo.filterFlags); - if(pair->getType() != newType) //Only convert interaction type if the type has changed - { - return convert(pair, newType, finfo, removeFromDirtyList, outputs); - } - else - { - //The pair flags might have changed, we need to forward the new ones - if(oldType == InteractionType::eOVERLAP) - { - ShapeInteraction* si = static_cast(pair); - - const PxU32 newPairFlags = finfo.pairFlags; - const PxU32 oldPairFlags = si->getPairFlags(); - PX_ASSERT((newPairFlags & ShapeInteraction::PAIR_FLAGS_MASK) == newPairFlags); - PX_ASSERT((oldPairFlags & ShapeInteraction::PAIR_FLAGS_MASK) == oldPairFlags); - - if(newPairFlags != oldPairFlags) - { - if(!(oldPairFlags & ShapeInteraction::CONTACT_REPORT_EVENTS) && (newPairFlags & ShapeInteraction::CONTACT_REPORT_EVENTS) && (si->getActorPair() == NULL || !si->getActorPair()->isReportPair())) - { - // for this actor pair there was no shape pair that requested contact reports but now there is one - // -> all the existing shape pairs need to get re-adjusted to point to an ActorPairReport instance instead. - ActorPair* actorPair = findActorPair(&s0, &s1, PxIntTrue); - if (si->getActorPair() == NULL) - { - actorPair->incRefCount(); - si->setActorPair(*actorPair); - } - } - - if(si->readFlag(ShapeInteraction::IN_PERSISTENT_EVENT_LIST) && (!(newPairFlags & PxPairFlag::eNOTIFY_TOUCH_PERSISTS))) - { - // the new report pair flags don't require persistent checks anymore -> remove from persistent list - // Note: The pair might get added to the force threshold list later - if(si->readFlag(ShapeInteraction::IS_IN_PERSISTENT_EVENT_LIST)) - removeFromPersistentContactEventPairs(si); - else - si->clearFlag(ShapeInteraction::WAS_IN_PERSISTENT_EVENT_LIST); - } - - if(newPairFlags & ShapeInteraction::CONTACT_FORCE_THRESHOLD_PAIRS) - { - PX_ASSERT((si->mReportPairIndex == INVALID_REPORT_PAIR_ID) || (!si->readFlag(ShapeInteraction::WAS_IN_PERSISTENT_EVENT_LIST))); - - if(si->mReportPairIndex == INVALID_REPORT_PAIR_ID && si->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) - { - PX_ASSERT(!si->readFlag(ShapeInteraction::WAS_IN_PERSISTENT_EVENT_LIST)); // sanity check: an active pair should never have this flag set - - if(si->hasTouch()) - addToForceThresholdContactEventPairs(si); - } - } - else if((oldPairFlags & ShapeInteraction::CONTACT_FORCE_THRESHOLD_PAIRS)) - { - // no force threshold events needed any longer -> clear flags - si->clearFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_FLAGS); - - if(si->readFlag(ShapeInteraction::IS_IN_FORCE_THRESHOLD_EVENT_LIST)) - removeFromForceThresholdContactEventPairs(si); - } - } - si->setPairFlags(finfo.pairFlags); - } - else if(oldType == InteractionType::eTRIGGER) - static_cast(pair)->setTriggerFlags(finfo.pairFlags); - - return pair; - } - } - case InteractionType::eCONSTRAINTSHADER: - case InteractionType::eARTICULATION: - case InteractionType::eTRACKED_IN_SCENE_COUNT: - case InteractionType::eINVALID: - PX_ASSERT(0); - break; - } - return NULL; -} - ActorPair* NPhaseCore::findActorPair(ShapeSimBase* s0, ShapeSimBase* s1, PxIntBool isReportPair) { PX_ASSERT(!(s0->getFlags() & PxShapeFlag::eTRIGGER_SHAPE) @@ -1254,7 +366,7 @@ PX_FORCE_INLINE void NPhaseCore::destroyActorPairReport(ActorPairReport& aPair) mActorPairReportPool.destroy(&aPair); } -ElementSimInteraction* NPhaseCore::convert(ElementSimInteraction* pair, InteractionType::Enum newType, PxFilterInfo& filterInfo, bool removeFromDirtyList, +ElementSimInteraction* NPhaseCore::convert(ElementSimInteraction* pair, InteractionType::Enum newType, FilterInfo& filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs) { PX_ASSERT(newType != pair->getType()); @@ -1306,7 +418,7 @@ ElementSimInteraction* NPhaseCore::convert(ElementSimInteraction* pair, Interact break; }; - if(filterInfo.filterPairIndex != INVALID_FILTER_PAIR_INDEX) + if(filterInfo.hasPairID) { PX_ASSERT(result); // If a filter callback pair is going to get killed, then the FilterPair struct should already have @@ -1314,9 +426,6 @@ ElementSimInteraction* NPhaseCore::convert(ElementSimInteraction* pair, Interact // Mark the new interaction as a filter callback pair result->raiseInteractionFlag(InteractionFlag::eIS_FILTER_PAIR); - - mFilterPairManager->setPair(filterInfo.filterPairIndex, result); - result->setFilterPairIndex(filterInfo.filterPairIndex); } return result; } @@ -1436,21 +545,19 @@ static bool findTriggerContacts(TriggerInteraction* tri, bool toBeDeleted, bool class TriggerContactTask : public Cm::Task { -private: - TriggerContactTask& operator = (const TriggerContactTask&); - + PX_NOCOPY(TriggerContactTask) public: - TriggerContactTask(Interaction* const* triggerPairs, PxU32 triggerPairCount, PxMutex& lock, + TriggerContactTask(ElementSimInteraction* const* triggerPairs, PxU32 triggerPairCount, PxMutex& lock, TriggerInteraction** pairsToDeactivate, volatile PxI32& pairsToDeactivateCount, - Scene& scene, PxsTransformCache& transformCache): - Cm::Task(scene.getContextId()), - mTriggerPairs(triggerPairs), - mTriggerPairCount(triggerPairCount), - mLock(lock), - mPairsToDeactivate(pairsToDeactivate), - mPairsToDeactivateCount(pairsToDeactivateCount), - mScene(scene), - mTransformCache(transformCache) + Scene& scene, PxsTransformCache& transformCache) : + Cm::Task (scene.getContextId()), + mTriggerPairs (triggerPairs), + mTriggerPairCount (triggerPairCount), + mLock (lock), + mPairsToDeactivate (pairsToDeactivate), + mPairsToDeactivateCount (pairsToDeactivateCount), + mScene (scene), + mTransformCache (transformCache) { } @@ -1469,7 +576,6 @@ class TriggerContactTask : public Cm::Task TriggerInteraction* deactivatePairs[sTriggerPairsPerTask]; PxI32 deactivatePairCount = 0; - for(PxU32 i=0; i < mTriggerPairCount; i++) { TriggerInteraction* tri = static_cast(mTriggerPairs[i]); @@ -1492,7 +598,7 @@ class TriggerContactTask : public Cm::Task // explicitly scheduled overlap test is done (after object creation, teleport, ...). Check if trigger pair should remain active or not. - if(!tri->onActivate_(0)) + if(!tri->onActivate(0)) { PX_ASSERT(tri->readInteractionFlag(InteractionFlag::eIS_ACTIVE)); // Why is the assert enough? @@ -1550,13 +656,13 @@ class TriggerContactTask : public Cm::Task static const PxU32 sTriggerPairsPerTask = 64; private: - Interaction* const* mTriggerPairs; - const PxU32 mTriggerPairCount; - PxMutex& mLock; - TriggerInteraction** mPairsToDeactivate; - volatile PxI32& mPairsToDeactivateCount; - Scene& mScene; - PxsTransformCache& mTransformCache; + ElementSimInteraction* const* mTriggerPairs; + const PxU32 mTriggerPairCount; + PxMutex& mLock; + TriggerInteraction** mPairsToDeactivate; + volatile PxI32& mPairsToDeactivateCount; + Scene& mScene; + PxsTransformCache& mTransformCache; }; } // namespace Sc @@ -1570,9 +676,10 @@ void NPhaseCore::processTriggerInteractions(PxBaseTask* continuation) Scene& scene = mOwnerScene; // Triggers - Interaction** triggerInteractions = mOwnerScene.getActiveInteractions(InteractionType::eTRIGGER); + ElementSimInteraction** triggerInteractions = mOwnerScene.getActiveInteractions(InteractionType::eTRIGGER); const PxU32 pairCount = mOwnerScene.getNbActiveInteractions(InteractionType::eTRIGGER); + // PT: TASK-CREATION TAG if(pairCount > 0) { const PxU32 taskCountWithoutRemainder = pairCount / TriggerContactTask::sTriggerPairsPerTask; @@ -1582,7 +689,7 @@ void NPhaseCore::processTriggerInteractions(PxBaseTask* continuation) void* triggerProcessingBlock = scene.getLowLevelContext()->getScratchAllocator().alloc(memBlockSize, true); if(triggerProcessingBlock) { - const bool hasMultipleThreads = scene.getTaskManager().getCpuDispatcher()->getWorkerCount() > 1; + const bool hasMultipleThreads = continuation && scene.getTaskManager().getCpuDispatcher()->getWorkerCount() > 1; const bool moreThanOneBatch = pairCount > TriggerContactTask::sTriggerPairsPerTask; const bool scheduleTasks = hasMultipleThreads && moreThanOneBatch; // when running on a single thread, the task system seems to cause the main overhead (locking and atomic operations @@ -1646,29 +753,6 @@ void NPhaseCore::mergeProcessedTriggerInteractions(PxBaseTask*) } } -void NPhaseCore::visualize(PxRenderOutput& renderOut, PxsContactManagerOutputIterator& outputs) -{ - // PT: put common reads here to avoid doing them for each interaction - - const PxReal scale = mOwnerScene.getVisualizationScale(); - if(scale == 0.0f) - return; - - const PxReal param_contactForce = mOwnerScene.getVisualizationParameter(PxVisualizationParameter::eCONTACT_FORCE); - const PxReal param_contactNormal = mOwnerScene.getVisualizationParameter(PxVisualizationParameter::eCONTACT_NORMAL); - const PxReal param_contactError = mOwnerScene.getVisualizationParameter(PxVisualizationParameter::eCONTACT_ERROR); - const PxReal param_contactPoint = mOwnerScene.getVisualizationParameter(PxVisualizationParameter::eCONTACT_POINT); - - if(param_contactForce==0.0f && param_contactNormal==0.0f && param_contactError==0.0f && param_contactPoint==0.0f) - return; - - Interaction** interactions = mOwnerScene.getActiveInteractions(InteractionType::eOVERLAP); - PxU32 nbActiveInteractions = mOwnerScene.getNbActiveInteractions(InteractionType::eOVERLAP); - while(nbActiveInteractions--) - static_cast(*interactions++)->visualize( renderOut, outputs, - scale, param_contactForce, param_contactNormal, param_contactError, param_contactPoint); -} - #ifdef REMOVED class ProcessPersistentContactTask : public Cm::Task { @@ -1744,10 +828,8 @@ class ProcessPersistentContactTask : public Cm::Task }; #endif -void NPhaseCore::processPersistentContactEvents(PxsContactManagerOutputIterator& outputs, PxBaseTask* continuation) +void NPhaseCore::processPersistentContactEvents(PxsContactManagerOutputIterator& outputs) { - PX_UNUSED(continuation); - PX_UNUSED(outputs); PX_PROFILE_ZONE("Sc::NPhaseCore::processPersistentContactEvents", mOwnerScene.getContextId()); // Go through ShapeInteractions which requested persistent contact event reports. This is necessary since there are no low level events for persistent contact. @@ -1784,46 +866,6 @@ void NPhaseCore::processPersistentContactEvents(PxsContactManagerOutputIterator& } } -void NPhaseCore::fireCustomFilteringCallbacks(PxsContactManagerOutputIterator& outputs) -{ - PX_PROFILE_ZONE("Sim.fireCustomFilteringCallbacks", mOwnerScene.getContextId()); - - PxSimulationFilterCallback* callback = mOwnerScene.getFilterCallbackFast(); - - if(callback) - { - // Ask user for pair filter status changes - PxU32 pairID; - PxFilterFlags filterFlags; - PxPairFlags pairFlags; - while(callback->statusChange(pairID, pairFlags, filterFlags)) - { - ElementSimInteraction* ei = (*mFilterPairManager)[pairID]; - - PX_ASSERT(ei); - // Check if the user tries to update a pair even though he deleted it earlier in the same frame - - checkFilterFlags(filterFlags); - - PX_ASSERT(ei->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR)); - - PxFilterInfo finfo; - finfo.filterFlags = filterFlags; - finfo.pairFlags = pairFlags; - finfo.filterPairIndex = pairID; - - ElementSimInteraction* refInt = refilterInteraction(ei, &finfo, true, outputs); - - // this gets called at the end of the simulation -> there should be no dirty interactions around - PX_ASSERT(!refInt->readInteractionFlag(InteractionFlag::eIN_DIRTY_LIST)); - PX_ASSERT(!refInt->getDirtyFlags()); - - if((refInt == ei) && (refInt->getType() == InteractionType::eOVERLAP)) // No interaction conversion happened, the pairFlags were just updated - static_cast(refInt)->updateState(InteractionDirtyFlag::eFILTER_STATE); - } - } -} - void NPhaseCore::addToDirtyInteractionList(Interaction* pair) { mDirtyInteractions.insert(pair); @@ -1840,19 +882,19 @@ void NPhaseCore::updateDirtyInteractions(PxsContactManagerOutputIterator& output { // The sleeping SIs will be updated on activation // clow: Sleeping SIs are not awaken for visualization updates - const bool dirtyDominance = mOwnerScene.readFlag(SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_DOMINANCE); - const bool dirtyVisualization = mOwnerScene.readFlag(SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_VISUALIZATION); + const bool dirtyDominance = mOwnerScene.readInternalFlag(SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_DOMINANCE); + const bool dirtyVisualization = mOwnerScene.readInternalFlag(SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_VISUALIZATION); if(dirtyDominance || dirtyVisualization) { // Update all interactions. const PxU8 mask = PxTo8((dirtyDominance ? InteractionDirtyFlag::eDOMINANCE : 0) | (dirtyVisualization ? InteractionDirtyFlag::eVISUALIZATION : 0)); - Interaction** it = mOwnerScene.getInteractions(InteractionType::eOVERLAP); + ElementSimInteraction** it = mOwnerScene.getInteractions(InteractionType::eOVERLAP); PxU32 size = mOwnerScene.getNbInteractions(InteractionType::eOVERLAP); while(size--) { - Interaction* pair = *it++; + ElementSimInteraction* pair = *it++; PX_ASSERT(pair->getType() == InteractionType::eOVERLAP); @@ -1896,20 +938,17 @@ void NPhaseCore::updateDirtyInteractions(PxsContactManagerOutputIterator& output mDirtyInteractions.clear(); } -void NPhaseCore::releaseElementPair(ElementSimInteraction* pair, PxU32 flags, ElementSim* removedElement, const PxU32 ccdPass, bool removeFromDirtyList, - PxsContactManagerOutputIterator& outputs) +void NPhaseCore::releaseElementPair(ElementSimInteraction* pair, PxU32 flags, ElementSim* removedElement, PxU32 ccdPass, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs) { pair->setClean(removeFromDirtyList); // Removes the pair from the dirty interaction list etc. if(pair->readInteractionFlag(InteractionFlag::eIS_FILTER_PAIR)) { // Check if this is a filter callback pair - const PxU32 filterPairIndex = mFilterPairManager->findIndex(pair); - PX_ASSERT(filterPairIndex!=INVALID_FILTER_PAIR_INDEX); - - callPairLost(mOwnerScene, pair->getElement0(), pair->getElement1(), filterPairIndex, (removedElement != NULL)); + ShapeSimBase& s0 = static_cast(pair->getElement0()); + ShapeSimBase& s1 = static_cast(pair->getElement1()); - mFilterPairManager->releaseIndex(filterPairIndex); + callPairLost(s0, s1, removedElement != NULL); } switch(pair->getType()) @@ -1956,8 +995,7 @@ void NPhaseCore::releaseElementPair(ElementSimInteraction* pair, PxU32 flags, El } } -void NPhaseCore::lostTouchReports(ShapeInteraction* si, PxU32 flags, ElementSim* removedElement, PxU32 ccdPass, - PxsContactManagerOutputIterator& outputs) +void NPhaseCore::lostTouchReports(ShapeInteraction* si, PxU32 flags, ElementSim* removedElement, PxU32 ccdPass, PxsContactManagerOutputIterator& outputs) { if(si->hasTouch()) { diff --git a/physx/source/simulationcontroller/src/ScNPhaseCore.h b/physx/source/simulationcontroller/src/ScNPhaseCore.h index e5272b26a..3b4e395d2 100644 --- a/physx/source/simulationcontroller/src/ScNPhaseCore.h +++ b/physx/source/simulationcontroller/src/ScNPhaseCore.h @@ -29,7 +29,6 @@ #ifndef SC_NPHASE_CORE_H #define SC_NPHASE_CORE_H -#include "common/PxRenderOutput.h" #include "foundation/PxHash.h" #include "foundation/PxUserAllocated.h" #include "foundation/PxHashSet.h" @@ -45,8 +44,6 @@ #include "ScScene.h" #include "ScContactReportBuffer.h" - - namespace physx { namespace Bp @@ -91,8 +88,7 @@ namespace Sc }; /* - Description: NPhaseCore encapsulates the near phase processing to allow multiple implementations(eg threading and non - threaded). + NPhaseCore encapsulates the near phase processing to allow multiple implementations(eg threading and non threaded). The broadphase inserts shape pairs into the NPhaseCore, which are then processed into contact point streams. Pairs can then be processed into AxisConstraints by the GroupSolveCore. @@ -118,33 +114,26 @@ namespace Sc struct ElementSimKey { - ElementSim* mSim0, *mSim1; + PxU32 mID0; + PxU32 mID1; - ElementSimKey() : mSim0(NULL), mSim1(NULL) + ElementSimKey() : mID0(0xffffffff), mID1(0xffffffff) {} - ElementSimKey(ElementSim* sim0, ElementSim* sim1) + ElementSimKey(PxU32 id0, PxU32 id1) { - if(sim0 > sim1) - PxSwap(sim0, sim1); - mSim0 = sim0; - mSim1 = sim1; + if(id0 > id1) + PxSwap(id0, id1); + mID0 = id0; + mID1 = id1; } - PX_FORCE_INLINE bool operator == (const ElementSimKey& pair) const { return mSim0 == pair.mSim0 && mSim1 == pair.mSim1; } + PX_FORCE_INLINE bool operator == (const ElementSimKey& pair) const { return mID0 == pair.mID0 && mID1 == pair.mID1; } }; PX_INLINE PxU32 PxComputeHash(const ElementSimKey& key) { - PxU32 add0 = (size_t(key.mSim0)) & 0xFFFFFFFF; - PxU32 add1 = (size_t(key.mSim1)) & 0xFFFFFFFF; - - //Clear the lower 2 bits, they will be 0s anyway - add0 = add0 >> 2; - add1 = add1 >> 2; - - const PxU32 base = PxU32((add0 & 0xFFFF) | (add1 << 16)); - + const PxU64 base = PxU64(key.mID0) | (PxU64(key.mID1) << 32); return physx::PxComputeHash(base); } @@ -165,10 +154,10 @@ namespace Sc { } - PxU8* allocate(const PxU32 size, PxU32& index, PxU32 alignment = 16u) + PxU8* allocate(PxU32 size, PxU32& index, PxU32 alignment = 16u) { //(1) fix up offsets... - PxU32 pad = ((mCurrentBufferIndex + alignment - 1)&~(alignment - 1)) - mCurrentBufferIndex; + const PxU32 pad = ((mCurrentBufferIndex + alignment - 1)&~(alignment - 1)) - mCurrentBufferIndex; PxU32 currOffset = mCurrentOffset + pad; if ((currOffset + size) > mBufferSize) @@ -197,13 +186,14 @@ namespace Sc NPhaseCore(Scene& scene, const PxSceneDesc& desc); ~NPhaseCore(); + ElementSimInteraction* findInteraction(const ElementSim* element0, const ElementSim* element1); + void onTriggerOverlapCreated(const Bp::AABBOverlap* PX_RESTRICT pairs, PxU32 pairCount); - void runOverlapFilters( PxU32 nbToProcess, const Bp::AABBOverlap* PX_RESTRICT pairs, PxFilterInfo* PX_RESTRICT filterInfo, - PxU32& nbToKeep, PxU32& nbToSuppress, PxU32& nbToCallback, PxU32* PX_RESTRICT keepMap, PxU32* PX_RESTRICT callbackMap); + void runOverlapFilters( PxU32 nbToProcess, const Bp::AABBOverlap* PX_RESTRICT pairs, FilterInfo* PX_RESTRICT filterInfo, + PxU32& nbToKeep, PxU32& nbToSuppress, PxU32* PX_RESTRICT keepMap); - ElementSimInteraction* onOverlapRemovedStage1(ElementSim* volume0, ElementSim* volume1); - void onOverlapRemoved(ElementSim* volume0, ElementSim* volume1, const PxU32 ccdPass, void* elemSim, PxsContactManagerOutputIterator& outputs); + void onOverlapRemoved(ElementSim* volume0, ElementSim* volume1, PxU32 ccdPass, void* elemSim, PxsContactManagerOutputIterator& outputs); void onVolumeRemoved(ElementSim* volume, PxU32 flags, PxsContactManagerOutputIterator& outputs); void managerNewTouch(Sc::ShapeInteraction& interaction); @@ -216,27 +206,14 @@ namespace Sc void removeFromDirtyInteractionList(Interaction* interaction); void updateDirtyInteractions(PxsContactManagerOutputIterator& outputs); - /* - Description: Perform trigger overlap tests. - */ + // Perform trigger overlap tests. void processTriggerInteractions(PxBaseTask* continuation); - /* - Description: Gather results from trigger overlap tests and clean up. - */ + // Gather results from trigger overlap tests and clean up. void mergeProcessedTriggerInteractions(PxBaseTask* continuation); - /* - Description: Check candidates for persistent touch contact events and create those events if necessary. - */ - void processPersistentContactEvents(PxsContactManagerOutputIterator& outputs, PxBaseTask* continuation); - - /* - Description: Displays visualizations associated with the near phase. - */ - void visualize(PxRenderOutput& out, PxsContactManagerOutputIterator& outputs); - - PX_FORCE_INLINE Scene& getScene() const { return mOwnerScene; } + // Check candidates for persistent touch contact events and create those events if necessary. + void processPersistentContactEvents(PxsContactManagerOutputIterator& outputs); PX_FORCE_INLINE void addToContactReportActorPairSet(ActorPairReport* pair) { mContactReportActorPairSet.pushBack(pair); } void clearContactReportActorPairs(bool shrinkToZero); @@ -247,7 +224,6 @@ namespace Sc void addToPersistentContactEventPairsDelayed(ShapeInteraction*); void removeFromPersistentContactEventPairs(ShapeInteraction*); - PX_FORCE_INLINE PxU32 getCurrentPersistentContactEventPairCount() const { return mNextFramePersistentContactEventPairIndex; } PX_FORCE_INLINE ShapeInteraction* const* getCurrentPersistentContactEventPairs() const { return mPersistentContactEventPairList.begin(); } PX_FORCE_INLINE PxU32 getAllPersistentContactEventPairCount() const { return mPersistentContactEventPairList.size(); } @@ -257,7 +233,6 @@ namespace Sc void addToForceThresholdContactEventPairs(ShapeInteraction*); void removeFromForceThresholdContactEventPairs(ShapeInteraction*); - PX_FORCE_INLINE PxU32 getForceThresholdContactEventPairCount() const { return mForceThresholdContactEventPairList.size(); } PX_FORCE_INLINE ShapeInteraction* const* getForceThresholdContactEventPairs() const { return mForceThresholdContactEventPairList.begin(); } @@ -270,26 +245,25 @@ namespace Sc ActorPairContactReportData* createActorPairContactReportData(); void releaseActorPairContactReportData(ActorPairContactReportData* data); - void reserveInteraction(PxU32 nbNewInteractions); void registerInteraction(ElementSimInteraction* interaction); void unregisterInteraction(ElementSimInteraction* interaction); - ElementSimInteraction* createRbElementInteraction(const PxFilterInfo& fInfo, ShapeSimBase& s0, ShapeSimBase& s1, PxsContactManager* contactManager, Sc::ShapeInteraction* shapeInteraction, + ElementSimInteraction* createRbElementInteraction(const FilterInfo& fInfo, ShapeSimBase& s0, ShapeSimBase& s1, PxsContactManager* contactManager, Sc::ShapeInteraction* shapeInteraction, Sc::ElementInteractionMarker* interactionMarker, bool isTriggerPair); void lockReports() { mReportAllocLock.lock(); } void unlockReports() { mReportAllocLock.unlock(); } - private: + void callPairLost(const ShapeSimBase& s0, const ShapeSimBase& s1, bool objVolumeRemoved); + ElementSimInteraction* createTriggerElementInteraction(ShapeSimBase& s0, ShapeSimBase& s1); - // // removedElement: points to the removed element (that is, the BP volume wrapper), if a pair gets removed or loses touch due to a removed element. // NULL if not triggered by a removed element. // - void releaseElementPair(ElementSimInteraction* pair, PxU32 flags, ElementSim* removedElement, const PxU32 ccdPass, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs); - void lostTouchReports(ShapeInteraction* pair, PxU32 flags, ElementSim* removedElement, const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs); + void releaseElementPair(ElementSimInteraction* pair, PxU32 flags, ElementSim* removedElement, PxU32 ccdPass, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs); + void lostTouchReports(ShapeInteraction* pair, PxU32 flags, ElementSim* removedElement, PxU32 ccdPass, PxsContactManagerOutputIterator& outputs); ShapeInteraction* createShapeInteraction(ShapeSimBase& s0, ShapeSimBase& s1, PxPairFlags pairFlags, PxsContactManager* contactManager, Sc::ShapeInteraction* shapeInteraction); TriggerInteraction* createTriggerInteraction(ShapeSimBase& s0, ShapeSimBase& s1, PxPairFlags triggerFlags); @@ -297,34 +271,31 @@ namespace Sc //------------- Filtering ------------- - ElementSimInteraction* refilterInteraction(ElementSimInteraction* pair, const PxFilterInfo* filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs); + ElementSimInteraction* refilterInteraction(ElementSimInteraction* pair, const FilterInfo* filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs); //------------------------------------- - ElementSimInteraction* convert(ElementSimInteraction* pair, InteractionType::Enum type, PxFilterInfo& filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs); + ElementSimInteraction* convert(ElementSimInteraction* pair, InteractionType::Enum type, FilterInfo& filterInfo, bool removeFromDirtyList, PxsContactManagerOutputIterator& outputs); ActorPair* findActorPair(ShapeSimBase* s0, ShapeSimBase* s1, PxIntBool isReportPair); PX_FORCE_INLINE void destroyActorPairReport(ActorPairReport&); - Sc::ElementSimInteraction* findInteraction(ElementSim* _element0, ElementSim* _element1); - // Pooling Scene& mOwnerScene; PxArray mContactReportActorPairSet; PxArray mPersistentContactEventPairList; // Pairs which request events which do not get triggered by the sdk and thus need to be tested actively every frame. - // May also contain force threshold event pairs (see mForceThresholdContactEventPairList) - // This list is split in two, the elements in front are for the current frame, the elements at the - // back will get added next frame. + // May also contain force threshold event pairs (see mForceThresholdContactEventPairList) + // This list is split in two, the elements in front are for the current frame, the elements at the + // back will get added next frame. PxU32 mNextFramePersistentContactEventPairIndex; // start index of the pairs which need to get added to the persistent list for next frame PxArray mForceThresholdContactEventPairList; // Pairs which request force threshold contact events. A pair is only in this list if it does have contact. - // Note: If a pair additionally requests PxPairFlag::eNOTIFY_TOUCH_PERSISTS events, then it - // goes into mPersistentContactEventPairList instead. This allows to share the list index. + // Note: If a pair additionally requests PxPairFlag::eNOTIFY_TOUCH_PERSISTS events, then it + // goes into mPersistentContactEventPairList instead. This allows to share the list index. - // // data layout: // ContactActorPair0_ExtraData, ContactShapePair0_0, ContactShapePair0_1, ... ContactShapePair0_N, // ContactActorPair1_ExtraData, ContactShapePair1_0, ... @@ -332,8 +303,6 @@ namespace Sc ContactReportBuffer mContactReportBuffer; // Shape pair information for contact reports PxCoalescedHashSet mDirtyInteractions; - FilterPairManager* mFilterPairManager; - // Pools PxPool mActorPairPool; PxPool mActorPairReportPool; @@ -361,12 +330,11 @@ namespace Sc { PX_NOCOPY(FilteringContext) public: - FilteringContext(const Sc::Scene& scene, FilterPairManager* filterPairManager) : + FilteringContext(const Sc::Scene& scene) : mFilterShader (scene.getFilterShaderFast()), mFilterShaderData (scene.getFilterShaderDataFast()), mFilterShaderDataSize (scene.getFilterShaderDataSizeFast()), mFilterCallback (scene.getFilterCallbackFast()), - mFilterPairManager (filterPairManager), mKineKineFilteringMode (scene.getKineKineFilteringMode()), mStaticKineFilteringMode(scene.getStaticKineFilteringMode()) { @@ -376,18 +344,12 @@ namespace Sc const void* mFilterShaderData; PxU32 mFilterShaderDataSize; PxSimulationFilterCallback* mFilterCallback; - FilterPairManager* mFilterPairManager; const PxPairFilteringMode::Enum mKineKineFilteringMode; const PxPairFilteringMode::Enum mStaticKineFilteringMode; }; - // helper function to run the filter logic after some hardwired filter criteria have been passed successfully - PxFilterInfo filterRbCollisionPairSecondStage(const FilteringContext& context, const ShapeSimBase& s0, const ShapeSimBase& s1, const Sc::ActorSim& b0, const Sc::ActorSim& b1, PxU32 filterPairIndex, bool runCallbacks, - bool isNonRigid); - } // namespace Sc - PX_FORCE_INLINE void Sc::NPhaseCore::preparePersistentContactEventListForNextFrame() { // reports have been processed -> "activate" next frame candidates for persistent contact events diff --git a/physx/source/simulationcontroller/src/ScParticleSystemCore.cpp b/physx/source/simulationcontroller/src/ScParticleSystemCore.cpp index 6fe9596df..7079734fe 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemCore.cpp +++ b/physx/source/simulationcontroller/src/ScParticleSystemCore.cpp @@ -148,15 +148,6 @@ void Sc::ParticleSystemCore::setParticleSystemCallback(PxParticleSystemCallback* mShapeCore.getLLCore().mCallback = callback; } -PxCustomParticleSystemSolverCallback* Sc::ParticleSystemCore::getParticleSystemSolverCallback() const -{ - return mShapeCore.getLLCore().mSolverCallback; -} -void Sc::ParticleSystemCore::setParticleSystemSolverCallback(PxCustomParticleSystemSolverCallback* callback) -{ - mShapeCore.getLLCore().mSolverCallback = callback; -} - PxReal Sc::ParticleSystemCore::getFluidBoundaryDensityScale() const { return mShapeCore.getLLCore().fluidBoundaryDensityScale; diff --git a/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.cpp b/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.cpp index 963b91683..32ebb7851 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.cpp +++ b/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.cpp @@ -86,7 +86,6 @@ ParticleSystemShapeCore::ParticleSystemShapeCore() mLLCore.solverIterationCounts = (1 << 8) | 4; mLLCore.mWind = PxVec3(0.f); - mLLCore.periodicBoundary = PxVec3(0.f); //mLLCore.mNumUpdateSprings = 0; diff --git a/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.h b/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.h index fa41bbcb6..0fe6a4628 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.h +++ b/physx/source/simulationcontroller/src/ScParticleSystemShapeCore.h @@ -27,6 +27,8 @@ #ifndef SC_PARTICLESYSTEM_SHAPECORE_H #define SC_PARTICLESYSTEM_SHAPECORE_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "foundation/PxUserAllocated.h" #include "PxvGeometry.h" #include "foundation/PxUtilities.h" @@ -46,12 +48,6 @@ namespace physx class ParticleSystemShapeCore : public Sc::ShapeCore { - //= 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. - //================================================================================================== public: // PX_SERIALIZATION ParticleSystemShapeCore(const PxEMPTY); @@ -69,9 +65,6 @@ namespace physx void addParticleBuffer(PxParticleBuffer* particleBuffer); void removeParticleBuffer(PxParticleBuffer* particleBuffer); - void setPeriodicBoundary(const PxVec3& boundary) { mLLCore.periodicBoundary = boundary; } - PxVec3 getPeriodicBoundary() const { return mLLCore.periodicBoundary; } - PxU64 getGpuMemStat() { return mGpuMemStat; } protected: @@ -80,8 +73,7 @@ namespace physx }; } // namespace Sc - - } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.cpp b/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.cpp index 3b1ae81f3..9b7176094 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.cpp +++ b/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.cpp @@ -115,7 +115,7 @@ void Sc::ParticleSystemShapeSim::createLowLevelVolume() getScene().getAABBManager()->reserveSpaceForBounds(index); { - const PxU32 group = Bp::FilterGroup::ePARTICLES; + const PxU32 group = Bp::FilterGroup::eDYNAMICS_BASE + getActor().getActorID(); const PxU32 type = Bp::FilterType::PARTICLESYSTEM; const PxReal contactOffset = getBodySim().getCore().getContactOffset(); addToAABBMgr(contactOffset, Bp::FilterGroup::Enum((group << BP_FILTERING_TYPE_SHIFT_BIT) | type), Bp::ElementType::eSHAPE); diff --git a/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.h b/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.h index 7212d58ac..001a4d21b 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.h +++ b/physx/source/simulationcontroller/src/ScParticleSystemShapeSim.h @@ -27,12 +27,13 @@ #ifndef SC_PARTICLESYSTEM_SHAPE_SIM_H #define SC_PARTICLESYSTEM_SHAPE_SIM_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxPhysXConfig.h" #include "ScElementSim.h" #include "ScShapeSimBase.h" - namespace physx { namespace Sc @@ -67,7 +68,7 @@ namespace physx }; } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScParticleSystemSim.cpp b/physx/source/simulationcontroller/src/ScParticleSystemSim.cpp index 08baaebe8..2ffc70411 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemSim.cpp +++ b/physx/source/simulationcontroller/src/ScParticleSystemSim.cpp @@ -38,8 +38,7 @@ using namespace physx::Dy; Sc::ParticleSystemSim::ParticleSystemSim(ParticleSystemCore& core, Scene& scene) : ActorSim(scene, core), - mShapeSim(*this, &core.getShapeCore()), - mNumCountedInteractions(0) + mShapeSim(*this, &core.getShapeCore()) { mLLParticleSystem = scene.createLLParticleSystem(this); @@ -99,13 +98,7 @@ void Sc::ParticleSystemSim::sleepCheck(PxReal dt) PX_UNUSED(dt); } -void Sc::ParticleSystemSim::setActive(const bool b, const PxU32 infoFlag) -{ - PX_UNUSED(b); - PX_UNUSED(infoFlag); -} - -void Sc::ParticleSystemSim::activate() +/*void Sc::ParticleSystemSim::activate() { activateInteractions(*this); } @@ -113,6 +106,6 @@ void Sc::ParticleSystemSim::activate() void Sc::ParticleSystemSim::deactivate() { deactivateInteractions(*this); -} +}*/ #endif //PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/simulationcontroller/src/ScParticleSystemSim.h b/physx/source/simulationcontroller/src/ScParticleSystemSim.h index ace0669cf..8178364bf 100644 --- a/physx/source/simulationcontroller/src/ScParticleSystemSim.h +++ b/physx/source/simulationcontroller/src/ScParticleSystemSim.h @@ -27,6 +27,8 @@ #ifndef SC_PARTICLESYSTEM_SIM_H #define SC_PARTICLESYSTEM_SIM_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "foundation/PxUserAllocated.h" #include "ScActorSim.h" #include "ScParticleSystemCore.h" @@ -40,9 +42,9 @@ namespace physx class ParticleSystemSim : public ActorSim { + PX_NOCOPY(ParticleSystemSim) public: ParticleSystemSim(ParticleSystemCore& core, Scene& scene); - ~ParticleSystemSim(); PX_INLINE Dy::ParticleSystem* getLowLevelParticleSystem() const { return mLLParticleSystem; } @@ -58,31 +60,23 @@ namespace physx bool isActive() const { return true; } void sleepCheck(PxReal dt); - void setActive(const bool b, const PxU32 infoFlag = 0); + void setActive(bool active, bool asPartOfCreation=false); const ParticleSystemShapeSim& getShapeSim() const { return mShapeSim; } ParticleSystemShapeSim& getShapeSim() { return mShapeSim; } - virtual void registerCountedInteraction() { mNumCountedInteractions++; } - virtual void unregisterCountedInteraction() { mNumCountedInteractions--; } - virtual PxU32 getNumCountedInteractions() const { return mNumCountedInteractions; } - - virtual void activate(); - virtual void deactivate(); - private: - ParticleSystemSim & operator=(const ParticleSystemSim&); - Dy::ParticleSystem* mLLParticleSystem; ParticleSystemShapeSim mShapeSim; - PxU32 mNumCountedInteractions; - +// PT: as far as I can tell these are never actually called +// void activate(); +// void deactivate(); }; } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScPipeline.cpp b/physx/source/simulationcontroller/src/ScPipeline.cpp new file mode 100644 index 000000000..0a3f81e5b --- /dev/null +++ b/physx/source/simulationcontroller/src/ScPipeline.cpp @@ -0,0 +1,2355 @@ +// 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. + +// PT: this file contains most Scene functions called during the simulate() call, i.e. the "pipeline" functions. +// Ideally they should be listed in the order in which they are called in the single-threaded version, to help +// understanding and following the pipeline. + +#include "ScScene.h" +#include "BpBroadPhase.h" +#include "ScArticulationSim.h" +#include "ScSimStats.h" +#include "PxsCCD.h" + +#if defined(__APPLE__) && defined(__POWERPC__) + #include +#endif + +#if PX_SUPPORT_GPU_PHYSX + #include "PxPhysXGpu.h" + #include "PxsKernelWrangler.h" + #include "PxsHeapMemoryAllocator.h" + #include "cudamanager/PxCudaContextManager.h" +#endif + +#include "ScShapeInteraction.h" +#include "ScElementInteractionMarker.h" + +#if PX_SUPPORT_GPU_PHYSX + #include "PxSoftBody.h" + #include "ScSoftBodySim.h" + #include "DySoftBody.h" + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #include "PxFEMCloth.h" + #include "PxHairSystem.h" + #endif + #include "ScFEMClothSim.h" + #include "DyFEMCloth.h" + #include "ScParticleSystemSim.h" + #include "DyParticleSystem.h" + #include "ScHairSystemSim.h" + #include "DyHairSystem.h" +#endif + +using namespace physx; +using namespace physx::Cm; +using namespace physx::Dy; +using namespace Sc; + +/////////////////////////////////////////////////////////////////////////////// + +void PxcClearContactCacheStats(); +void Sc::Scene::stepSetupCollide(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.stepSetupCollide", mContextId); + + { + PX_PROFILE_ZONE("Sim.prepareCollide", mContextId); + mReportShapePairTimeStamp++; // deleted actors/shapes should get separate pair entries in contact reports + mContactReportsNeedPostSolverVelocity = false; + + getRenderBuffer().clear(); + + // Clear broken constraint list: + clearBrokenConstraintBuffer(); + + visualizeStartStep(); + + PxcClearContactCacheStats(); + } + + kinematicsSetup(continuation); + + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + // Update all dirty interactions + mNPhaseCore->updateDirtyInteractions(outputs); + mInternalFlags &= ~(SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_DOMINANCE | SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_VISUALIZATION); +} + +void Sc::Scene::simulate(PxReal timeStep, PxBaseTask* continuation) +{ + if(timeStep != 0.0f) + { + setElapsedTime(timeStep); + mDynamicsContext->setDt(timeStep); + + mAdvanceStep.setContinuation(continuation); + + stepSetupCollide(&mAdvanceStep); + + mCollideStep.setContinuation(&mAdvanceStep); + + mAdvanceStep.removeReference(); + mCollideStep.removeReference(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::collideStep(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.collideQueueTasks", mContextId); + PX_PROFILE_START_CROSSTHREAD("Basic.collision", mContextId); + + mStats->simStart(); + mLLContext->beginUpdate(); + + mSimulationController->flushInsertions(); + + mPostNarrowPhase.setTaskManager(*continuation->getTaskManager()); + mPostNarrowPhase.addReference(); + + mFinalizationPhase.setTaskManager(*continuation->getTaskManager()); + mFinalizationPhase.addReference(); + + mRigidBodyNarrowPhase.setContinuation(continuation); + mPreRigidBodyNarrowPhase.setContinuation(&mRigidBodyNarrowPhase); + mUpdateShapes.setContinuation(&mPreRigidBodyNarrowPhase); + + mRigidBodyNarrowPhase.removeReference(); + mPreRigidBodyNarrowPhase.removeReference(); + mUpdateShapes.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::updateShapes(PxBaseTask* continuation) +{ + //dma shapes data to gpu + mSimulationController->updateShapes(continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +namespace +{ +class DirtyShapeUpdatesTask : public Cm::Task +{ +public: + static const PxU32 MaxShapes = 256; + + PxsTransformCache& mCache; + Bp::BoundsArray& mBoundsArray; + ShapeSim* mShapes[MaxShapes]; + PxU32 mNbShapes; + + DirtyShapeUpdatesTask(PxU64 contextID, PxsTransformCache& cache, Bp::BoundsArray& boundsArray) : + Cm::Task (contextID), + mCache (cache), + mBoundsArray(boundsArray), + mNbShapes (0) + { + } + + virtual void runInternal() + { + for (PxU32 a = 0; a < mNbShapes; ++a) + mShapes[a]->updateCached(mCache, mBoundsArray); + } + + virtual const char* getName() const { return "DirtyShapeUpdatesTask"; } + +private: + PX_NOCOPY(DirtyShapeUpdatesTask) +}; +} + +static DirtyShapeUpdatesTask* createDirtyShapeUpdateTask(Cm::FlushPool& pool, PxU64 contextID, PxsTransformCache& cache, Bp::BoundsArray& boundsArray) +{ + return PX_PLACEMENT_NEW(pool.allocate(sizeof(DirtyShapeUpdatesTask)), DirtyShapeUpdatesTask)(contextID, cache, boundsArray); +} + +void Sc::Scene::updateDirtyShapes(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Scene.updateDirtyShapes", mContextId); + + // PT: it is quite unfortunate that we cannot shortcut parsing the bitmaps. We should consider switching to arrays. + + //Process dirty shapeSims... + PxBitMap::Iterator dirtyShapeIter(mDirtyShapeSimMap); + + PxsTransformCache& cache = mLLContext->getTransformCache(); + Bp::BoundsArray& boundsArray = mAABBManager->getBoundsArray(); + + Cm::FlushPool& pool = mLLContext->getTaskPool(); + PxBitMapPinned& changedMap = mAABBManager->getChangedAABBMgActorHandleMap(); + + DirtyShapeUpdatesTask* task = createDirtyShapeUpdateTask(pool, mContextId, cache, boundsArray); + + // PT: TASK-CREATION TAG + bool hasDirtyShapes = false; + PxU32 nbDirtyShapes = 0; + PxU32 index; + while((index = dirtyShapeIter.getNext()) != PxBitMap::Iterator::DONE) + { + ShapeSim* shapeSim = reinterpret_cast(mAABBManager->getUserData(index)); + if(shapeSim) + { + hasDirtyShapes = true; + changedMap.growAndSet(index); + task->mShapes[nbDirtyShapes++] = shapeSim; + + // PT: consider better load balancing? + if(nbDirtyShapes == DirtyShapeUpdatesTask::MaxShapes) + { + task->mNbShapes = nbDirtyShapes; + nbDirtyShapes = 0; + startTask(task, continuation); + + task = createDirtyShapeUpdateTask(pool, mContextId, cache, boundsArray); + } + } + } + + if(hasDirtyShapes) + { + //Setting the boundsArray and transform cache as dirty so that they get DMAd to GPU if GPU dynamics and BP are being used respectively. + //These bits are no longer set when we update the cached state for actors due to an optimization avoiding setting these dirty bits multiple times. + getBoundsArray().setChangedState(); + getLowLevelContext()->getTransformCache().setChangedState(); + } + + if(nbDirtyShapes) + { + task->mNbShapes = nbDirtyShapes; + startTask(task, continuation); + } + + // PT: we clear the map but we don't shrink it, bad because we always parse it above + mDirtyShapeSimMap.clear(); +} + +void Sc::Scene::preRigidBodyNarrowPhase(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Scene.preNarrowPhase", mContextId); + + updateContactDistances(continuation); + updateDirtyShapes(continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::rigidBodyNarrowPhase(PxBaseTask* continuation) +{ + PX_PROFILE_START_CROSSTHREAD("Basic.narrowPhase", mContextId); + + mCCDPass = 0; + + mPostBroadPhase3.addDependent(*continuation); + mPostBroadPhase2.setContinuation(&mPostBroadPhase3); + mPostBroadPhaseCont.setContinuation(&mPostBroadPhase2); + mPostBroadPhase.setContinuation(&mPostBroadPhaseCont); + mBroadPhase.setContinuation(&mPostBroadPhase); + + mRigidBodyNPhaseUnlock.setContinuation(continuation); + mRigidBodyNPhaseUnlock.addReference(); + + mUpdateBoundAndShapeTask.addDependent(mBroadPhase); + + mLLContext->resetThreadContexts(); + + mLLContext->updateContactManager(mDt, mBoundsArray->hasChanged(), mHasContactDistanceChanged, continuation, + &mRigidBodyNPhaseUnlock, &mUpdateBoundAndShapeTask); // Starts update of contact managers + + mPostBroadPhase3.removeReference(); + mPostBroadPhase2.removeReference(); + mPostBroadPhaseCont.removeReference(); + mPostBroadPhase.removeReference(); + mBroadPhase.removeReference(); + + mUpdateBoundAndShapeTask.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::updateBoundsAndShapes(PxBaseTask* /*continuation*/) +{ + //if the scene doesn't use gpu dynamic and gpu broad phase and the user enables the direct API, + //the sdk will refuse to create the scene. + const bool useDirectGpuApi = mPublicFlags & PxSceneFlag::eENABLE_DIRECT_GPU_API; + mSimulationController->updateBoundsAndShapes(*mAABBManager, mUseGpuBp, useDirectGpuApi); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::broadPhase(PxBaseTask* continuation) +{ + PX_PROFILE_START_CROSSTHREAD("Basic.broadPhase", mContextId); + + mProcessLostPatchesTask.setContinuation(&mPostNarrowPhase); + mProcessLostPatchesTask.removeReference(); + +#if PX_SUPPORT_GPU_PHYSX + gpu_updateBounds(); +#endif + + mCCDBp = false; + + mBpSecondPass.setContinuation(continuation); + mBpFirstPass.setContinuation(&mBpSecondPass); + + mBpSecondPass.removeReference(); + mBpFirstPass.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processFoundSolverPatches(PxBaseTask* /*continuation*/) +{ + PxvNphaseImplementationContext* nphase = mLLContext->getNphaseImplementationContext(); + mDynamicsContext->processFoundPatches(*mSimpleIslandManager, nphase->getFoundPatchManagers(), nphase->getNbFoundPatchManagers(), nphase->getFoundPatchOutputCounts()); +} + +void Sc::Scene::processLostSolverPatches(PxBaseTask* /*continuation*/) +{ + PxvNphaseImplementationContext* nphase = mLLContext->getNphaseImplementationContext(); + mDynamicsContext->processLostPatches(*mSimpleIslandManager, nphase->getFoundPatchManagers(), nphase->getNbFoundPatchManagers(), nphase->getFoundPatchOutputCounts()); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::broadPhaseFirstPass(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Basic.broadPhaseFirstPass", mContextId); + + const PxU32 numCpuTasks = continuation->getTaskManager()->getCpuDispatcher()->getWorkerCount(); + mAABBManager->updateBPFirstPass(numCpuTasks, mLLContext->getTaskPool(), mHasContactDistanceChanged, continuation); + + const PxU32 maxAABBHandles = PxMax(mAABBManager->getChangedAABBMgActorHandleMap().getWordCount() * 32, getElementIDPool().getMaxID()); + + mSimulationController->mergeChangedAABBMgHandle(maxAABBHandles, mPublicFlags & PxSceneFlag::eENABLE_DIRECT_GPU_API); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::broadPhaseSecondPass(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Basic.broadPhaseSecondPass", mContextId); + + mBpUpdate.setContinuation(continuation); + mPreIntegrate.setContinuation(&mBpUpdate); + + mPreIntegrate.removeReference(); + mBpUpdate.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::preIntegrate(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Basic.preIntegrate", mContextId); + + if (!mCCDBp && isUsingGpuDynamicsOrBp()) + mSimulationController->preIntegrateAndUpdateBound(continuation, mGravity, mDt); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::updateBroadPhase(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Basic.updateBroadPhase", mContextId); + + PxBaseTask* rigidBodyNPhaseUnlock = mCCDPass ? NULL : &mRigidBodyNPhaseUnlock; + + mAABBManager->updateBPSecondPass(&mLLContext->getScratchAllocator(), continuation); + + // PT: decoupling: I moved this back from updateBPSecondPass + //if this is mCCDPass, narrowPhaseUnlockTask will be NULL + if(rigidBodyNPhaseUnlock) + rigidBodyNPhaseUnlock->removeReference(); + + if(!mCCDBp && isUsingGpuDynamicsOrBp()) + mSimulationController->updateParticleSystemsAndSoftBodies(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::unblockNarrowPhase(PxBaseTask*) +{ + /*if (!mCCDBp && mUseGpuRigidBodies) + mSimulationController->updateParticleSystemsAndSoftBodies();*/ + // + mLLContext->getNphaseImplementationContext()->startNarrowPhaseTasks(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::postBroadPhase(PxBaseTask* continuation) +{ + PX_PROFILE_START_CROSSTHREAD("Basic.postBroadPhase", mContextId); + + //Notify narrow phase that broad phase has completed + mLLContext->getNphaseImplementationContext()->postBroadPhaseUpdateContactManager(continuation); + + mAABBManager->postBroadPhase(continuation, *getFlushPool()); +} + +/////////////////////////////////////////////////////////////////////////////// + + class OverlapFilterTask : public Cm::Task + { + public: + static const PxU32 MaxPairs = 512; + NPhaseCore* mNPhaseCore; + const Bp::AABBOverlap* mPairs; + + PxU32 mNbToProcess; + + PxU32 mKeepMap[MaxPairs/32]; + + FilterInfo* mFinfo; + + PxU32 mNbToKeep; + PxU32 mNbToSuppress; + + OverlapFilterTask* mNext; + + OverlapFilterTask(PxU64 contextID, NPhaseCore* nPhaseCore, FilterInfo* fInfo, const Bp::AABBOverlap* pairs, PxU32 nbToProcess) : + Cm::Task (contextID), + mNPhaseCore (nPhaseCore), + mPairs (pairs), + mNbToProcess (nbToProcess), + mFinfo (fInfo), + mNbToKeep (0), + mNbToSuppress (0), + mNext (NULL) + { + PxMemZero(mKeepMap, sizeof(mKeepMap)); + } + + virtual void runInternal() + { + mNPhaseCore->runOverlapFilters( mNbToProcess, mPairs, mFinfo, mNbToKeep, mNbToSuppress, mKeepMap); + } + + virtual const char* getName() const { return "OverlapFilterTask"; } + }; + +void Sc::Scene::finishBroadPhase(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sc::Scene::finishBroadPhase", mContextId); + + { + PX_PROFILE_ZONE("Sim.processNewOverlaps", mContextId); + + // PT: we process "trigger pairs" immediately, sequentially. Both the filtering and the creation of trigger + // interactions happen at the same time in onTriggerOverlapCreated. + // PT: could we drop trigger interactions or parallelize this? I am not sure why Kier decided to treat trigger + // interactions differently here, in my eyes it is pretty much the same as regular interactions, and they + // could have been kept in the same multithreaded pipeline. Regular shape interactions also call "registerInActors" + // by default, so the below comment is not very convincing - we worked around this for ShapeInteraction, we + // could have worked around this as well for TriggerInteraction. + { + //KS - these functions call "registerInActors", while OverlapFilterTask reads the list of interactions + //in an actor. This could lead to a race condition and a crash if they occur at the same time, so we + //serialize these operations + PX_PROFILE_ZONE("Sim.processNewOverlaps.createOverlapsNoShapeInteractions", mContextId); + { + PxU32 createdOverlapCount; + const Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getCreatedOverlaps(Bp::ElementType::eTRIGGER, createdOverlapCount); + if(createdOverlapCount) + { + mLLContext->getSimStats().mNbNewPairs += createdOverlapCount; + mNPhaseCore->onTriggerOverlapCreated(p, createdOverlapCount); + } + } + } + + // PT: for regular shapes the code has been multithreaded and split into different parts, making it harder to follow. + // Basically this is the same code as the above for triggers, but scattered over multiple Sc::Scene functions and + // tasks. As far as I can tell the steps are: + // - "first stage" filtering (right here below) + // - "second stage" filtering and creation of ShapeInteractions in preallocateContactManagers + // - some cleanup in postBroadPhaseStage2 + { + PxU32 createdOverlapCount; + const Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getCreatedOverlaps(Bp::ElementType::eSHAPE, createdOverlapCount); + + // PT: removed this because it's pointless at this stage? + if(0) + { + //We allocate at least 1 element in this array to ensure that the onOverlapCreated functions don't go bang! + mPreallocatedContactManagers.reserve(1); + mPreallocatedShapeInteractions.reserve(1); + mPreallocatedInteractionMarkers.reserve(1); + + mPreallocatedContactManagers.forceSize_Unsafe(1); + mPreallocatedShapeInteractions.forceSize_Unsafe(1); + mPreallocatedInteractionMarkers.forceSize_Unsafe(1); + } + + mPreallocateContactManagers.setContinuation(continuation); + + // PT: this is a temporary member value used to pass the OverlapFilterTasks to the next stage of the pipeline (preallocateContactManagers). + // It ideally shouldn't be a class member but just a user-data passed from one task to the next. The task manager doesn't support that though (AFAIK), + // so instead it just lies there in Sc::Scene as a class member. It's only used in finishBroadPhase & preallocateContactManagers though. + mOverlapFilterTaskHead = NULL; + + if(createdOverlapCount) + { + mLLContext->getSimStats().mNbNewPairs += createdOverlapCount; + + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + // PT: temporary data, similar to mOverlapFilterTaskHead. Will be filled with filter info for each pair by the OverlapFilterTask. + mFilterInfo.forceSize_Unsafe(0); + mFilterInfo.reserve(createdOverlapCount); + mFilterInfo.forceSize_Unsafe(createdOverlapCount); + + // PT: TASK-CREATION TAG + const PxU32 nbPairsPerTask = OverlapFilterTask::MaxPairs; + OverlapFilterTask* previousTask = NULL; + for(PxU32 a=0; asetContinuation(&mPreallocateContactManagers); + task->removeReference(); + + // PT: setup a linked-list of OverlapFilterTasks, will be parsed in preallocateContactManagers + if(previousTask) + previousTask->mNext = task; + else + mOverlapFilterTaskHead = task; + + previousTask = task; + } + } + } + + mPreallocateContactManagers.removeReference(); + } +} + +void Sc::Scene::postBroadPhaseContinuation(PxBaseTask* continuation) +{ + mAABBManager->getChangedAABBMgActorHandleMap().clear(); + + // - Finishes broadphase update + // - Adds new interactions (and thereby contact managers if needed) + finishBroadPhase(continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +template +static PX_FORCE_INLINE T* markPointerAsUsed(T* ptr) { return reinterpret_cast(size_t(ptr) | 1); } + +static PX_FORCE_INLINE size_t isPointerMarkedAsUsed(void* ptr) { return size_t(ptr) & 1; } + +template +static PX_FORCE_INLINE T* getUsedPointer(T* ptr) +{ + const size_t address = size_t(ptr); + return address & 1 ? reinterpret_cast(address & size_t(~1)) : NULL; +} + +namespace +{ + class OnOverlapCreatedTask : public Cm::Task + { + public: + NPhaseCore* mNPhaseCore; + const Bp::AABBOverlap* mPairs; + const FilterInfo* mFinfo; + PxsContactManager** mContactManagers; + ShapeInteraction** mShapeInteractions; + ElementInteractionMarker** mInteractionMarkers; + PxU32 mNbToProcess; + + OnOverlapCreatedTask(PxU64 contextID, NPhaseCore* nPhaseCore, const Bp::AABBOverlap* pairs, const FilterInfo* fInfo, PxsContactManager** contactManagers, + ShapeInteraction** shapeInteractions, ElementInteractionMarker** interactionMarkers, PxU32 nbToProcess) : + Cm::Task (contextID), + mNPhaseCore (nPhaseCore), + mPairs (pairs), + mFinfo (fInfo), + mContactManagers (contactManagers), + mShapeInteractions (shapeInteractions), + mInteractionMarkers (interactionMarkers), + mNbToProcess (nbToProcess) + { + } + + virtual void runInternal() + { + PxsContactManager** currentCm = mContactManagers; + ShapeInteraction** currentSI = mShapeInteractions; + ElementInteractionMarker** currentEI = mInteractionMarkers; + + for(PxU32 i=0; i(pair.mUserData1); + ShapeSimBase* s1 = reinterpret_cast(pair.mUserData0); + + ElementSimInteraction* interaction = mNPhaseCore->createRbElementInteraction(mFinfo[i], *s0, *s1, *currentCm, *currentSI, *currentEI, false); + if(interaction) + { + const InteractionType::Enum type = interaction->getType(); + if(type == InteractionType::eOVERLAP) + { + PX_ASSERT(interaction==*currentSI); + + *currentSI = markPointerAsUsed(*currentSI); + currentSI++; + + if(static_cast(interaction)->getContactManager()) + { + PX_ASSERT(static_cast(interaction)->getContactManager()==*currentCm); + + *currentCm = markPointerAsUsed(*currentCm); + currentCm++; + } + } + else if(type == InteractionType::eMARKER) + { + *currentEI = markPointerAsUsed(*currentEI); + currentEI++; + } + } + } + } + + virtual const char* getName() const { return "OnOverlapCreatedTask"; } + }; +} + +void Sc::Scene::preallocateContactManagers(PxBaseTask* continuation) +{ + //Iterate over all filter tasks and work out how many pairs we need... + + PxU32 totalCreatedPairs = 0; + PxU32 totalSuppressPairs = 0; + + OverlapFilterTask* task = mOverlapFilterTaskHead; + while(task) + { + totalCreatedPairs += task->mNbToKeep; + totalSuppressPairs += task->mNbToSuppress; + task = task->mNext; + } + + { + //We allocate at least 1 element in this array to ensure that the onOverlapCreated functions don't go bang! + // PT: this has to do with the way we dereference currentCm, currentSI and currentEI in OnOverlapCreatedTask + // before we know which type of interaction will be created. That is, we need room for at least one of each type + // even if no interaction of that type will be created. + // PT: don't we preallocate 2 to 3 times as much memory as needed here then? + // PT: also doesn't it mean we're going to allocate & deallocate ALL the interaction markers most of the time? + mPreallocatedContactManagers.forceSize_Unsafe(0); + mPreallocatedShapeInteractions.forceSize_Unsafe(0); + mPreallocatedInteractionMarkers.forceSize_Unsafe(0); + + mPreallocatedContactManagers.reserve(totalCreatedPairs+1); + mPreallocatedShapeInteractions.reserve(totalCreatedPairs+1); + mPreallocatedInteractionMarkers.reserve(totalSuppressPairs+1); + + mPreallocatedContactManagers.forceSize_Unsafe(totalCreatedPairs); + mPreallocatedShapeInteractions.forceSize_Unsafe(totalCreatedPairs); + mPreallocatedInteractionMarkers.forceSize_Unsafe(totalSuppressPairs); + } + + PxU32 overlapCount; + Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getCreatedOverlaps(Bp::ElementType::eSHAPE, overlapCount); + if(!overlapCount) + return; + + struct Local + { + static void processBatch(const PxU32 createdCurrIdx, PxU32& createdStartIdx, const PxU32 suppressedCurrIdx, PxU32& suppressedStartIdx, const PxU32 batchSize, + PxsContext* const context, NPhaseCore* const core, OnOverlapCreatedTask* const createTask, PxBaseTask* const continuation_, + PxsContactManager** const cms_, ShapeInteraction** const shapeInter_, ElementInteractionMarker** const markerIter_) + { + const PxU32 nbToCreate = createdCurrIdx - createdStartIdx; + const PxU32 nbToSuppress = suppressedCurrIdx - suppressedStartIdx; + + context->getContactManagerPool().preallocate(nbToCreate, cms_ + createdStartIdx); + + for (PxU32 i = 0; i < nbToCreate; ++i) + shapeInter_[createdStartIdx + i] = core->mShapeInteractionPool.allocate(); + + for (PxU32 i = 0; i < nbToSuppress; ++i) + markerIter_[suppressedStartIdx + i] = core->mInteractionMarkerPool.allocate(); + + createdStartIdx = createdCurrIdx; + suppressedStartIdx = suppressedCurrIdx; + + createTask->mNbToProcess = batchSize; + startTask(createTask, continuation_); + } + }; + + const PxU32 nbPairsPerTask = 256; + PxsContactManager** cms = mPreallocatedContactManagers.begin(); + ShapeInteraction** shapeInter = mPreallocatedShapeInteractions.begin(); + ElementInteractionMarker** markerIter = mPreallocatedInteractionMarkers.begin(); + + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + FilterInfo* fInfo = mFilterInfo.begin(); + + // PT: TODO: why do we create the task immediately? Why not create it only when a batch is full? + // PT: it's the same pattern as for CCD, kinematics, etc + OnOverlapCreatedTask* createTask = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(OnOverlapCreatedTask)), OnOverlapCreatedTask)(mContextId, mNPhaseCore, p, fInfo, cms, shapeInter, markerIter, 0); + + PxU32 batchSize = 0; + PxU32 suppressedStartIdx = 0; + PxU32 createdStartIdx = 0; + PxU32 suppressedCurrIdx = 0; + PxU32 createdCurrIdx = 0; + PxU32 currentReadIdx = 0; + + PxU32 createdOverlapCount = 0; + + // PT: TASK-CREATION TAG + task = mOverlapFilterTaskHead; + while(task) + { + if(task->mNbToKeep || task->mNbToSuppress) + { + for(PxU32 w = 0; w < (OverlapFilterTask::MaxPairs/32); ++w) + { + for(PxU32 b = task->mKeepMap[w]; b; b &= b-1) + { + const PxU32 index = (w<<5) + PxLowestSetBit(b); + + if(createdOverlapCount < (index + currentReadIdx)) + { + p[createdOverlapCount] = task->mPairs[index]; + fInfo[createdOverlapCount] = task->mFinfo[index]; + } + createdOverlapCount++; + batchSize++; + } + } + + suppressedCurrIdx += task->mNbToSuppress; + createdCurrIdx += task->mNbToKeep; + + if(batchSize >= nbPairsPerTask) + { + Local::processBatch(createdCurrIdx, createdStartIdx, suppressedCurrIdx, suppressedStartIdx, batchSize, mLLContext, mNPhaseCore, createTask, continuation, cms, shapeInter, markerIter); + + createTask = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(OnOverlapCreatedTask)), OnOverlapCreatedTask)(mContextId, mNPhaseCore, p + createdOverlapCount, + fInfo + createdOverlapCount, cms + createdStartIdx, shapeInter + createdStartIdx, markerIter + suppressedStartIdx, 0); + + batchSize = 0; + } + } + currentReadIdx += OverlapFilterTask::MaxPairs; + task = task->mNext; + } + + if(batchSize) + Local::processBatch(createdCurrIdx, createdStartIdx, suppressedCurrIdx, suppressedStartIdx, batchSize, mLLContext, mNPhaseCore, createTask, continuation, cms, shapeInter, markerIter); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processLostTouchPairs() +{ + PX_PROFILE_ZONE("Sc::Scene::processLostTouchPairs", mContextId); + + const PxU32 nb = mLostTouchPairs.size(); + const SimpleBodyPair* pairs = mLostTouchPairs.begin(); + for(PxU32 i=0; iinternalWakeUp(); + if(!deletedBody2) + body2->internalWakeUp(); + continue; + } + + const bool b1Active = body1->isActive(); + const bool b2Active = body2->isActive(); + + // If both are sleeping, we let them sleep + // (for example, two sleeping objects touch and the user teleports one (without waking it up)) + if(!b1Active && !b2Active) + continue; + + // If only one has fallen asleep, we wake them both + if(!b1Active || !b2Active) + { + body1->internalWakeUp(); + body2->internalWakeUp(); + } + } + + mLostTouchPairs.clear(); + mLostTouchPairsDeletedBodyIDs.clear(); +} + +void Sc::Scene::postBroadPhaseStage2(PxBaseTask* continuation) +{ + // - Wakes actors that lost touch if appropriate + processLostTouchPairs(); + + mIslandInsertion.setContinuation(continuation); + mRegisterContactManagers.setContinuation(continuation); + mRegisterInteractions.setContinuation(continuation); + mRegisterSceneInteractions.setContinuation(continuation); + mIslandInsertion.removeReference(); + mRegisterContactManagers.removeReference(); + mRegisterInteractions.removeReference(); + mRegisterSceneInteractions.removeReference(); + + //Release unused Cms back to the pool (later, this needs to be done in a thread-safe way from multiple worker threads + { + PX_PROFILE_ZONE("Sim.processNewOverlaps.release", mContextId); + + { + PxU32 nb = mPreallocatedContactManagers.size(); + PxsContactManager** managers = mPreallocatedContactManagers.begin(); + Cm::PoolList& pool = mLLContext->getContactManagerPool(); + while(nb--) + { + PxsContactManager* current = *managers++; + if(!isPointerMarkedAsUsed(current)) + pool.put(current); + } + } + + { + PxU32 nb = mPreallocatedShapeInteractions.size(); + ShapeInteraction** interactions = mPreallocatedShapeInteractions.begin(); + PxPool& pool = mNPhaseCore->mShapeInteractionPool; + while(nb--) + { + ShapeInteraction* current = *interactions++; + if(!isPointerMarkedAsUsed(current)) + pool.deallocate(current); + } + } + { + PxU32 nb = mPreallocatedInteractionMarkers.size(); + ElementInteractionMarker** interactions = mPreallocatedInteractionMarkers.begin(); + PxPool& pool = mNPhaseCore->mInteractionMarkerPool; + while(nb--) + { + ElementInteractionMarker* current = *interactions++; + if(!isPointerMarkedAsUsed(current)) + pool.deallocate(current); + } + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: islandInsertion / registerContactManagers / registerInteractions / registerSceneInteractions run in parallel +void Sc::Scene::islandInsertion(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sim.processNewOverlaps.islandInsertion", mContextId); + + const PxU32 nbShapeIdxCreated = mPreallocatedShapeInteractions.size(); + for(PxU32 a = 0; a < nbShapeIdxCreated; ++a) + { + ShapeInteraction* interaction = getUsedPointer(mPreallocatedShapeInteractions[a]); + if(interaction) + { + PxsContactManager* contactManager = const_cast(interaction->getContactManager()); + + const ActorSim& bs0 = interaction->getShape0().getActor(); + const ActorSim& bs1 = interaction->getShape1().getActor(); + + const PxActorType::Enum actorTypeLargest = PxMax(bs0.getActorType(), bs1.getActorType()); + + PxNodeIndex nodeIndexB; + if (!bs1.isStaticRigid()) + nodeIndexB = bs1.getNodeIndex(); + + IG::Edge::EdgeType type = IG::Edge::eCONTACT_MANAGER; +#if PX_SUPPORT_GPU_PHYSX + if(actorTypeLargest == PxActorType::eSOFTBODY) + type = IG::Edge::eSOFT_BODY_CONTACT; + else if (actorTypeLargest == PxActorType::eFEMCLOTH) + type = IG::Edge::eFEM_CLOTH_CONTACT; + else if(isParticleSystem(actorTypeLargest)) + type = IG::Edge::ePARTICLE_SYSTEM_CONTACT; + else if (actorTypeLargest == PxActorType::eHAIRSYSTEM) + type = IG::Edge::eHAIR_SYSTEM_CONTACT; +#endif + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(contactManager, bs0.getNodeIndex(), nodeIndexB, interaction, type); + + interaction->mEdgeIndex = edgeIdx; + + if(contactManager) + contactManager->getWorkUnit().mEdgeIndex = edgeIdx; + + //If it is a soft body or particle overlap, treat it as a contact for now (we can hook up touch found/lost events later maybe) + if(actorTypeLargest > PxActorType::eARTICULATION_LINK) + mSimpleIslandManager->setEdgeConnected(edgeIdx, type); + } + } + + // - Wakes actors that lost touch if appropriate + //processLostTouchPairs(); + + if(mCCDPass == 0) + mSimpleIslandManager->firstPassIslandGen(); +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: islandInsertion / registerContactManagers / registerInteractions / registerSceneInteractions run in parallel +void Sc::Scene::registerContactManagers(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sim.processNewOverlaps.registerCms", mContextId); + + // PT: we sometimes iterate over this array in vain (all ptrs are unused). Would be better + // to store used pointers maybe in the overlap created tasks, and reuse these tasks here to + // process only used pointers. + + PxvNphaseImplementationContext* nphaseContext = mLLContext->getNphaseImplementationContext(); + nphaseContext->lock(); + //nphaseContext->registerContactManagers(mPreallocatedContactManagers.begin(), mPreallocatedContactManagers.size(), mLLContext->getContactManagerPool().getMaxUsedIndex()); + const PxU32 nbCmsCreated = mPreallocatedContactManagers.size(); + for(PxU32 a = 0; a < nbCmsCreated; ++a) + { + PxsContactManager* cm = getUsedPointer(mPreallocatedContactManagers[a]); + if(cm) + { + ShapeInteraction* interaction = getUsedPointer(mPreallocatedShapeInteractions[a]); + + nphaseContext->registerContactManager(cm, interaction, 0, 0); + } + } + nphaseContext->unlock(); +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: islandInsertion / registerContactManagers / registerInteractions / registerSceneInteractions run in parallel +void Sc::Scene::registerInteractions(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sim.processNewOverlaps.registerInteractions", mContextId); + + const PxU32 nbShapeIdxCreated = mPreallocatedShapeInteractions.size(); + for(PxU32 a = 0; a < nbShapeIdxCreated; ++a) + { + ShapeInteraction* interaction = getUsedPointer(mPreallocatedShapeInteractions[a]); + if(interaction) + { + // PT: this is similar to interaction->registerInActors(), which is usually called from + // interaction ctors. + ActorSim& actorSim0 = interaction->getActorSim0(); + ActorSim& actorSim1 = interaction->getActorSim1(); + actorSim0.registerInteractionInActor(interaction); + actorSim1.registerInteractionInActor(interaction); + + // PT: the number of counted interactions is used for the sleeping system + if(actorSim0.isDynamicRigid()) + static_cast(&actorSim0)->registerCountedInteraction(); + + if(actorSim1.isDynamicRigid()) + static_cast(&actorSim1)->registerCountedInteraction(); + } + } + + const PxU32 nbMarkersCreated = mPreallocatedInteractionMarkers.size(); + for(PxU32 a = 0; a < nbMarkersCreated; ++a) + { + ElementInteractionMarker* interaction = getUsedPointer(mPreallocatedInteractionMarkers[a]); + if(interaction) + { + // PT: no call to "interaction->onActivate()" here because it doesn't do anything + interaction->registerInActors(); + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +// PT: islandInsertion / registerContactManagers / registerInteractions / registerSceneInteractions run in parallel +void Sc::Scene::registerSceneInteractions(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sim.processNewOverlaps.registerInteractionsScene", mContextId); + + const PxU32 nbShapeIdxCreated = mPreallocatedShapeInteractions.size(); + for(PxU32 a = 0; a < nbShapeIdxCreated; ++a) + { + ShapeInteraction* interaction = getUsedPointer(mPreallocatedShapeInteractions[a]); + if(interaction) + { + registerInteraction(interaction, interaction->getContactManager() != NULL); + + const PxsContactManager* cm = interaction->getContactManager(); + if(cm) + mLLContext->setActiveContactManager(cm, cm->getCCD()); + } + } + + const PxU32 nbInteractionMarkers = mPreallocatedInteractionMarkers.size(); + for(PxU32 a = 0; a < nbInteractionMarkers; ++a) + { + ElementInteractionMarker* interaction = getUsedPointer(mPreallocatedInteractionMarkers[a]); + if(interaction) + registerInteraction(interaction, false); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::finishBroadPhaseStage2(PxU32 ccdPass) +{ + PX_PROFILE_ZONE("Sc::Scene::finishBroadPhase2", mContextId); + + Bp::AABBManagerBase* aabbMgr = mAABBManager; + + PxU32 nbLostPairs = 0; + for(PxU32 i=0; igetDestroyedOverlaps(Bp::ElementType::Enum(i), destroyedOverlapCount); + nbLostPairs += destroyedOverlapCount; + } + mLLContext->getSimStats().mNbLostPairs += nbLostPairs; + + // PT: TODO: move this to ccd file? + //KS - we need to defer processing lost overlaps until later! + if (ccdPass) + { + PX_PROFILE_ZONE("Sim.processLostOverlaps", mContextId); + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + + PxU32 destroyedOverlapCount; + + // PT: for regular shapes + { + Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + + while(destroyedOverlapCount--) + { + ElementSim* volume0 = reinterpret_cast(p->mUserData0); + ElementSim* volume1 = reinterpret_cast(p->mUserData1); + + //KS - this is a bit ugly. We split the "onOverlapRemoved" for shape interactions to parallelize it and that means + //that we have to call each of the individual stages of the remove here. + + //First, we have to get the interaction pointer... + ElementSimInteraction* interaction = mNPhaseCore->findInteraction(volume0, volume1); + p->mPairUserData = interaction; + if(interaction) + { + if(interaction->getType() == InteractionType::eOVERLAP || interaction->getType() == InteractionType::eMARKER) + { + //If it's a standard "overlap" interaction, we have to send a lost touch report, unregister it, and destroy its manager and island gen data. + if(interaction->getType() == InteractionType::eOVERLAP) + { + ShapeInteraction* si = static_cast(interaction); + mNPhaseCore->lostTouchReports(si, PxU32(PairReleaseFlag::eWAKE_ON_LOST_TOUCH), NULL, 0, outputs); + + //We must check to see if we have a contact manager here. There is an edge case where actors could be put to + //sleep after discrete simulation, prior to CCD, causing their contactManager() to be destroyed. If their bounds + //also ceased overlapping, then this code will try to destroy the manager again. + if(si->getContactManager()) + si->destroyManager(); + si->clearIslandGenData(); + } + + unregisterInteraction(interaction); + } + + //Then call "onOverlapRemoved" to actually free the interaction + mNPhaseCore->onOverlapRemoved(volume0, volume1, ccdPass, interaction, outputs); + } + p++; + } + } + + // PT: for triggers + { + Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eTRIGGER, destroyedOverlapCount); + + while(destroyedOverlapCount--) + { + ElementSim* volume0 = reinterpret_cast(p->mUserData0); + ElementSim* volume1 = reinterpret_cast(p->mUserData1); + + p->mPairUserData = NULL; + + //KS - this is a bit ugly. + mNPhaseCore->onOverlapRemoved(volume0, volume1, ccdPass, NULL, outputs); + p++; + } + } + } + + // - Wakes actors that lost touch if appropriate + processLostTouchPairs(); + + if (ccdPass) + aabbMgr->freeBuffers(); +} + +void Sc::Scene::postBroadPhaseStage3(PxBaseTask* /*continuation*/) +{ + finishBroadPhaseStage2(0); + + PX_PROFILE_STOP_CROSSTHREAD("Basic.postBroadPhase", mContextId); + PX_PROFILE_STOP_CROSSTHREAD("Basic.broadPhase", mContextId); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::advanceStep(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.solveQueueTasks", mContextId); + + if(mDt != 0.0f) + { + mFinalizationPhase.addDependent(*continuation); + mFinalizationPhase.removeReference(); + + if(mPublicFlags & PxSceneFlag::eENABLE_CCD) + { + mUpdateCCDMultiPass.setContinuation(&mFinalizationPhase); + mAfterIntegration.setContinuation(&mUpdateCCDMultiPass); + mUpdateCCDMultiPass.removeReference(); + } + else + { + mAfterIntegration.setContinuation(&mFinalizationPhase); + } + + mPostSolver.setContinuation(&mAfterIntegration); + mUpdateSimulationController.setContinuation(&mPostSolver); + mUpdateDynamics.setContinuation(&mUpdateSimulationController); + mUpdateBodies.setContinuation(&mUpdateDynamics); + mSolver.setContinuation(&mUpdateBodies); + mPostIslandGen.setContinuation(&mSolver); + mIslandGen.setContinuation(&mPostIslandGen); + mPostNarrowPhase.addDependent(mIslandGen); + mPostNarrowPhase.removeReference(); + + mSecondPassNarrowPhase.setContinuation(&mPostNarrowPhase); + + mFinalizationPhase.removeReference(); + mAfterIntegration.removeReference(); + mPostSolver.removeReference(); + mUpdateSimulationController.removeReference(); + mUpdateDynamics.removeReference(); + mUpdateBodies.removeReference(); + mSolver.removeReference(); + mPostIslandGen.removeReference(); + mIslandGen.removeReference(); + mPostNarrowPhase.removeReference(); + mSecondPassNarrowPhase.removeReference(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::activateEdgesInternal(const IG::EdgeIndex* activatingEdges, const PxU32 nbActivatingEdges) +{ + const IG::IslandSim& speculativeSim = mSimpleIslandManager->getSpeculativeIslandSim(); + for(PxU32 i = 0; i < nbActivatingEdges; ++i) + { + Interaction* interaction = mSimpleIslandManager->getInteraction(activatingEdges[i]); + + if(interaction && !interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) + { + if(speculativeSim.getEdge(activatingEdges[i]).isActive()) + { + const bool proceed = activateInteraction(interaction, NULL); + + if(proceed && (interaction->getType() < InteractionType::eTRACKED_IN_SCENE_COUNT)) + notifyInteractionActivated(interaction); + } + } + } +} + +void Sc::Scene::secondPassNarrowPhase(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sim.secondPassNarrowPhase", mContextId); + { + PX_PROFILE_ZONE("Sim.postIslandGen", mContextId); + + mSimpleIslandManager->additionalSpeculativeActivation(); + + // wake interactions + { + PX_PROFILE_ZONE("ScScene.wakeInteractions", mContextId); + const IG::IslandSim& speculativeSim = mSimpleIslandManager->getSpeculativeIslandSim(); + + //KS - only wake contact managers based on speculative state to trigger contact gen. Waking actors based on accurate state + //should activate and joints. + { + //Wake speculatively based on rigid contacts, soft contacts and particle contacts + activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eCONTACT_MANAGER), speculativeSim.getNbActivatedEdges(IG::Edge::eCONTACT_MANAGER)); +#if PX_SUPPORT_GPU_PHYSX + activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eSOFT_BODY_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::eSOFT_BODY_CONTACT)); + activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eFEM_CLOTH_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::eFEM_CLOTH_CONTACT)); + activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::ePARTICLE_SYSTEM_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::ePARTICLE_SYSTEM_CONTACT)); + activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eHAIR_SYSTEM_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::eHAIR_SYSTEM_CONTACT)); +#endif + } + } + } + mLLContext->secondPassUpdateContactManager(mDt, &mPostNarrowPhase); // Starts update of contact managers +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::releaseConstraints(bool endOfScene) +{ + PX_ASSERT(mLLContext); + + if(mEnableStabilization) + { + //If stabilization is enabled, we're caching contacts for next frame + if(!endOfScene) + { + //So we only clear memory (flip buffers) when not at the end-of-scene. + //This means we clear after narrow phase completed so we can + //release the previous frame's contact buffers before we enter the solve phase. + mLLContext->getNpMemBlockPool().releaseContacts(); + } + } + else if(endOfScene) + { + //We now have a double-buffered pool of mem blocks so we must + //release both pools (which actually triggers the memory used this + //frame to be released + mLLContext->getNpMemBlockPool().releaseContacts(); + mLLContext->getNpMemBlockPool().releaseContacts(); + } +} + +void Sc::Scene::postNarrowPhase(PxBaseTask* /*continuation*/) +{ + setCollisionPhaseToInactive(); + + mHasContactDistanceChanged = false; + mLLContext->fetchUpdateContactManager(); //Sync on contact gen results! + + if(!mCCDBp && isUsingGpuDynamicsOrBp()) + mSimulationController->sortContacts(); + + releaseConstraints(false); + + PX_PROFILE_STOP_CROSSTHREAD("Basic.narrowPhase", mContextId); + PX_PROFILE_STOP_CROSSTHREAD("Basic.collision", mContextId); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processNarrowPhaseTouchEvents() +{ + PX_PROFILE_ZONE("Sim.preIslandGen", mContextId); + + PxsContext* context = mLLContext; + + // Update touch states from LL + PxU32 newTouchCount, lostTouchCount; + PxU32 ccdTouchCount = 0; + { + PX_PROFILE_ZONE("Sim.preIslandGen.managerTouchEvents", mContextId); + context->getManagerTouchEventCount(reinterpret_cast(&newTouchCount), reinterpret_cast(&lostTouchCount), NULL); + //PX_ALLOCA(newTouches, PxvContactManagerTouchEvent, newTouchCount); + //PX_ALLOCA(lostTouches, PxvContactManagerTouchEvent, lostTouchCount); + + mTouchFoundEvents.forceSize_Unsafe(0); + mTouchFoundEvents.reserve(newTouchCount); + mTouchFoundEvents.forceSize_Unsafe(newTouchCount); + + mTouchLostEvents.forceSize_Unsafe(0); + mTouchLostEvents.reserve(lostTouchCount); + mTouchLostEvents.forceSize_Unsafe(lostTouchCount); + + context->fillManagerTouchEvents(mTouchFoundEvents.begin(), reinterpret_cast(newTouchCount), mTouchLostEvents.begin(), + reinterpret_cast(lostTouchCount), NULL, reinterpret_cast(ccdTouchCount)); + + mTouchFoundEvents.forceSize_Unsafe(newTouchCount); + mTouchLostEvents.forceSize_Unsafe(lostTouchCount); + } + + context->getSimStats().mNbNewTouches = newTouchCount; + context->getSimStats().mNbLostTouches = lostTouchCount; +} + +void Sc::Scene::islandGen(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sc::Scene::islandGen", mContextId); + + //mLLContext->runModifiableContactManagers(); //KS - moved here so that we can get up-to-date touch found/lost events in IG + + /*mProcessLostPatchesTask.setContinuation(&mUpdateDynamics); + mProcessLostPatchesTask.removeReference();*/ + + processNarrowPhaseTouchEvents(); + + // PT: could we merge processNarrowPhaseTouchEventsStage2 with processNarrowPhaseTouchEvents ? + mProcessFoundPatchesTask.setContinuation(continuation); + mProcessFoundPatchesTask.removeReference(); + + processNarrowPhaseTouchEventsStage2(&mPostSolver); +} + +/////////////////////////////////////////////////////////////////////////////// + +static PX_FORCE_INLINE ShapeInteraction* getSI(PxvContactManagerTouchEvent& evt) +{ + return reinterpret_cast(evt.getCMTouchEventUserData()); +} + +namespace +{ + class InteractionNewTouchTask : public Cm::Task + { + PxvContactManagerTouchEvent* mEvents; + const PxU32 mNbEvents; + PxsContactManagerOutputIterator mOutputs; + NPhaseCore* mNphaseCore; + + public: + InteractionNewTouchTask(PxU64 contextID, PxvContactManagerTouchEvent* events, PxU32 nbEvents, PxsContactManagerOutputIterator& outputs, NPhaseCore* nPhaseCore) : + Cm::Task (contextID), + mEvents (events), + mNbEvents (nbEvents), + mOutputs (outputs), + mNphaseCore (nPhaseCore) + { + } + + virtual const char* getName() const + { + return "InteractionNewTouchTask"; + } + + virtual void runInternal() + { + mNphaseCore->lockReports(); + for(PxU32 i = 0; i < mNbEvents; ++i) + { + ShapeInteraction* si = getSI(mEvents[i]); + PX_ASSERT(si); + mNphaseCore->managerNewTouch(*si); + si->managerNewTouch(0, true, mOutputs); + } + mNphaseCore->unlockReports(); + } + private: + PX_NOCOPY(InteractionNewTouchTask) + }; +} + +void Sc::Scene::processNarrowPhaseTouchEventsStage2(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sc::Scene::processNarrowPhaseTouchEventsStage2", mContextId); + + PxvNphaseImplementationContext* ctx = mLLContext->getNphaseImplementationContext(); + + PxsContactManagerOutputIterator outputs = ctx->getContactManagerOutputs(); + + const PxU32 newTouchCount = mTouchFoundEvents.size(); + + { + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + // PT: why not a delegate task here? We seem to be creating a single InteractionNewTouchTask ? + InteractionNewTouchTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(InteractionNewTouchTask)), InteractionNewTouchTask)(mContextId, mTouchFoundEvents.begin(), newTouchCount, outputs, mNPhaseCore); + startTask(task, continuation); + } + + /*{ + PX_PROFILE_ZONE("Sim.preIslandGen.newTouchesInteraction", mContextId); + for (PxU32 i = 0; i < newTouchCount; ++i) + { + ShapeInteraction* si = reinterpret_cast(mTouchFoundEvents[i].userData); + PX_ASSERT(si); + mNPhaseCore->managerNewTouch(*si); + si->managerNewTouch(0, true, outputs, useAdaptiveForce); + } + }*/ +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::postIslandGen(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.postIslandGen", mContextId); + + mSetEdgesConnectedTask.setContinuation(continuation); + mSetEdgesConnectedTask.removeReference(); + + // - Performs collision detection for trigger interactions + mNPhaseCore->processTriggerInteractions(continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::setEdgesConnected(PxBaseTask*) +{ + PX_PROFILE_ZONE("Sim.preIslandGen.islandTouches", mContextId); + { + PX_PROFILE_ZONE("Sim.preIslandGen.setEdgesConnected", mContextId); + + const PxU32 newTouchCount = mTouchFoundEvents.size(); + for(PxU32 i = 0; i < newTouchCount; ++i) + { + ShapeInteraction* si = getSI(mTouchFoundEvents[i]); + if(!si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) + mSimpleIslandManager->setEdgeConnected(si->getEdgeIndex(), IG::Edge::eCONTACT_MANAGER); + } + } + + mSimpleIslandManager->secondPassIslandGen(); + + wakeObjectsUp(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::solver(PxBaseTask* continuation) +{ + PX_PROFILE_START_CROSSTHREAD("Basic.rigidBodySolver", mContextId); + + //Update forces per body in parallel. This can overlap with the other work in this phase. + beforeSolver(continuation); + + PX_PROFILE_ZONE("Sim.postNarrowPhaseSecondPass", mContextId); + + //Narrowphase is completely finished so the streams can be swapped. + mLLContext->swapStreams(); + + //PxsContactManagerOutputIterator outputs = this->mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + //mNPhaseCore->processPersistentContactEvents(outputs, continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +namespace +{ + class ScBeforeSolverTask : public Cm::Task + { + public: + static const PxU32 MaxBodiesPerTask = 256; + PxNodeIndex mBodies[MaxBodiesPerTask]; + PxU32 mNumBodies; + const PxReal mDt; + IG::SimpleIslandManager* mIslandManager; + PxsSimulationController* mSimulationController; + + public: + + ScBeforeSolverTask(PxReal dt, IG::SimpleIslandManager* islandManager, PxsSimulationController* simulationController, PxU64 contextID) : + Cm::Task (contextID), + mDt (dt), + mIslandManager (islandManager), + mSimulationController (simulationController) + { + } + + virtual void runInternal() + { + PX_PROFILE_ZONE("Sim.ScBeforeSolverTask", mContextID); + + const IG::IslandSim& islandSim = mIslandManager->getAccurateIslandSim(); + const PxU32 rigidBodyOffset = BodySim::getRigidBodyOffset(); + + PxsRigidBody* updatedBodySims[MaxBodiesPerTask]; + PxU32 updatedBodyNodeIndices[MaxBodiesPerTask]; + PxU32 nbUpdatedBodySims = 0; + + PxU32 nb = mNumBodies; + const PxNodeIndex* bodies = mBodies; + while(nb--) + { + const PxNodeIndex index = *bodies++; + + if(islandSim.getActiveNodeIndex(index) != PX_INVALID_NODE) + { + if(islandSim.getNode(index).mType == IG::Node::eRIGID_BODY_TYPE) + { + PxsRigidBody* body = islandSim.getRigidBody(index); + BodySim* bodySim = reinterpret_cast(reinterpret_cast(body) - rigidBodyOffset); + bodySim->updateForces(mDt, updatedBodySims, updatedBodyNodeIndices, nbUpdatedBodySims, NULL); + } + } + } + + if(nbUpdatedBodySims) + mSimulationController->updateBodies(updatedBodySims, updatedBodyNodeIndices, nbUpdatedBodySims); + } + + virtual const char* getName() const + { + return "ScScene.beforeSolver"; + } + + private: + PX_NOCOPY(ScBeforeSolverTask) + }; + + class ScArticBeforeSolverTask : public Cm::Task + { + public: + ArticulationSim* const* mArticSims; + const PxU32 mNumArticulations; + const PxReal mDt; + IG::SimpleIslandManager* mIslandManager; + + public: + + ScArticBeforeSolverTask(ArticulationSim* const* articSims, PxU32 nbArtics, PxReal dt, IG::SimpleIslandManager* islandManager, PxU64 contextID) : + Cm::Task(contextID), + mArticSims(articSims), + mNumArticulations(nbArtics), + mDt(dt), + mIslandManager(islandManager) + { + } + + virtual void runInternal() + { + PX_PROFILE_ZONE("Sim.ScArticBeforeSolverTask", mContextID); + //const IG::IslandSim& islandSim = mIslandManager->getAccurateIslandSim(); + + for(PxU32 a = 0; a < mNumArticulations; ++a) + { + ArticulationSim* PX_RESTRICT articSim = mArticSims[a]; + //articSim->checkResize(); + articSim->updateForces(mDt, false); + articSim->setDirtyFlag(ArticulationSimDirtyFlag::eNONE); + } + } + + virtual const char* getName() const + { + return "ScScene.ScArticBeforeSolverTask"; + } + + private: + PX_NOCOPY(ScArticBeforeSolverTask) + }; + + class ScArticBeforeSolverCCDTask : public Cm::Task + { + public: + const PxNodeIndex* const mArticIndices; + const PxU32 mNumArticulations; + const PxReal mDt; + IG::SimpleIslandManager* mIslandManager; + + public: + + ScArticBeforeSolverCCDTask(const PxNodeIndex* const articIndices, PxU32 nbArtics, PxReal dt, IG::SimpleIslandManager* islandManager, PxU64 contextID) : + Cm::Task(contextID), + mArticIndices(articIndices), + mNumArticulations(nbArtics), + mDt(dt), + mIslandManager(islandManager) + { + } + + virtual void runInternal() + { + PX_PROFILE_ZONE("Sim.ScArticBeforeSolverCCDTask", mContextID); + const IG::IslandSim& islandSim = mIslandManager->getAccurateIslandSim(); + + for(PxU32 a = 0; a < mNumArticulations; ++a) + { + ArticulationSim* articSim = islandSim.getArticulationSim(mArticIndices[a]); + + articSim->saveLastCCDTransform(); + } + } + + virtual const char* getName() const + { + return "ScScene.ScArticBeforeSolverCCDTask"; + } + + private: + PX_NOCOPY(ScArticBeforeSolverCCDTask) + }; +} + +void Sc::Scene::beforeSolver(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.updateForces", mContextId); + + // Note: For contact notifications it is important that force threshold checks are done after new/lost touches have been processed + // because pairs might get added to the list processed below + + // Atoms that passed contact force threshold + ThresholdStream& thresholdStream = mDynamicsContext->getThresholdStream(); + thresholdStream.clear(); + + const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); + + const PxU32 nbActiveBodies = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); + + mNumDeactivatingNodes[IG::Node::eRIGID_BODY_TYPE] = 0;//islandSim.getNbNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); + mNumDeactivatingNodes[IG::Node::eARTICULATION_TYPE] = 0;//islandSim.getNbNodesToDeactivate(IG::Node::eARTICULATION_TYPE); +//#if PX_SUPPORT_GPU_PHYSX + mNumDeactivatingNodes[IG::Node::eSOFTBODY_TYPE] = 0; + mNumDeactivatingNodes[IG::Node::eFEMCLOTH_TYPE] = 0; + mNumDeactivatingNodes[IG::Node::ePARTICLESYSTEM_TYPE] = 0; + mNumDeactivatingNodes[IG::Node::eHAIRSYSTEM_TYPE] = 0; +//#endif + + const PxU32 MaxBodiesPerTask = ScBeforeSolverTask::MaxBodiesPerTask; + + Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + + mSimulationController->reserve(nbActiveBodies); + + { + PxBitMap::Iterator iter(mVelocityModifyMap); + + // PT: TASK-CREATION TAG + for (PxU32 i = iter.getNext(); i != PxBitMap::Iterator::DONE; /*i = iter.getNext()*/) + { + ScBeforeSolverTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScBeforeSolverTask)), ScBeforeSolverTask(mDt, mSimpleIslandManager, mSimulationController, mContextId)); + PxU32 count = 0; + for(; count < MaxBodiesPerTask && i != PxBitMap::Iterator::DONE; i = iter.getNext()) + { + PxsRigidBody* body = islandSim.getRigidBody(PxNodeIndex(i)); + bool retainsAccelerations = false; + if(body) + { + task->mBodies[count++] = PxNodeIndex(i); + + retainsAccelerations = (body->mCore->mFlags & PxRigidBodyFlag::eRETAIN_ACCELERATIONS); + } + + if(!retainsAccelerations) + mVelocityModifyMap.reset(i); + } + task->mNumBodies = count; + startTask(task, continuation); + } + } + + // PT: TASK-CREATION TAG + const PxU32 nbArticsPerTask = 32; + const PxU32 nbDirtyArticulations = mDirtyArticulationSims.size(); + ArticulationSim* const* artiSim = mDirtyArticulationSims.getEntries(); + for(PxU32 a = 0; a < nbDirtyArticulations; a += nbArticsPerTask) + { + const PxU32 nbToProcess = PxMin(PxU32(nbDirtyArticulations - a), nbArticsPerTask); + + ScArticBeforeSolverTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScArticBeforeSolverTask)), ScArticBeforeSolverTask(artiSim + a, nbToProcess, + mDt, mSimpleIslandManager, mContextId)); + + startTask(task, continuation); + } + + //if the scene has ccd flag on, we should call ScArticBeforeSolverCCDTask to copy the last transform to the current transform + if(mPublicFlags & PxSceneFlag::eENABLE_CCD) + { + //CCD + const PxU32 nbActiveArticulations = islandSim.getNbActiveNodes(IG::Node::eARTICULATION_TYPE); + const PxNodeIndex* const articIndices = islandSim.getActiveNodes(IG::Node::eARTICULATION_TYPE); + + // PT: TASK-CREATION TAG + for(PxU32 a = 0; a < nbActiveArticulations; a += nbArticsPerTask) + { + const PxU32 nbToProcess = PxMin(PxU32(nbActiveArticulations - a), nbArticsPerTask); + ScArticBeforeSolverCCDTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScArticBeforeSolverCCDTask)), ScArticBeforeSolverCCDTask(articIndices + a, nbToProcess, + mDt, mSimpleIslandManager, mContextId)); + + startTask(task, continuation); + } + } + + for(PxU32 a = 0; a < nbDirtyArticulations; a++) + mSimulationController->updateArticulationExtAccel(artiSim[a]->getLowLevelArticulation(), artiSim[a]->getIslandNodeIndex()); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::updateBodies(PxBaseTask* continuation) +{ + //dma bodies and articulation data to gpu + mSimulationController->updateBodies(continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::updateDynamics(PxBaseTask* continuation) +{ + PX_PROFILE_START_CROSSTHREAD("Basic.dynamics", mContextId); + + //Allow processLostContactsTask to run until after 2nd pass of solver completes (update bodies, run sleeping logic etc.) + mProcessLostContactsTask3.setContinuation(static_cast(continuation)->getContinuation()); + mProcessLostContactsTask2.setContinuation(&mProcessLostContactsTask3); + mProcessLostContactsTask.setContinuation(&mProcessLostContactsTask2); + + ////dma bodies and shapes data to gpu + //mSimulationController->updateBodiesAndShapes(); + + mLLContext->getNpMemBlockPool().acquireConstraintMemory(); + + const PxU32 maxPatchCount = mLLContext->getMaxPatchCount(); + + mAABBManager->reallocateChangedAABBMgActorHandleMap(getElementIDPool().getMaxID()); + + //mNPhaseCore->processPersistentContactEvents(outputs, continuation); + + PxvNphaseImplementationContext* nphase = mLLContext->getNphaseImplementationContext(); + + mDynamicsContext->update(*mSimpleIslandManager, continuation, &mProcessLostContactsTask, + nphase, maxPatchCount, mMaxNbArticulationLinks, mDt, mGravity, mAABBManager->getChangedAABBMgActorHandleMap()); + + mSimpleIslandManager->clearDestroyedEdges(); + + mProcessLostContactsTask3.removeReference(); + mProcessLostContactsTask2.removeReference(); + mProcessLostContactsTask.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processLostContacts(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sc::Scene::processLostContacts", mContextId); + + mProcessNarrowPhaseLostTouchTasks.setContinuation(continuation); + mProcessNarrowPhaseLostTouchTasks.removeReference(); + + //mLostTouchReportsTask.setContinuation(&mProcessLostContactsTask3); + mProcessNPLostTouchEvents.setContinuation(continuation); + mProcessNPLostTouchEvents.removeReference(); + + { + PX_PROFILE_ZONE("Sim.findInteractionsPtrs", mContextId); + + Bp::AABBManagerBase* aabbMgr = mAABBManager; + PxU32 destroyedOverlapCount; + Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + while(destroyedOverlapCount--) + { + ElementSim* volume0 = reinterpret_cast(p->mUserData0); + ElementSim* volume1 = reinterpret_cast(p->mUserData1); + + // PT: this looks useless on lost pairs but it is used in processLostContacts2 and processLostContacts3 + // PT: it seems very questionable to store this within the BP structures at this point. If anything + // we should have stored that there when the overlap was created, and we wouldn't have to look for the + // interaction here. + p->mPairUserData = mNPhaseCore->findInteraction(volume0, volume1); + p++; + } + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processNarrowPhaseLostTouchEventsIslands(PxBaseTask*) +{ + PX_PROFILE_ZONE("Sc::Scene.islandLostTouches", mContextId); + + const PxU32 count = mTouchLostEvents.size(); + for(PxU32 i=0; i setEdgeDisconnected(si->getEdgeIndex()); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::addToLostTouchList(ActorSim& body1, ActorSim& body2) +{ + PX_ASSERT(!body1.isStaticRigid()); + PX_ASSERT(!body2.isStaticRigid()); + SimpleBodyPair p = { &body1, &body2, body1.getActorID(), body2.getActorID() }; + mLostTouchPairs.pushBack(p); +} + +void Sc::Scene::processNarrowPhaseLostTouchEvents(PxBaseTask*) +{ + PX_PROFILE_ZONE("Sc::Scene.processNarrowPhaseLostTouchEvents", mContextId); + + PxvNphaseImplementationContext* ctx = mLLContext->getNphaseImplementationContext(); + + PxsContactManagerOutputIterator outputs = ctx->getContactManagerOutputs(); + const PxU32 count = mTouchLostEvents.size(); + for(PxU32 i=0; imanagerLostTouch(0, true, outputs) && !si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) + addToLostTouchList(si->getShape0().getActor(), si->getShape1().getActor()); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processLostContacts2(PxBaseTask* continuation) +{ + mDestroyManagersTask.setContinuation(continuation); + mLostTouchReportsTask.setContinuation(&mDestroyManagersTask); + mLostTouchReportsTask.removeReference(); + + mUnregisterInteractionsTask.setContinuation(continuation); + mUnregisterInteractionsTask.removeReference(); + + { + PX_PROFILE_ZONE("Sim.clearIslandData", mContextId); + + Bp::AABBManagerBase* aabbMgr = mAABBManager; + PxU32 destroyedOverlapCount; + { + Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + while(destroyedOverlapCount--) + { + ElementSimInteraction* pair = reinterpret_cast(p->mPairUserData); + if(pair) + { + if(pair->getType() == InteractionType::eOVERLAP) + { + ShapeInteraction* si = static_cast(pair); + si->clearIslandGenData(); + } + } + p++; + } + } + } + + mDestroyManagersTask.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::lostTouchReports(PxBaseTask*) +{ + PX_PROFILE_ZONE("Sim.lostTouchReports", mContextId); + + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + + mNPhaseCore->lockReports(); + { + PxU32 destroyedOverlapCount; + const Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + while(destroyedOverlapCount--) + { + if(p->mPairUserData) + { + ElementSimInteraction* elemInteraction = reinterpret_cast(p->mPairUserData); + if(elemInteraction->getType() == InteractionType::eOVERLAP) + mNPhaseCore->lostTouchReports(static_cast(elemInteraction), PxU32(PairReleaseFlag::eWAKE_ON_LOST_TOUCH), NULL, 0, outputs); + } + p++; + } + } + mNPhaseCore->unlockReports(); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::unregisterInteractions(PxBaseTask*) +{ + PX_PROFILE_ZONE("Sim.unregisterInteractions", mContextId); + + PxU32 destroyedOverlapCount; + const Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + + while(destroyedOverlapCount--) + { + if(p->mPairUserData) + { + ElementSimInteraction* elemInteraction = reinterpret_cast(p->mPairUserData); + if(elemInteraction->getType() == InteractionType::eOVERLAP || elemInteraction->getType() == InteractionType::eMARKER) + unregisterInteraction(elemInteraction); + } + p++; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::destroyManagers(PxBaseTask*) +{ + PX_PROFILE_ZONE("Sim.destroyManagers", mContextId); + + mPostThirdPassIslandGenTask.setContinuation(mProcessLostContactsTask3.getContinuation()); + + mSimpleIslandManager->thirdPassIslandGen(&mPostThirdPassIslandGenTask); + + PxU32 destroyedOverlapCount; + const Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + + while(destroyedOverlapCount--) + { + if(p->mPairUserData) + { + ElementSimInteraction* elemInteraction = reinterpret_cast(p->mPairUserData); + if(elemInteraction->getType() == InteractionType::eOVERLAP) + { + ShapeInteraction* si = static_cast(elemInteraction); + if(si->getContactManager()) + si->destroyManager(); + } + } + p++; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::processLostContacts3(PxBaseTask* /*continuation*/) +{ + { + PX_PROFILE_ZONE("Sim.processLostOverlapsStage2", mContextId); + + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + + Bp::AABBManagerBase* aabbMgr = mAABBManager; + PxU32 destroyedOverlapCount; + + // PT: for regular shapes + { + const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + while(destroyedOverlapCount--) + { + ElementSim* volume0 = reinterpret_cast(p->mUserData0); + ElementSim* volume1 = reinterpret_cast(p->mUserData1); + + mNPhaseCore->onOverlapRemoved(volume0, volume1, false, p->mPairUserData, outputs); + p++; + } + } + + // PT: for triggers + { + const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eTRIGGER, destroyedOverlapCount); + while(destroyedOverlapCount--) + { + ElementSim* volume0 = reinterpret_cast(p->mUserData0); + ElementSim* volume1 = reinterpret_cast(p->mUserData1); + + mNPhaseCore->onOverlapRemoved(volume0, volume1, false, NULL, outputs); + p++; + } + } + + aabbMgr->freeBuffers(); + } + + mPostThirdPassIslandGenTask.removeReference(); +} + +/////////////////////////////////////////////////////////////////////////////// + +/*static*/ bool deactivateInteraction(Interaction* interaction, const InteractionType::Enum type); + +void Sc::Scene::postThirdPassIslandGen(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sc::Scene::postThirdPassIslandGen", mContextId); + + putObjectsToSleep(); + + { + PX_PROFILE_ZONE("Sc::Scene::putInteractionsToSleep", mContextId); + const IG::IslandSim& islandSim = mSimpleIslandManager->getSpeculativeIslandSim(); + + //KS - only deactivate contact managers based on speculative state to trigger contact gen. When the actors were deactivated based on accurate state + //joints should have been deactivated. + + const PxU32 NbTypes = 5; + const IG::Edge::EdgeType types[NbTypes] = { + IG::Edge::eCONTACT_MANAGER, + IG::Edge::eSOFT_BODY_CONTACT, + IG::Edge::eFEM_CLOTH_CONTACT, + IG::Edge::ePARTICLE_SYSTEM_CONTACT, + IG::Edge::eHAIR_SYSTEM_CONTACT }; + + for(PxU32 t = 0; t < NbTypes; ++t) + { + const PxU32 nbDeactivatingEdges = islandSim.getNbDeactivatingEdges(types[t]); + const IG::EdgeIndex* deactivatingEdgeIds = islandSim.getDeactivatingEdges(types[t]); + + for(PxU32 i = 0; i < nbDeactivatingEdges; ++i) + { + Interaction* interaction = mSimpleIslandManager->getInteraction(deactivatingEdgeIds[i]); + + if(interaction && interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) + { + if(!islandSim.getEdge(deactivatingEdgeIds[i]).isActive()) + { + const InteractionType::Enum type = interaction->getType(); + const bool proceed = deactivateInteraction(interaction, type); + if(proceed && (type < InteractionType::eTRACKED_IN_SCENE_COUNT)) + notifyInteractionDeactivated(interaction); + } + } + } + } + } + + PxvNphaseImplementationContext* implCtx = mLLContext->getNphaseImplementationContext(); + PxsContactManagerOutputIterator outputs = implCtx->getContactManagerOutputs(); + mNPhaseCore->processPersistentContactEvents(outputs); +} + +/////////////////////////////////////////////////////////////////////////////// + +//This is called after solver finish +void Sc::Scene::updateSimulationController(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sim.updateSimulationController", mContextId); + + PxsTransformCache& cache = getLowLevelContext()->getTransformCache(); + Bp::BoundsArray& boundArray = getBoundsArray(); + + PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); + + mSimulationController->gpuDmabackData(cache, boundArray, changedAABBMgrActorHandles, mPublicFlags & PxSceneFlag::eENABLE_DIRECT_GPU_API); + + //for pxgdynamicscontext: copy solver body data to body core + { + PX_PROFILE_ZONE("Sim.updateBodyCore", mContextId); + mDynamicsContext->updateBodyCore(continuation); + } + //mSimulationController->update(cache, boundArray, changedAABBMgrActorHandles); + + /*mProcessLostPatchesTask.setContinuation(&mFinalizationPhase); + mProcessLostPatchesTask.removeReference();*/ +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::postSolver(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sc::Scene::postSolver", mContextId); + + PxcNpMemBlockPool& blockPool = mLLContext->getNpMemBlockPool(); + + //Merge... + mDynamicsContext->mergeResults(); + blockPool.releaseConstraintMemory(); + //Swap friction! + blockPool.swapFrictionStreams(); + + mCcdBodies.clear(); + +#if PX_ENABLE_SIM_STATS + mLLContext->getSimStats().mPeakConstraintBlockAllocations = blockPool.getPeakConstraintBlockCount(); +#else + PX_CATCH_UNDEFINED_ENABLE_SIM_STATS +#endif + + integrateKinematicPose(); + + { + const PxU32 size = mDirtyArticulationSims.size(); + ArticulationSim* const* articSims = mDirtyArticulationSims.getEntries(); + //clear the acceleration term for articulation if the application raised PxForceMode::eIMPULSE in addForce function. This change + //will make sure articulation and rigid body behave the same + const float dt = mDt; + for(PxU32 i=0; iclearAcceleration(dt); + + //clear the dirty articulation list + mDirtyArticulationSims.clear(); + } + + //afterIntegration(continuation); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::constraintProjection(PxBaseTask* /*continuation*/) +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::checkForceThresholdContactEvents(PxU32 ccdPass) +{ + PX_PROFILE_ZONE("Sim.checkForceThresholdContactEvents", mContextId); + + // Note: For contact notifications it is important that force threshold checks are done after new/lost touches have been processed + // because pairs might get added to the list processed below + + // Bodies that passed contact force threshold + + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + + ThresholdStream& thresholdStream = mDynamicsContext->getForceChangedThresholdStream(); + + const PxU32 nbThresholdElements = thresholdStream.size(); + + for(PxU32 i = 0; i< nbThresholdElements; ++i) + { + ThresholdStreamElement& elem = thresholdStream[i]; + ShapeInteraction* si = elem.shapeInteraction; + + //If there is a shapeInteraction and the shapeInteraction points to a contactManager (i.e. the CM was not destroyed in parallel with the solver) + if(si) + { + PxU32 pairFlags = si->getPairFlags(); + if(pairFlags & ShapeInteraction::CONTACT_FORCE_THRESHOLD_PAIRS) + { + si->swapAndClearForceThresholdExceeded(); + + if(elem.accumulatedForce > elem.threshold * mDt) + { + si->raiseFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_NOW); + + PX_ASSERT(si->hasTouch()); + + //If the accumulatedForce is large than the threshold in the current frame and the accumulatedForce is less than the threshold in the previous frame, + //and the user request notify for found event, we will raise eNOTIFY_THRESHOLD_FORCE_FOUND + if((!si->readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_BEFORE)) && (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND)) + si->processUserNotification(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND, 0, false, ccdPass, false, outputs); + else if(si->readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_BEFORE) && (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS)) + si->processUserNotification(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS, 0, false, ccdPass, false, outputs); + } + else + { + //If the accumulatedForce is less than the threshold in the current frame and the accumulatedForce is large than the threshold in the previous frame, + //and the user request notify for found event, we will raise eNOTIFY_THRESHOLD_FORCE_LOST + if(si->readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_BEFORE) && (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST)) + si->processUserNotification(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST, 0, false, ccdPass, false, outputs); + } + } + } + } +} + +void Sc::Scene::afterIntegration(PxBaseTask* continuation) +{ + PX_PROFILE_ZONE("Sc::Scene::afterIntegration", mContextId); + + mLLContext->getTransformCache().resetChangedState(); //Reset the changed state. If anything outside of the GPU kernels updates any shape's transforms, this will be raised again + getBoundsArray().resetChangedState(); + + PxsTransformCache& cache = getLowLevelContext()->getTransformCache(); + Bp::BoundsArray& boundArray = getBoundsArray(); + + { + PX_PROFILE_ZONE("AfterIntegration::lockStage", mContextId); + mLLContext->getLock().lock(); + + { + PX_PROFILE_ZONE("SimController", mContextId); + mSimulationController->updateScBodyAndShapeSim(cache, boundArray, continuation); + } + + const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); + + const PxU32 rigidBodyOffset = BodySim::getRigidBodyOffset(); + + const PxU32 numBodiesToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); + + const PxNodeIndex*const deactivatingIndices = islandSim.getNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); + + PxU32 previousNumBodiesToDeactivate = mNumDeactivatingNodes[IG::Node::eRIGID_BODY_TYPE]; + + { + PX_PROFILE_ZONE("AfterIntegration::deactivateStage", mContextId); + + PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); + for(PxU32 i = previousNumBodiesToDeactivate; i < numBodiesToDeactivate; i++) + { + PxsRigidBody* rigid = islandSim.getRigidBody(deactivatingIndices[i]); + BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigid) - rigidBodyOffset); + //we need to set the rigid body back to the previous pose for the deactivated objects. This emulates the previous behavior where island gen ran before the solver, ensuring + //that bodies that should be deactivated this frame never reach the solver. We now run the solver in parallel with island gen, so objects that should be deactivated this frame + //still reach the solver and are integrated. However, on the frame when they should be deactivated, we roll back to their state at the beginning of the frame to ensure that the + //user perceives the same behavior as before. + + PxsBodyCore& bodyCore = bodySim->getBodyCore().getCore(); + + //if(!islandSim.getNode(bodySim->getNodeIndex()).isActive()) + rigid->setPose(rigid->getLastCCDTransform()); + + bodySim->updateCached(&changedAABBMgrActorHandles); + updateBodySim(*bodySim); + + //solver is running in parallel with IG(so solver might solving the body which IG identify as deactivatedNodes). After we moved sleepCheck into the solver after integration, sleepChecks + //might have processed bodies that are now considered deactivated. This could have resulted in either freezing or unfreezing one of these bodies this frame, so we need to process those + //events to ensure that the SqManager's bounds arrays are consistently maintained. Also, we need to clear the frame flags for these bodies. + + if(rigid->isFreezeThisFrame()) + bodySim->freezeTransforms(&mAABBManager->getChangedAABBMgActorHandleMap()); + + //KS - the IG deactivates bodies in parallel with the solver. It appears that under certain circumstances, the solver's integration (which performs + //sleep checks) could decide that the body is no longer a candidate for sleeping on the same frame that the island gen decides to deactivate the island + //that the body is contained in. This is a rare occurrence but the behavior we want to emulate is that of IG running before solver so we should therefore + //permit the IG to make the authoritative decision over whether the body should be active or inactive. + bodyCore.wakeCounter = 0.0f; + bodyCore.linearVelocity = PxVec3(0.0f); + bodyCore.angularVelocity = PxVec3(0.0f); + + rigid->clearAllFrameFlags(); + } + } + + updateKinematicCached(continuation); + + mLLContext->getLock().unlock(); + } + + IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); + + const PxU32 nbActiveArticulations = islandSim.getNbActiveNodes(IG::Node::eARTICULATION_TYPE); + + if(nbActiveArticulations) + mSimulationController->updateArticulationAfterIntegration(mLLContext, mAABBManager, mCcdBodies, continuation, islandSim, mDt); + + const PxU32 numArticsToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eARTICULATION_TYPE); + + const PxNodeIndex*const deactivatingArticIndices = islandSim.getNodesToDeactivate(IG::Node::eARTICULATION_TYPE); + + PxU32 previousNumArticsToDeactivate = mNumDeactivatingNodes[IG::Node::eARTICULATION_TYPE]; + + for(PxU32 i = previousNumArticsToDeactivate; i < numArticsToDeactivate; ++i) + { + ArticulationSim* artic = islandSim.getArticulationSim(deactivatingArticIndices[i]); + + artic->putToSleep(); + } + + //PxU32 previousNumClothToDeactivate = mNumDeactivatingNodes[IG::Node::eFEMCLOTH_TYPE]; + //const PxU32 numClothToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eFEMCLOTH_TYPE); + //const IG::NodeIndex*const deactivatingClothIndices = islandSim.getNodesToDeactivate(IG::Node::eFEMCLOTH_TYPE); + + //for (PxU32 i = previousNumClothToDeactivate; i < numClothToDeactivate; ++i) + //{ + // FEMCloth* cloth = islandSim.getLLFEMCloth(deactivatingClothIndices[i]); + // mSimulationController->deactivateCloth(cloth); + //} + + //PxU32 previousNumSoftBodiesToDeactivate = mNumDeactivatingNodes[IG::Node::eSOFTBODY_TYPE]; + //const PxU32 numSoftBodiesToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eSOFTBODY_TYPE); + //const IG::NodeIndex*const deactivatingSoftBodiesIndices = islandSim.getNodesToDeactivate(IG::Node::eSOFTBODY_TYPE); + + //for (PxU32 i = previousNumSoftBodiesToDeactivate; i < numSoftBodiesToDeactivate; ++i) + //{ + // Dy::SoftBody* softbody = islandSim.getLLSoftBody(deactivatingSoftBodiesIndices[i]); + // printf("after Integration: Deactivating soft body %i\n", softbody->getGpuRemapId()); + // //mSimulationController->deactivateSoftbody(softbody); + // softbody->getSoftBodySim()->setActive(false, 0); + //} + + PX_PROFILE_STOP_CROSSTHREAD("Basic.dynamics", mContextId); + + checkForceThresholdContactEvents(0); +} + +/////////////////////////////////////////////////////////////////////////////// + +void Sc::Scene::fireOnAdvanceCallback() +{ + if(!mSimulationEventCallback) + return; + + const PxU32 nbPosePreviews = mPosePreviewBodies.size(); + if(!nbPosePreviews) + return; + + mClientPosePreviewBodies.clear(); + mClientPosePreviewBodies.reserve(nbPosePreviews); + + mClientPosePreviewBuffer.clear(); + mClientPosePreviewBuffer.reserve(nbPosePreviews); + + const BodySim*const* PX_RESTRICT posePreviewBodies = mPosePreviewBodies.getEntries(); + for(PxU32 i=0; i(b.getPxActor())); + // PT:: tag: scalar transform*transform + mClientPosePreviewBuffer.pushBack(c.body2World * c.getBody2Actor().getInverse()); + } + } + + const PxU32 bodyCount = mClientPosePreviewBodies.size(); + if(bodyCount) + mSimulationEventCallback->onAdvance(mClientPosePreviewBodies.begin(), mClientPosePreviewBuffer.begin(), bodyCount); +} + +void Sc::Scene::finalizationPhase(PxBaseTask* /*continuation*/) +{ + PX_PROFILE_ZONE("Sim.sceneFinalization", mContextId); + + if(mCCDContext) + { + if(mSimulationController->mGPU) // PT: skip this on CPU, see empty CPU function called in updateBodySim + { + //KS - force simulation controller to update any bodies updated by the CCD. When running GPU simulation, this would be required + //to ensure that cached body states are updated + const PxU32 nbUpdatedBodies = mCCDContext->getNumUpdatedBodies(); + PxsRigidBody*const* updatedBodies = mCCDContext->getUpdatedBodies(); + + const PxU32 rigidBodyOffset = BodySim::getRigidBodyOffset(); + + for(PxU32 a=0; a(reinterpret_cast(updatedBodies[a]) - rigidBodyOffset); + updateBodySim(*bodySim); + } + } + + mCCDContext->clearUpdatedBodies(); + } + + fireOnAdvanceCallback(); // placed here because it needs to be done after sleep check and after potential CCD passes + + checkConstraintBreakage(); // Performs breakage tests on breakable constraints + + PX_PROFILE_STOP_CROSSTHREAD("Basic.rigidBodySolver", mContextId); + + mTaskPool.clear(); + + mReportShapePairTimeStamp++; // important to do this before fetchResults() is called to make sure that delayed deleted actors/shapes get + // separate pair entries in contact reports +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/physx/source/simulationcontroller/src/ScRigidCore.cpp b/physx/source/simulationcontroller/src/ScRigidCore.cpp index 66d9b4ec8..32c572205 100644 --- a/physx/source/simulationcontroller/src/ScRigidCore.cpp +++ b/physx/source/simulationcontroller/src/ScRigidCore.cpp @@ -37,10 +37,9 @@ using namespace Sc; static ShapeSim& getSimForShape(const ShapeCore& core, const ActorSim& actorSim) { - if(core.getSim()) + if(core.getExclusiveSim()) { - //Exclusive shape. - return *core.getSim(); + return *core.getExclusiveSim(); } //Must be a shared shape. @@ -58,8 +57,7 @@ static ShapeSim& getSimForShape(const ShapeCore& core, const ActorSim& actorSim) return *reinterpret_cast(1); } -RigidCore::RigidCore(const PxActorType::Enum type) -: ActorCore(type, PxActorFlag::eVISUALIZATION, PX_DEFAULT_CLIENT, 0) +RigidCore::RigidCore(const PxActorType::Enum type) : ActorCore(type, PxActorFlag::eVISUALIZATION, PX_DEFAULT_CLIENT, 0) { } diff --git a/physx/source/simulationcontroller/src/ScScene.cpp b/physx/source/simulationcontroller/src/ScScene.cpp index c09cd9922..750170488 100644 --- a/physx/source/simulationcontroller/src/ScScene.cpp +++ b/physx/source/simulationcontroller/src/ScScene.cpp @@ -26,88 +26,61 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#define NOMINMAX - -#include "common/PxProfileZone.h" -#include "foundation/PxTime.h" #include "ScPhysics.h" #include "ScScene.h" -#include "BpAABBManager.h" #include "BpBroadPhase.h" -#include "ScStaticSim.h" #include "ScConstraintSim.h" -#include "ScConstraintProjectionManager.h" #include "ScConstraintCore.h" -#include "ScArticulationCore.h" #include "ScArticulationJointCore.h" #include "ScArticulationTendonCore.h" #include "ScArticulationSensor.h" #include "ScArticulationSim.h" #include "ScArticulationJointSim.h" -#include "foundation/PxTime.h" #include "ScArticulationTendonSim.h" #include "ScArticulationSensorSim.h" #include "ScConstraintInteraction.h" #include "ScTriggerInteraction.h" #include "ScSimStats.h" -#include "ScTriggerPairs.h" -#include "ScObjectIDTracker.h" -#include "PxvManager.h" #include "PxvGlobals.h" -#include "DyContext.h" #include "PxsCCD.h" -#include "PxsSimpleIslandManager.h" #include "ScSimulationController.h" #include "ScSqBoundsManager.h" -#include "ScElementSim.h" #if defined(__APPLE__) && defined(__POWERPC__) -#include + #include #endif #if PX_SUPPORT_GPU_PHYSX -#include "PxPhysXGpu.h" -#include "PxsKernelWrangler.h" -#include "PxsHeapMemoryAllocator.h" -#include "cudamanager/PxCudaContextManager.h" + #include "PxPhysXGpu.h" + #include "PxsKernelWrangler.h" + #include "PxsHeapMemoryAllocator.h" + #include "cudamanager/PxCudaContextManager.h" #endif #include "PxsMemoryManager.h" -//////////// - -#include "PxvNphaseImplementationContext.h" #include "ScShapeInteraction.h" -#include "ScElementInteractionMarker.h" -#include "PxsContext.h" - -#include "PxRigidDynamic.h" - -#include "PxvDynamics.h" -#include "DyFeatherstoneArticulation.h" #if PX_SUPPORT_GPU_PHYSX -#include "PxSoftBody.h" -#include "ScSoftBodySim.h" -#include "DySoftBody.h" -#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION -#include "PxFEMCloth.h" -#include "PxHairSystem.h" + #include "PxSoftBody.h" + #include "ScSoftBodySim.h" + #include "DySoftBody.h" + #if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + #include "PxFEMCloth.h" + #include "PxHairSystem.h" + #endif + #include "ScFEMClothSim.h" + #include "DyFEMCloth.h" + #include "ScParticleSystemSim.h" + #include "DyParticleSystem.h" + #include "ScHairSystemSim.h" + #include "DyHairSystem.h" #endif -#include "ScFEMClothSim.h" -#include "DyFEMCloth.h" -#include "ScParticleSystemSim.h" -#include "DyParticleSystem.h" -#include "ScHairSystemSim.h" -#include "DyHairSystem.h" -#endif - -#include "CmPtrTable.h" -#include "CmTransformUtils.h" using namespace physx; -using namespace physx::Cm; -using namespace physx::Dy; +using namespace Cm; +using namespace Dy; +using namespace Sc; PX_IMPLEMENT_OUTPUT_ERROR @@ -150,501 +123,503 @@ static const char* sFilterShaderDataMemAllocId = "SceneDesc filterShaderData"; }} -void PxcClearContactCacheStats(); void PxcDisplayContactCacheStats(); -class ScAfterIntegrationTask : public Cm::Task +static const bool gUseNewTaskAllocationScheme = false; + +namespace { -public: - static const PxU32 MaxTasks = 256; -private: - const PxNodeIndex* const mIndices; - const PxU32 mNumBodies; - PxsContext* mContext; - Context* mDynamicsContext; - PxsTransformCache& mCache; - Sc::Scene& mScene; + class ScAfterIntegrationTask : public Cm::Task + { + public: + static const PxU32 MaxTasks = 256; + private: + const PxNodeIndex* const mIndices; + const PxU32 mNumBodies; + PxsContext* mContext; + Context* mDynamicsContext; + PxsTransformCache& mCache; + Sc::Scene& mScene; -public: + public: - ScAfterIntegrationTask(const PxNodeIndex* const indices, PxU32 numBodies, PxsContext* context, Context* dynamicsContext, PxsTransformCache& cache, Sc::Scene& scene) : - Cm::Task (scene.getContextId()), - mIndices (indices), - mNumBodies (numBodies), - mContext (context), - mDynamicsContext(dynamicsContext), - mCache (cache), - mScene (scene) - { - } + ScAfterIntegrationTask(const PxNodeIndex* const indices, PxU32 numBodies, PxsContext* context, Context* dynamicsContext, PxsTransformCache& cache, Sc::Scene& scene) : + Cm::Task (scene.getContextId()), + mIndices (indices), + mNumBodies (numBodies), + mContext (context), + mDynamicsContext(dynamicsContext), + mCache (cache), + mScene (scene) + { + } - virtual void runInternal() - { - const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); + virtual void runInternal() + { + const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); - Sc::BodySim* bpUpdates[MaxTasks]; - Sc::BodySim* ccdBodies[MaxTasks]; - Sc::BodySim* activateBodies[MaxTasks]; - Sc::BodySim* deactivateBodies[MaxTasks]; - PxU32 nbBpUpdates = 0, nbCcdBodies = 0; + Sc::BodySim* bpUpdates[MaxTasks]; + Sc::BodySim* ccdBodies[MaxTasks]; + Sc::BodySim* activateBodies[MaxTasks]; + Sc::BodySim* deactivateBodies[MaxTasks]; + PxU32 nbBpUpdates = 0, nbCcdBodies = 0; - IG::SimpleIslandManager& manager = *mScene.getSimpleIslandManager(); - const IG::IslandSim& islandSim = manager.getAccurateIslandSim(); - Bp::BoundsArray& boundsArray = mScene.getBoundsArray(); + IG::SimpleIslandManager& manager = *mScene.getSimpleIslandManager(); + const IG::IslandSim& islandSim = manager.getAccurateIslandSim(); + Bp::BoundsArray& boundsArray = mScene.getBoundsArray(); - Sc::BodySim* frozen[MaxTasks], * unfrozen[MaxTasks]; - PxU32 nbFrozen = 0, nbUnfrozen = 0; - PxU32 nbActivated = 0, nbDeactivated = 0; + Sc::BodySim* frozen[MaxTasks], * unfrozen[MaxTasks]; + PxU32 nbFrozen = 0, nbUnfrozen = 0; + PxU32 nbActivated = 0, nbDeactivated = 0; - for(PxU32 i = 0; i < mNumBodies; i++) - { - PxsRigidBody* rigid = islandSim.getRigidBody(mIndices[i]); - Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigid) - rigidBodyOffset); - //This move to PxgPostSolveWorkerTask for the gpu dynamic - //bodySim->sleepCheck(mDt, mOneOverDt, mEnableStabilization); - - PxsBodyCore& bodyCore = bodySim->getBodyCore().getCore(); - //If we got in this code, then this is an active object this frame. The solver computed the new wakeCounter and we - //commit it at this stage. We need to do it this way to avoid a race condition between the solver and the island gen, where - //the island gen may have deactivated a body while the solver decided to change its wake counter. - bodyCore.wakeCounter = bodyCore.solverWakeCounter; - PxsRigidBody& llBody = bodySim->getLowLevelBody(); - - const PxIntBool isFrozen = bodySim->isFrozen(); - if(!isFrozen) + for(PxU32 i = 0; i < mNumBodies; i++) { - bpUpdates[nbBpUpdates++] = bodySim; + PxsRigidBody* rigid = islandSim.getRigidBody(mIndices[i]); + Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigid) - rigidBodyOffset); + //This move to PxgPostSolveWorkerTask for the gpu dynamic + //bodySim->sleepCheck(mDt, mOneOverDt, mEnableStabilization); + + PxsBodyCore& bodyCore = bodySim->getBodyCore().getCore(); + //If we got in this code, then this is an active object this frame. The solver computed the new wakeCounter and we + //commit it at this stage. We need to do it this way to avoid a race condition between the solver and the island gen, where + //the island gen may have deactivated a body while the solver decided to change its wake counter. + bodyCore.wakeCounter = bodyCore.solverWakeCounter; + PxsRigidBody& llBody = bodySim->getLowLevelBody(); + + const PxIntBool isFrozen = bodySim->isFrozen(); + if(!isFrozen) + { + bpUpdates[nbBpUpdates++] = bodySim; - // PT: TODO: remove duplicate "isFrozen" test inside updateCached -// bodySim->updateCached(NULL); - bodySim->updateCached(mCache, boundsArray); - } + // PT: TODO: remove duplicate "isFrozen" test inside updateCached + // bodySim->updateCached(NULL); + bodySim->updateCached(mCache, boundsArray); + } - if(llBody.isFreezeThisFrame() && isFrozen) - frozen[nbFrozen++] = bodySim; - else if(llBody.isUnfreezeThisFrame()) - unfrozen[nbUnfrozen++] = bodySim; + if(llBody.isFreezeThisFrame() && isFrozen) + frozen[nbFrozen++] = bodySim; + else if(llBody.isUnfreezeThisFrame()) + unfrozen[nbUnfrozen++] = bodySim; - if(bodyCore.mFlags & PxRigidBodyFlag::eENABLE_CCD) - ccdBodies[nbCcdBodies++] = bodySim; + if(bodyCore.mFlags & PxRigidBodyFlag::eENABLE_CCD) + ccdBodies[nbCcdBodies++] = bodySim; - if(llBody.isActivateThisFrame()) - { - PX_ASSERT(!llBody.isDeactivateThisFrame()); - activateBodies[nbActivated++] = bodySim; + if(llBody.isActivateThisFrame()) + { + PX_ASSERT(!llBody.isDeactivateThisFrame()); + activateBodies[nbActivated++] = bodySim; + } + else if(llBody.isDeactivateThisFrame()) + { + deactivateBodies[nbDeactivated++] = bodySim; + } + llBody.clearAllFrameFlags(); } - else if(llBody.isDeactivateThisFrame()) + if(nbBpUpdates) { - deactivateBodies[nbDeactivated++] = bodySim; + mCache.setChangedState(); + boundsArray.setChangedState(); } - llBody.clearAllFrameFlags(); - } - if(nbBpUpdates) - { - mCache.setChangedState(); - boundsArray.setChangedState(); - } - if(nbBpUpdates>0 || nbFrozen > 0 || nbCcdBodies>0 || nbActivated>0 || nbDeactivated>0) - { - //Write active bodies to changed actor map - mContext->getLock().lock(); - PxBitMapPinned& changedAABBMgrHandles = mScene.getAABBManager()->getChangedAABBMgActorHandleMap(); - - for(PxU32 i = 0; i < nbBpUpdates; i++) + if(nbBpUpdates>0 || nbFrozen > 0 || nbCcdBodies>0 || nbActivated>0 || nbDeactivated>0) { - // PT: ### changedMap pattern #1 - PxU32 nbElems = bpUpdates[i]->getNbElements(); - Sc::ElementSim** elems = bpUpdates[i]->getElements(); - while (nbElems--) + //Write active bodies to changed actor map + mContext->getLock().lock(); + PxBitMapPinned& changedAABBMgrHandles = mScene.getAABBManager()->getChangedAABBMgActorHandleMap(); + + for(PxU32 i = 0; i < nbBpUpdates; i++) { - Sc::ShapeSim* sim = static_cast(*elems++); - // PT: TODO: what's the difference between this test and "isInBroadphase" as used in bodySim->updateCached ? - // PT: Also, shouldn't it be "isInAABBManager" rather than BP ? - if (sim->getFlags()&PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) // TODO: need trigger shape here? - changedAABBMgrHandles.growAndSet(sim->getElementID()); + // PT: ### changedMap pattern #1 + PxU32 nbElems = bpUpdates[i]->getNbElements(); + Sc::ElementSim** elems = bpUpdates[i]->getElements(); + while (nbElems--) + { + Sc::ShapeSim* sim = static_cast(*elems++); + // PT: TODO: what's the difference between this test and "isInBroadphase" as used in bodySim->updateCached ? + // PT: Also, shouldn't it be "isInAABBManager" rather than BP ? + if (sim->getFlags()&PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) // TODO: need trigger shape here? + changedAABBMgrHandles.growAndSet(sim->getElementID()); + } } - } - PxArray& sceneCcdBodies = mScene.getCcdBodies(); - for (PxU32 i = 0; i < nbCcdBodies; i++) - sceneCcdBodies.pushBack(ccdBodies[i]); + PxArray& sceneCcdBodies = mScene.getCcdBodies(); + for (PxU32 i = 0; i < nbCcdBodies; i++) + sceneCcdBodies.pushBack(ccdBodies[i]); - for(PxU32 i=0;iisFrozen()); - frozen[i]->freezeTransforms(&changedAABBMgrHandles); - } + for(PxU32 i=0;iisFrozen()); + frozen[i]->freezeTransforms(&changedAABBMgrHandles); + } - for(PxU32 i=0;iisFrozen()); - unfrozen[i]->createSqBounds(); - } + for(PxU32 i=0;iisFrozen()); + unfrozen[i]->createSqBounds(); + } - for(PxU32 i = 0; i < nbActivated; ++i) - activateBodies[i]->notifyNotReadyForSleeping(); + for(PxU32 i = 0; i < nbActivated; ++i) + activateBodies[i]->notifyNotReadyForSleeping(); - for(PxU32 i = 0; i < nbDeactivated; ++i) - deactivateBodies[i]->notifyReadyForSleeping(); + for(PxU32 i = 0; i < nbDeactivated; ++i) + deactivateBodies[i]->notifyReadyForSleeping(); - mContext->getLock().unlock(); + mContext->getLock().unlock(); + } } - } - - virtual const char* getName() const - { - return "ScScene.afterIntegrationTask"; - } - -private: - PX_NOCOPY(ScAfterIntegrationTask) -}; -static const bool gUseNewTaskAllocationScheme = false; + virtual const char* getName() const + { + return "ScScene.afterIntegrationTask"; + } -class ScSimulationControllerCallback : public PxsSimulationControllerCallback -{ - Sc::Scene* mScene; -public: + private: + PX_NOCOPY(ScAfterIntegrationTask) + }; - ScSimulationControllerCallback(Sc::Scene* scene) : mScene(scene) + class ScSimulationControllerCallback : public PxsSimulationControllerCallback { - } + Sc::Scene* mScene; + public: + + ScSimulationControllerCallback(Sc::Scene* scene) : mScene(scene) + { + } - virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) - { - PxsContext* contextLL = mScene->getLowLevelContext(); - IG::SimpleIslandManager* islandManager = mScene->getSimpleIslandManager(); - Dy::Context* dynamicContext = mScene->getDynamicsContext(); + virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) + { + PxsContext* contextLL = mScene->getLowLevelContext(); + IG::SimpleIslandManager* islandManager = mScene->getSimpleIslandManager(); + Dy::Context* dynamicContext = mScene->getDynamicsContext(); - Cm::FlushPool& flushPool = contextLL->getTaskPool(); + Cm::FlushPool& flushPool = contextLL->getTaskPool(); - const PxU32 MaxBodiesPerTask = ScAfterIntegrationTask::MaxTasks; + const PxU32 MaxBodiesPerTask = ScAfterIntegrationTask::MaxTasks; - PxsTransformCache& cache = contextLL->getTransformCache(); + PxsTransformCache& cache = contextLL->getTransformCache(); - const IG::IslandSim& islandSim = islandManager->getAccurateIslandSim(); + const IG::IslandSim& islandSim = islandManager->getAccurateIslandSim(); - /*const*/ PxU32 numBodies = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); + /*const*/ PxU32 numBodies = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); - const PxNodeIndex*const nodeIndices = islandSim.getActiveNodes(IG::Node::eRIGID_BODY_TYPE); + const PxNodeIndex*const nodeIndices = islandSim.getActiveNodes(IG::Node::eRIGID_BODY_TYPE); - const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); + const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); - if(!gUseNewTaskAllocationScheme) - { - PxU32 nbShapes = 0; - PxU32 startIdx = 0; - for (PxU32 i = 0; i < numBodies; i++) + // PT: TASK-CREATION TAG + if(!gUseNewTaskAllocationScheme) { - if (nbShapes >= MaxBodiesPerTask) + PxU32 nbShapes = 0; + PxU32 startIdx = 0; + for (PxU32 i = 0; i < numBodies; i++) + { + if (nbShapes >= MaxBodiesPerTask) + { + ScAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScAfterIntegrationTask)), ScAfterIntegrationTask(nodeIndices + startIdx, i - startIdx, + contextLL, dynamicContext, cache, *mScene)); + + startTask(task, continuation); + + startIdx = i; + nbShapes = 0; + } + PxsRigidBody* rigid = islandSim.getRigidBody(nodeIndices[i]); + Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigid) - rigidBodyOffset); + nbShapes += PxMax(1u, bodySim->getNbShapes()); //Always add at least 1 shape in, even if the body has zero shapes because there is still some per-body overhead + } + + if (nbShapes) { - ScAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScAfterIntegrationTask)), ScAfterIntegrationTask(nodeIndices + startIdx, i - startIdx, + ScAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScAfterIntegrationTask)), ScAfterIntegrationTask(nodeIndices + startIdx, numBodies - startIdx, contextLL, dynamicContext, cache, *mScene)); - task->setContinuation(continuation); - task->removeReference(); - startIdx = i; - nbShapes = 0; + + startTask(task, continuation); } - PxsRigidBody* rigid = islandSim.getRigidBody(nodeIndices[i]); - Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigid) - rigidBodyOffset); - nbShapes += PxMax(1u, bodySim->getNbShapes()); //Always add at least 1 shape in, even if the body has zero shapes because there is still some per-body overhead } - - if (nbShapes) + else { - ScAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScAfterIntegrationTask)), ScAfterIntegrationTask(nodeIndices + startIdx, numBodies - startIdx, - contextLL, dynamicContext, cache, *mScene)); - task->setContinuation(continuation); - task->removeReference(); - } - } - else - { - // PT: - const PxU32 numCpuTasks = continuation->getTaskManager()->getCpuDispatcher()->getWorkerCount(); + // PT: + const PxU32 numCpuTasks = continuation->getTaskManager()->getCpuDispatcher()->getWorkerCount(); - PxU32 nbPerTask; - if(numCpuTasks) - nbPerTask = numBodies > numCpuTasks ? numBodies / numCpuTasks : numBodies; - else - nbPerTask = numBodies; + PxU32 nbPerTask; + if(numCpuTasks) + nbPerTask = numBodies > numCpuTasks ? numBodies / numCpuTasks : numBodies; + else + nbPerTask = numBodies; - // PT: we need to respect that limit even with a single thread, because of hardcoded buffer limits in ScAfterIntegrationTask. - if(nbPerTask>MaxBodiesPerTask) - nbPerTask = MaxBodiesPerTask; + // PT: we need to respect that limit even with a single thread, because of hardcoded buffer limits in ScAfterIntegrationTask. + if(nbPerTask>MaxBodiesPerTask) + nbPerTask = MaxBodiesPerTask; - PxU32 start = 0; - while(numBodies) - { - const PxU32 nb = numBodies < nbPerTask ? numBodies : nbPerTask; + PxU32 start = 0; + while(numBodies) + { + const PxU32 nb = numBodies < nbPerTask ? numBodies : nbPerTask; - ScAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScAfterIntegrationTask)), ScAfterIntegrationTask(nodeIndices+start, nb, - contextLL, dynamicContext, cache, *mScene)); + ScAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScAfterIntegrationTask)), ScAfterIntegrationTask(nodeIndices+start, nb, + contextLL, dynamicContext, cache, *mScene)); - start += nb; - numBodies -= nb; + start += nb; + numBodies -= nb; - task->setContinuation(continuation); - task->removeReference(); + startTask(task, continuation); + } } } - } - virtual PxU32 getNbCcdBodies() - { - return mScene->getCcdBodies().size(); - } -}; + virtual PxU32 getNbCcdBodies() + { + return mScene->getCcdBodies().size(); + } + }; -class PxgUpdateBodyAndShapeStatusTask : public Cm::Task -{ -public: - static const PxU32 MaxTasks = 2048; -private: - const PxNodeIndex* const mNodeIndices; - const PxU32 mNumBodies; - Sc::Scene& mScene; - void** mRigidBodyLL; - PxU32* mActivatedBodies; - PxU32* mDeactivatedBodies; - PxI32& mCCDBodyWriteIndex; + // PT: TODO: what is this Pxg class doing here? + class PxgUpdateBodyAndShapeStatusTask : public Cm::Task + { + public: + static const PxU32 MaxTasks = 2048; + private: + const PxNodeIndex* const mNodeIndices; + const PxU32 mNumBodies; + Sc::Scene& mScene; + void** mRigidBodyLL; + PxU32* mActivatedBodies; + PxU32* mDeactivatedBodies; + PxI32& mCCDBodyWriteIndex; -public: + public: - PxgUpdateBodyAndShapeStatusTask(const PxNodeIndex* const indices, PxU32 numBodies, void** rigidBodyLL, PxU32* activatedBodies, PxU32* deactivatedBodies, Sc::Scene& scene, PxI32& ccdBodyWriteIndex) : - Cm::Task (scene.getContextId()), - mNodeIndices (indices), - mNumBodies (numBodies), - mScene (scene), - mRigidBodyLL (rigidBodyLL), - mActivatedBodies (activatedBodies), - mDeactivatedBodies (deactivatedBodies), - mCCDBodyWriteIndex (ccdBodyWriteIndex) - { - } + PxgUpdateBodyAndShapeStatusTask(const PxNodeIndex* const indices, PxU32 numBodies, void** rigidBodyLL, PxU32* activatedBodies, PxU32* deactivatedBodies, Sc::Scene& scene, PxI32& ccdBodyWriteIndex) : + Cm::Task (scene.getContextId()), + mNodeIndices (indices), + mNumBodies (numBodies), + mScene (scene), + mRigidBodyLL (rigidBodyLL), + mActivatedBodies (activatedBodies), + mDeactivatedBodies (deactivatedBodies), + mCCDBodyWriteIndex (ccdBodyWriteIndex) + { + } - virtual void runInternal() - { - IG::SimpleIslandManager& islandManager = *mScene.getSimpleIslandManager(); - const IG::IslandSim& islandSim = islandManager.getAccurateIslandSim(); + virtual void runInternal() + { + IG::SimpleIslandManager& islandManager = *mScene.getSimpleIslandManager(); + const IG::IslandSim& islandSim = islandManager.getAccurateIslandSim(); - PxU32 nbCcdBodies = 0; + PxU32 nbCcdBodies = 0; - PxArray& sceneCcdBodies = mScene.getCcdBodies(); - Sc::BodySim* ccdBodies[MaxTasks]; + PxArray& sceneCcdBodies = mScene.getCcdBodies(); + Sc::BodySim* ccdBodies[MaxTasks]; - const size_t bodyOffset = PX_OFFSET_OF_RT(Sc::BodySim, getLowLevelBody()); + const size_t bodyOffset = PX_OFFSET_OF_RT(Sc::BodySim, getLowLevelBody()); - for(PxU32 i=0; i(mRigidBodyLL[nodeIndex]); - - PxsBodyCore* bodyCore = &rigidLL->getCore(); - bodyCore->wakeCounter = bodyCore->solverWakeCounter; - //we can set the frozen/unfrozen flag in GPU, but we have copied the internalflags - //from the solverbodysleepdata to pxsbodycore, so we just need to clear the frozen flag in here - rigidLL->clearAllFrameFlags(); - - PX_ASSERT(mActivatedBodies[nodeIndex] <= 1); - PX_ASSERT(mDeactivatedBodies[nodeIndex] <= 1); - if(mActivatedBodies[nodeIndex]) + for(PxU32 i=0; iwakeCounter > 0.0f); - islandManager.activateNode(mNodeIndices[i]); - } - else if(mDeactivatedBodies[nodeIndex]) - { - //KS - the CPU code can reset the wake counter due to lost touches in parallel with the solver, so we need to verify - //that the wakeCounter is still 0 before deactivating the node - if (bodyCore->wakeCounter == 0.0f) + const PxU32 nodeIndex = mNodeIndices[i].index(); + PxsRigidBody* rigidLL = reinterpret_cast(mRigidBodyLL[nodeIndex]); + + PxsBodyCore* bodyCore = &rigidLL->getCore(); + bodyCore->wakeCounter = bodyCore->solverWakeCounter; + //we can set the frozen/unfrozen flag in GPU, but we have copied the internalflags + //from the solverbodysleepdata to pxsbodycore, so we just need to clear the frozen flag in here + rigidLL->clearAllFrameFlags(); + + PX_ASSERT(mActivatedBodies[nodeIndex] <= 1); + PX_ASSERT(mDeactivatedBodies[nodeIndex] <= 1); + if(mActivatedBodies[nodeIndex]) { - islandManager.deactivateNode(mNodeIndices[i]); + PX_ASSERT(bodyCore->wakeCounter > 0.0f); + islandManager.activateNode(mNodeIndices[i]); + } + else if(mDeactivatedBodies[nodeIndex]) + { + //KS - the CPU code can reset the wake counter due to lost touches in parallel with the solver, so we need to verify + //that the wakeCounter is still 0 before deactivating the node + if (bodyCore->wakeCounter == 0.0f) + { + islandManager.deactivateNode(mNodeIndices[i]); + } } - } - if (bodyCore->mFlags & PxRigidBodyFlag::eENABLE_CCD) - { - PxsRigidBody* rigidBody = islandSim.getRigidBody(mNodeIndices[i]); - Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigidBody) - bodyOffset); - ccdBodies[nbCcdBodies++] = bodySim; + if (bodyCore->mFlags & PxRigidBodyFlag::eENABLE_CCD) + { + PxsRigidBody* rigidBody = islandSim.getRigidBody(mNodeIndices[i]); + Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigidBody) - bodyOffset); + ccdBodies[nbCcdBodies++] = bodySim; + } } - } - if(nbCcdBodies > 0) - { - PxI32 startIndex = PxAtomicAdd(&mCCDBodyWriteIndex, PxI32(nbCcdBodies)) - PxI32(nbCcdBodies); - for(PxU32 a = 0; a < nbCcdBodies; ++a) + if(nbCcdBodies > 0) { - sceneCcdBodies[startIndex + a] = ccdBodies[a]; + PxI32 startIndex = PxAtomicAdd(&mCCDBodyWriteIndex, PxI32(nbCcdBodies)) - PxI32(nbCcdBodies); + for(PxU32 a = 0; a < nbCcdBodies; ++a) + { + sceneCcdBodies[startIndex + a] = ccdBodies[a]; + } } } - } - - virtual const char* getName() const - { - return "ScScene.PxgUpdateBodyAndShapeStatusTask"; - } -private: - PX_NOCOPY(PxgUpdateBodyAndShapeStatusTask) -}; + virtual const char* getName() const + { + return "ScScene.PxgUpdateBodyAndShapeStatusTask"; + } -class PxgSimulationControllerCallback : public PxsSimulationControllerCallback -{ - Sc::Scene* mScene; - PxI32 mCcdBodyWriteIndex; + private: + PX_NOCOPY(PxgUpdateBodyAndShapeStatusTask) + }; -public: - PxgSimulationControllerCallback(Sc::Scene* scene) : mScene(scene), mCcdBodyWriteIndex(0) +#if PX_SUPPORT_GPU_PHYSX + // PT: TODO: what is this Pxg class doing here? + class PxgSimulationControllerCallback : public PxsSimulationControllerCallback { - } + Sc::Scene* mScene; + PxI32 mCcdBodyWriteIndex; - virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) - { - IG::SimpleIslandManager* islandManager = mScene->getSimpleIslandManager(); - PxsSimulationController* simulationController = mScene->getSimulationController(); - PxsContext* contextLL = mScene->getLowLevelContext(); - IG::IslandSim& islandSim = islandManager->getAccurateIslandSim(); - const PxU32 numBodies = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); - const PxNodeIndex*const nodeIndices = islandSim.getActiveNodes(IG::Node::eRIGID_BODY_TYPE); + public: + PxgSimulationControllerCallback(Sc::Scene* scene) : mScene(scene), mCcdBodyWriteIndex(0) + { + } - PxU32* activatedBodies = simulationController->getActiveBodies(); - PxU32* deactivatedBodies = simulationController->getDeactiveBodies(); + virtual void updateScBodyAndShapeSim(PxBaseTask* continuation) + { + IG::SimpleIslandManager* islandManager = mScene->getSimpleIslandManager(); + PxsSimulationController* simulationController = mScene->getSimulationController(); + PxsContext* contextLL = mScene->getLowLevelContext(); + IG::IslandSim& islandSim = islandManager->getAccurateIslandSim(); + const PxU32 numBodies = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); + const PxNodeIndex*const nodeIndices = islandSim.getActiveNodes(IG::Node::eRIGID_BODY_TYPE); - //PxsRigidBody** rigidBodyLL = simulationController->getRigidBodies(); - void** rigidBodyLL = simulationController->getRigidBodies(); + PxU32* activatedBodies = simulationController->getActiveBodies(); + PxU32* deactivatedBodies = simulationController->getDeactiveBodies(); - Cm::FlushPool& flushPool = contextLL->getTaskPool(); + //PxsRigidBody** rigidBodyLL = simulationController->getRigidBodies(); + void** rigidBodyLL = simulationController->getRigidBodies(); - PxArray& ccdBodies = mScene->getCcdBodies(); - ccdBodies.forceSize_Unsafe(0); - ccdBodies.reserve(numBodies); - ccdBodies.forceSize_Unsafe(numBodies); + Cm::FlushPool& flushPool = contextLL->getTaskPool(); - mCcdBodyWriteIndex = 0; + PxArray& ccdBodies = mScene->getCcdBodies(); + ccdBodies.forceSize_Unsafe(0); + ccdBodies.reserve(numBodies); + ccdBodies.forceSize_Unsafe(numBodies); - for(PxU32 i = 0; i < numBodies; i+=PxgUpdateBodyAndShapeStatusTask::MaxTasks) - { - PxgUpdateBodyAndShapeStatusTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(PxgUpdateBodyAndShapeStatusTask)), PxgUpdateBodyAndShapeStatusTask(nodeIndices + i, - PxMin(PxgUpdateBodyAndShapeStatusTask::MaxTasks, numBodies - i), rigidBodyLL, activatedBodies, deactivatedBodies, *mScene, mCcdBodyWriteIndex)); - task->setContinuation(continuation); - task->removeReference(); - } + mCcdBodyWriteIndex = 0; + + // PT: TASK-CREATION TAG + for(PxU32 i = 0; i < numBodies; i+=PxgUpdateBodyAndShapeStatusTask::MaxTasks) + { + PxgUpdateBodyAndShapeStatusTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(PxgUpdateBodyAndShapeStatusTask)), PxgUpdateBodyAndShapeStatusTask(nodeIndices + i, + PxMin(PxgUpdateBodyAndShapeStatusTask::MaxTasks, numBodies - i), rigidBodyLL, activatedBodies, deactivatedBodies, *mScene, mCcdBodyWriteIndex)); + task->setContinuation(continuation); + task->removeReference(); + } - PxU32* unfrozenShapeIndices = simulationController->getUnfrozenShapes(); - PxU32* frozenShapeIndices = simulationController->getFrozenShapes(); - const PxU32 nbFrozenShapes = simulationController->getNbFrozenShapes(); - const PxU32 nbUnfrozenShapes = simulationController->getNbUnfrozenShapes(); + PxU32* unfrozenShapeIndices = simulationController->getUnfrozenShapes(); + PxU32* frozenShapeIndices = simulationController->getFrozenShapes(); + const PxU32 nbFrozenShapes = simulationController->getNbFrozenShapes(); + const PxU32 nbUnfrozenShapes = simulationController->getNbUnfrozenShapes(); - PxsShapeSim** shapeSimsLL = simulationController->getShapeSims(); + PxsShapeSim** shapeSimsLL = simulationController->getShapeSims(); - const size_t shapeOffset = PX_OFFSET_OF_RT(Sc::ShapeSim, getLLShapeSim()); + const size_t shapeOffset = PX_OFFSET_OF_RT(Sc::ShapeSim, getLLShapeSim()); - for(PxU32 i=0; i(reinterpret_cast(shapeLL) - shapeOffset); - shape->destroySqBounds(); - } + for(PxU32 i=0; i(reinterpret_cast(shapeLL) - shapeOffset); + shape->destroySqBounds(); + } - for(PxU32 i=0; i(reinterpret_cast(shapeLL) - shapeOffset); - shape->createSqBounds(); - } + for(PxU32 i=0; i(reinterpret_cast(shapeLL) - shapeOffset); + shape->createSqBounds(); + } + if (simulationController->hasFEMCloth()) + { + //KS - technically, there's a race condition calling activateNode/deactivateNode, but we know that it is + //safe because these deactivate/activate calls came from the solver. This means that we know that the + //actors are active currently, so at most we are just clearing/setting the ready for sleeping flag. + //None of the more complex logic that touching shared state will be executed. + const PxU32 nbActivatedCloth = simulationController->getNbActivatedFEMCloth(); + Dy::FEMCloth** activatedCloths = simulationController->getActivatedFEMCloths(); + + for (PxU32 i = 0; i < nbActivatedCloth; ++i) + { + PxNodeIndex nodeIndex = activatedCloths[i]->getFEMClothSim()->getNodeIndex(); -#if PX_SUPPORT_GPU_PHYSX - if (simulationController->hasFEMCloth()) - { + islandManager->activateNode(nodeIndex); + } - //KS - technically, there's a race condition calling activateNode/deactivateNode, but we know that it is - //safe because these deactivate/activate calls came from the solver. This means that we know that the - //actors are active currently, so at most we are just clearing/setting the ready for sleeping flag. - //None of the more complex logic that touching shared state will be executed. - const PxU32 nbActivatedCloth = simulationController->getNbActivatedFEMCloth(); - Dy::FEMCloth** activatedCloths = simulationController->getActivatedFEMCloths(); + const PxU32 nbDeactivatedCloth = simulationController->getNbDeactivatedFEMCloth(); + Dy::FEMCloth** deactivatedCloths = simulationController->getDeactivatedFEMCloths(); - for (PxU32 i = 0; i < nbActivatedCloth; ++i) - { - PxNodeIndex nodeIndex = activatedCloths[i]->getFEMClothSim()->getNodeIndex(); + for (PxU32 i = 0; i < nbDeactivatedCloth; ++i) + { + PxNodeIndex nodeIndex = deactivatedCloths[i]->getFEMClothSim()->getNodeIndex(); - islandManager->activateNode(nodeIndex); + islandManager->deactivateNode(nodeIndex); + } } - const PxU32 nbDeactivatedCloth = simulationController->getNbDeactivatedFEMCloth(); - Dy::FEMCloth** deactivatedCloths = simulationController->getDeactivatedFEMCloths(); - - for (PxU32 i = 0; i < nbDeactivatedCloth; ++i) + if (simulationController->hasSoftBodies()) { - PxNodeIndex nodeIndex = deactivatedCloths[i]->getFEMClothSim()->getNodeIndex(); + //KS - technically, there's a race condition calling activateNode/deactivateNode, but we know that it is + //safe because these deactivate/activate calls came from the solver. This means that we know that the + //actors are active currently, so at most we are just clearing/setting the ready for sleeping flag. + //None of the more complex logic that touching shared state will be executed. - islandManager->deactivateNode(nodeIndex); - } - } + const PxU32 nbDeactivatedSB = simulationController->getNbDeactivatedSoftbodies(); + Dy::SoftBody** deactivatedSB = simulationController->getDeactivatedSoftbodies(); - if (simulationController->hasSoftBodies()) - { + for (PxU32 i = 0; i < nbDeactivatedSB; ++i) + { + PxNodeIndex nodeIndex = deactivatedSB[i]->getSoftBodySim()->getNodeIndex(); + + islandManager->deactivateNode(nodeIndex); + } - //KS - technically, there's a race condition calling activateNode/deactivateNode, but we know that it is - //safe because these deactivate/activate calls came from the solver. This means that we know that the - //actors are active currently, so at most we are just clearing/setting the ready for sleeping flag. - //None of the more complex logic that touching shared state will be executed. + const PxU32 nbActivatedSB = simulationController->getNbActivatedSoftbodies(); + Dy::SoftBody** activatedSB = simulationController->getActivatedSoftbodies(); - const PxU32 nbDeactivatedSB = simulationController->getNbDeactivatedSoftbodies(); - Dy::SoftBody** deactivatedSB = simulationController->getDeactivatedSoftbodies(); + for (PxU32 i = 0; i < nbActivatedSB; ++i) + { + PxNodeIndex nodeIndex = activatedSB[i]->getSoftBodySim()->getNodeIndex(); - for (PxU32 i = 0; i < nbDeactivatedSB; ++i) - { - PxNodeIndex nodeIndex = deactivatedSB[i]->getSoftBodySim()->getNodeIndex(); - - islandManager->deactivateNode(nodeIndex); + islandManager->activateNode(nodeIndex); + } } - const PxU32 nbActivatedSB = simulationController->getNbActivatedSoftbodies(); - Dy::SoftBody** activatedSB = simulationController->getActivatedSoftbodies(); - - for (PxU32 i = 0; i < nbActivatedSB; ++i) + if (simulationController->hasHairSystems()) { - PxNodeIndex nodeIndex = activatedSB[i]->getSoftBodySim()->getNodeIndex(); + // comment from KS regarding race condition applies here, too + const PxU32 nbDeactivatedHS = simulationController->getNbDeactivatedHairSystems(); + Dy::HairSystem** deactivatedHS = simulationController->getDeactivatedHairSystems(); + for (PxU32 i = 0; i < nbDeactivatedHS; ++i) + { + PxNodeIndex nodeIndex = deactivatedHS[i]->getHairSystemSim()->getNodeIndex(); + islandManager->deactivateNode(nodeIndex); + } - islandManager->activateNode(nodeIndex); + const PxU32 nbActivatedHS = simulationController->getNbActivatedHairSystems(); + Dy::HairSystem** activatedHS = simulationController->getActivatedHairSystems(); + for (PxU32 i = 0; i < nbActivatedHS; ++i) + { + PxNodeIndex nodeIndex = activatedHS[i]->getHairSystemSim()->getNodeIndex(); + islandManager->activateNode(nodeIndex); + } } } - if (simulationController->hasHairSystems()) + virtual PxU32 getNbCcdBodies() { - // comment from KS regarding race condition applies here, too - const PxU32 nbDeactivatedHS = simulationController->getNbDeactivatedHairSystems(); - Dy::HairSystem** deactivatedHS = simulationController->getDeactivatedHairSystems(); - for (PxU32 i = 0; i < nbDeactivatedHS; ++i) - { - PxNodeIndex nodeIndex = deactivatedHS[i]->getHairSystemSim()->getNodeIndex(); - islandManager->deactivateNode(nodeIndex); - } - - const PxU32 nbActivatedHS = simulationController->getNbActivatedHairSystems(); - Dy::HairSystem** activatedHS = simulationController->getActivatedHairSystems(); - for (PxU32 i = 0; i < nbActivatedHS; ++i) - { - PxNodeIndex nodeIndex = activatedHS[i]->getHairSystemSim()->getNodeIndex(); - islandManager->activateNode(nodeIndex); - } + return PxU32(mCcdBodyWriteIndex); } + }; #endif - - } - - virtual PxU32 getNbCcdBodies() - { - return PxU32(mCcdBodyWriteIndex); - } -}; +} static Bp::AABBManagerBase* createAABBManagerCPU(const PxSceneDesc& desc, Bp::BroadPhase* broadPhase, Bp::BoundsArray* boundsArray, PxFloatArrayPinned* contactDistances, PxVirtualAllocator& allocator, PxU64 contextID) { @@ -694,19 +669,12 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mSimulationController (NULL), mSimulationControllerCallback (NULL), mGravity (PxVec3(0.0f)), - mBodyGravityDirty (true), mDt (0), mOneOverDt (0), mTimeStamp (1), // PT: has to start to 1 to fix determinism bug. I don't know why yet but it works. mReportShapePairTimeStamp (0), mTriggerBufferAPI ("sceneTriggerBufferAPI"), mArticulations ("sceneArticulations"), -#if PX_SUPPORT_GPU_PHYSX - mSoftBodies ("sceneSoftBodies"), - mFEMCloths ("sceneFEMCloths"), - mParticleSystems ("sceneParticleSystems"), - mHairSystems ("sceneHairSystems"), -#endif mBrokenConstraints ("sceneBrokenConstraints"), mActiveBreakableConstraints ("sceneActiveBreakableConstraints"), mMemBlock128Pool ("PxsContext ConstraintBlock128Pool"), @@ -723,13 +691,12 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mClientPosePreviewBodies ("clientPosePreviewBodies"), mClientPosePreviewBuffer ("clientPosePreviewBuffer"), mSimulationEventCallback (NULL), - mBroadPhaseCallback (NULL), mInternalFlags (SceneInternalFlag::eSCENE_DEFAULT), mPublicFlags (desc.flags), + mAnchorCore (PxTransform(PxIdentity)), mStaticAnchor (NULL), mBatchRemoveState (NULL), mLostTouchPairs ("sceneLostTouchPairs"), - mOutOfBoundsIDs ("sceneOutOfBoundsIds"), mVisualizationParameterChanged (false), mMaxNbArticulationLinks (0), mNbRigidStatics (0), @@ -740,7 +707,6 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mFinalizationPhase (contextID, this, "ScScene.finalizationPhase"), mUpdateCCDMultiPass (contextID, this, "ScScene.updateCCDMultiPass"), mAfterIntegration (contextID, this, "ScScene.afterIntegration"), - mConstraintProjection (contextID, this, "ScScene.constraintProjection"), mPostSolver (contextID, this, "ScScene.postSolver"), mSolver (contextID, this, "ScScene.rigidBodySolver"), mUpdateBodies (contextID, this, "ScScene.updateBodies"), @@ -760,7 +726,6 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mIslandGen (contextID, this, "ScScene.islandGen"), mPreRigidBodyNarrowPhase (contextID, this, "ScScene.preRigidBodyNarrowPhase"), mSetEdgesConnectedTask (contextID, this, "ScScene.setEdgesConnectedTask"), - mFetchPatchEventsTask (contextID, this, "ScScene.fetchPatchEventsTask"), mProcessLostPatchesTask (contextID, this, "ScScene.processLostSolverPatchesTask"), mProcessFoundPatchesTask (contextID, this, "ScScene.processFoundSolverPatchesTask"), mUpdateBoundAndShapeTask (contextID, this, "ScScene.updateBoundsAndShapesTask"), @@ -790,12 +755,30 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mUseGpuBp (false), mCCDBp (false), mSimulationStage (SimulationStage::eCOMPLETE), - mTmpConstraintGroupRootBuffer (NULL), mPosePreviewBodies ("scenePosePreviewBodies"), mOverlapFilterTaskHead (NULL), mIsCollisionPhaseActive (false), mOnSleepingStateChanged (NULL) +#if PX_SUPPORT_GPU_PHYSX + ,mSoftBodies ("sceneSoftBodies"), + mFEMCloths ("sceneFEMCloths"), + mParticleSystems ("sceneParticleSystems"), + mHairSystems ("sceneHairSystems") +#endif { +#if PX_SUPPORT_GPU_PHYSX + mLLSoftBodyPool = PX_NEW(LLSoftBodyPool); + mLLFEMClothPool = PX_NEW(LLFEMClothPool); + mLLParticleSystemPool = PX_NEW(LLParticleSystemPool); + mLLHairSystemPool = PX_NEW(LLHairSystemPool); + + mWokeSoftBodyListValid = true; + mSleepSoftBodyListValid = true; + + mWokeHairSystemListValid = true; + mSleepHairSystemListValid = true; +#endif + for(PxU32 type = 0; type < InteractionType::eTRACKED_IN_SCENE_COUNT; ++type) mInteractions[type].reserve(64); @@ -816,16 +799,8 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mConstraintSimPool = PX_NEW(PxPool)("ScScene::ConstraintSim"); mConstraintInteractionPool = PX_NEW(PxPool)("ScScene::ConstraintInteraction"); mLLArticulationRCPool = PX_NEW(LLArticulationRCPool); -#if PX_SUPPORT_GPU_PHYSX - mLLSoftBodyPool = PX_NEW(LLSoftBodyPool); - mLLFEMClothPool = PX_NEW(LLFEMClothPool); - mLLParticleSystemPool = PX_NEW(LLParticleSystemPool); - mLLHairSystemPool = PX_NEW(LLHairSystemPool); -#endif mSimStateDataPool = PX_NEW(PxPool)("ScScene::SimStateData"); - mProjectionManager = PX_NEW(ConstraintProjectionManager)(); - mSqBoundsManager = PX_NEW(SqBoundsManager); mTaskManager = physx::PxTaskManager::createTaskManager(*PxGetErrorCallback(), desc.cpuDispatcher); @@ -873,7 +848,7 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : // PT: this creates a PxgMemoryManager, whose host memory allocator is a PxgCudaHostMemoryAllocatorCallback mMemoryManager = physxGpu->createGpuMemoryManager(mLLContext->getCudaContextManager()); - mGpuWranglerManagers = physxGpu->createGpuKernelWranglerManager(mLLContext->getCudaContextManager(), *PxGetErrorCallback(), desc.gpuComputeVersion); + mGpuWranglerManagers = physxGpu->getGpuKernelWranglerManager(mLLContext->getCudaContextManager()); // PT: this creates a PxgHeapMemoryAllocatorManager mHeapMemoryAllocationManager = physxGpu->createGpuHeapMemoryAllocatorManager(desc.gpuDynamicsConfig.heapCapacity, mMemoryManager, desc.gpuComputeVersion); } @@ -926,6 +901,8 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mSimpleIslandManager = PX_NEW(IG::SimpleIslandManager)(useEnhancedDeterminism, contextID); + PxvNphaseImplementationContextUsableAsFallback* cpuNphaseImplementation = createNphaseImplementationContext(*mLLContext, &mSimpleIslandManager->getAccurateIslandSim(), allocatorCallback, useGpuDynamics); + if (!useGpuDynamics) { if (desc.solverType == PxSolverType::ePGS) @@ -945,7 +922,7 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : desc.getTolerancesScale().length); } - mLLContext->setNphaseImplementationContext(createNphaseImplementationContext(*mLLContext, &mSimpleIslandManager->getAccurateIslandSim(), allocatorCallback)); + mLLContext->setNphaseImplementationContext(cpuNphaseImplementation); mSimulationControllerCallback = PX_NEW(ScSimulationControllerCallback)(this); mSimulationController = PX_NEW(SimulationController)(mSimulationControllerCallback); @@ -960,9 +937,17 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : else { #if PX_SUPPORT_GPU_PHYSX + + // TODO AD: eFORCE_READBACK is deprecated, so this this will be a direct passthrough. + bool directAPI = mPublicFlags & PxSceneFlag::eENABLE_DIRECT_GPU_API; + bool forceReadback = mPublicFlags & PxSceneFlag::eFORCE_READBACK; + + if(directAPI && forceReadback) + directAPI = false; + mDynamicsContext = PxvGetPhysXGpu(true)->createGpuDynamicsContext(mLLContext->getTaskPool(), mGpuWranglerManagers, mLLContext->getCudaContextManager(), desc.gpuDynamicsConfig, mSimpleIslandManager, desc.gpuMaxNumPartitions, desc.gpuMaxNumStaticPartitions, mEnableStabilization, useEnhancedDeterminism, desc.maxBiasCoefficient, desc.gpuComputeVersion, mLLContext->getSimStats(), - mHeapMemoryAllocationManager, !!(desc.flags & PxSceneFlag::eENABLE_FRICTION_EVERY_ITERATION), desc.solverType, desc.getTolerancesScale().length); + mHeapMemoryAllocationManager, !!(desc.flags & PxSceneFlag::eENABLE_FRICTION_EVERY_ITERATION), desc.solverType, desc.getTolerancesScale().length, directAPI); void* contactStreamBase = NULL; void* patchStreamBase = NULL; @@ -970,7 +955,6 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mDynamicsContext->getDataStreamBase(contactStreamBase, patchStreamBase, forceAndIndiceStreamBase); - PxvNphaseImplementationContextUsableAsFallback* cpuNphaseImplementation = createNphaseImplementationContext(*mLLContext, &mSimpleIslandManager->getAccurateIslandSim(), allocatorCallback); mLLContext->setNphaseFallbackImplementationContext(cpuNphaseImplementation); PxvNphaseImplementationContext* gpuNphaseImplementation = PxvGetPhysXGpu(true)->createGpuNphaseImplementationContext(*mLLContext, mGpuWranglerManagers, cpuNphaseImplementation, desc.gpuDynamicsConfig, contactStreamBase, patchStreamBase, @@ -1002,14 +986,6 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : #endif } - bool suppressReadback = mPublicFlags & PxSceneFlag::eSUPPRESS_READBACK; - bool forceReadback = mPublicFlags & PxSceneFlag::eFORCE_READBACK; - - if(suppressReadback && forceReadback) - suppressReadback = false; - - mDynamicsContext->setSuppressReadback(suppressReadback); - //Construct the bitmap of updated actors required as input to the broadphase update if(desc.limits.maxNbBodies) { @@ -1042,9 +1018,7 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mDynamicsContext->setBounceThreshold(-desc.bounceThresholdVelocity); - StaticCore* anchorCore = PX_NEW(StaticCore)(PxTransform(PxIdentity)); - - mStaticAnchor = mStaticSimPool->construct(*this, *anchorCore); + mStaticAnchor = mStaticSimPool->construct(*this, mAnchorCore); mNPhaseCore = PX_NEW(NPhaseCore)(*this, desc); @@ -1065,17 +1039,11 @@ Sc::Scene::Scene(const PxSceneDesc& desc, PxU64 contextID) : mWokeBodyListValid = true; mSleepBodyListValid = true; - mWokeSoftBodyListValid = true; - mSleepSoftBodyListValid = true; - - mWokeHairSystemListValid = true; - mSleepHairSystemListValid = true; - //load from desc: setLimits(desc.limits); // Create broad phase - setBroadPhaseCallback(desc.broadPhaseCallback); + mBroadphaseManager.setBroadPhaseCallback(desc.broadPhaseCallback); setGravity(desc.gravity); @@ -1129,19 +1097,12 @@ void Sc::Scene::release() PX_FREE(mActiveKinematicsCopy); - ///clear broken constraint list: - clearBrokenConstraintBuffer(); - PX_DELETE(mNPhaseCore); PX_FREE(mFilterShaderData); - if (mStaticAnchor) - { - StaticCore& core = mStaticAnchor->getStaticCore(); + if(mStaticAnchor) mStaticSimPool->destroy(mStaticAnchor); - delete &core; - } // Free object IDs and the deleted object id map postReportsCleanup(); @@ -1162,7 +1123,6 @@ void Sc::Scene::release() } } - PX_DELETE(mProjectionManager); PX_DELETE(mSqBoundsManager); PX_DELETE(mBoundsArray); @@ -1174,10 +1134,7 @@ void Sc::Scene::release() PX_DELETE(mBodySimPool); PX_DELETE(mLLArticulationRCPool); #if PX_SUPPORT_GPU_PHYSX - PX_DELETE(mLLSoftBodyPool); - PX_DELETE(mLLFEMClothPool); - PX_DELETE(mLLParticleSystemPool); - PX_DELETE(mLLHairSystemPool); + gpu_releasePools(); #endif mTriggerBufferExtraData->~TriggerBufferExtraData(); PX_FREE(mTriggerBufferExtraData); @@ -1201,8 +1158,7 @@ void Sc::Scene::release() PX_DELETE(mSimpleIslandManager); #if PX_SUPPORT_GPU_PHYSX - PX_DELETE(mGpuWranglerManagers); - PX_DELETE(mHeapMemoryAllocationManager); + gpu_release(); #endif PX_RELEASE(mTaskManager); @@ -1283,30 +1239,8 @@ void Sc::Scene::addToActiveList(ActorSim& actorSim) mActiveBodies.pushBack(static_cast(appendedActorCore)); // PT: will be the incoming object or the first dynamic we moved out. } #if PX_SUPPORT_GPU_PHYSX - else if (actorSim.isSoftBody()) - { - PxU32 activeListIndex = mActiveSoftBodies.size(); - actorSim.setActiveListIndex(activeListIndex); - mActiveSoftBodies.pushBack(static_cast(appendedActorCore)); - } - else if (actorSim.isFEMCloth()) - { - PxU32 activeListIndex = mActiveFEMCloths.size(); - actorSim.setActiveListIndex(activeListIndex); - mActiveFEMCloths.pushBack(static_cast(appendedActorCore)); - } - else if (actorSim.isParticleSystem()) - { - PxU32 activeListIndex = mActiveParticleSystems.size(); - actorSim.setActiveListIndex(activeListIndex); - mActiveParticleSystems.pushBack(static_cast(appendedActorCore)); - } - else if (actorSim.isHairSystem()) - { - PxU32 activeListIndex = mActiveHairSystems.size(); - actorSim.setActiveListIndex(activeListIndex); - mActiveHairSystems.pushBack(static_cast(appendedActorCore)); - } + else + gpu_addToActiveList(actorSim, appendedActorCore); #endif } @@ -1380,56 +1314,8 @@ void Sc::Scene::removeFromActiveList(ActorSim& actorSim) mActiveBodies.forceSize_Unsafe(newSize); } #if PX_SUPPORT_GPU_PHYSX - else if(actorSim.isSoftBody()) - { - const PxU32 newSoftBodySize = mActiveSoftBodies.size() - 1; - - if (removedActiveIndex != newSoftBodySize) - { - Sc::SoftBodyCore* lastBody = mActiveSoftBodies[newSoftBodySize]; - mActiveSoftBodies[removedActiveIndex] = lastBody; - lastBody->getSim()->setActiveListIndex(removedActiveIndex); - } - mActiveSoftBodies.forceSize_Unsafe(newSoftBodySize); - } - else if (actorSim.isFEMCloth()) - { - const PxU32 newFEMClothSize = mActiveFEMCloths.size() - 1; - - if (removedActiveIndex != newFEMClothSize) - { - Sc::FEMClothCore* lastBody = mActiveFEMCloths[newFEMClothSize]; - mActiveFEMCloths[removedActiveIndex] = lastBody; - lastBody->getSim()->setActiveListIndex(removedActiveIndex); - } - mActiveFEMCloths.forceSize_Unsafe(newFEMClothSize); - } - else if (actorSim.isParticleSystem()) - { - - const PxU32 newParticleSystemSize = mActiveParticleSystems.size() - 1; - - if (removedActiveIndex != newParticleSystemSize) - { - Sc::ParticleSystemCore* lastBody = mActiveParticleSystems[newParticleSystemSize]; - mActiveParticleSystems[removedActiveIndex] = lastBody; - lastBody->getSim()->setActiveListIndex(removedActiveIndex); - } - mActiveParticleSystems.forceSize_Unsafe(newParticleSystemSize); - - } - else if (actorSim.isHairSystem()) - { - const PxU32 newHairSystemSize = mActiveHairSystems.size() - 1; - - if (removedActiveIndex != newHairSystemSize) - { - Sc::HairSystemCore* lastHairSystem = mActiveHairSystems[newHairSystemSize]; - mActiveHairSystems[removedActiveIndex] = lastHairSystem; - lastHairSystem->getSim()->setActiveListIndex(removedActiveIndex); - } - mActiveHairSystems.forceSize_Unsafe(newHairSystemSize); - } + else + gpu_removeFromActiveList(actorSim, removedActiveIndex); #endif } @@ -1475,7 +1361,7 @@ void Sc::Scene::swapInActiveBodyList(BodySim& body) /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void Sc::Scene::registerInteraction(Interaction* interaction, bool active) +void Sc::Scene::registerInteraction(ElementSimInteraction* interaction, bool active) { const InteractionType::Enum type = interaction->getType(); const PxU32 sceneArrayIndex = mInteractions[type].size(); @@ -1488,11 +1374,13 @@ void Sc::Scene::registerInteraction(Interaction* interaction, bool active) swapInteractionArrayIndices(sceneArrayIndex, mActiveInteractionCount[type], type); mActiveInteractionCount[type]++; } + + mNPhaseCore->registerInteraction(interaction); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void Sc::Scene::unregisterInteraction(Interaction* interaction) +void Sc::Scene::unregisterInteraction(ElementSimInteraction* interaction) { const InteractionType::Enum type = interaction->getType(); const PxU32 sceneArrayIndex = interaction->getInteractionId(); @@ -1509,15 +1397,17 @@ void Sc::Scene::unregisterInteraction(Interaction* interaction) if (mActiveInteractionCount[type]unregisterInteraction(interaction); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Sc::Scene::swapInteractionArrayIndices(PxU32 id1, PxU32 id2, InteractionType::Enum type) { - PxArray& interArray = mInteractions[type]; - Interaction* interaction1 = interArray[id1]; - Interaction* interaction2 = interArray[id2]; + PxArray& interArray = mInteractions[type]; + ElementSimInteraction* interaction1 = interArray[id1]; + ElementSimInteraction* interaction2 = interArray[id2]; interArray[id1] = interaction2; interArray[id2] = interaction1; interaction1->setInteractionId(id2); @@ -1526,13 +1416,6 @@ void Sc::Scene::swapInteractionArrayIndices(PxU32 id1, PxU32 id2, InteractionTyp /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -PxReal Sc::Scene::getLengthScale() const -{ - return mDynamicsContext->getLengthScale(); -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - void Sc::Scene::notifyInteractionActivated(Interaction* interaction) { PX_ASSERT((interaction->getType() == InteractionType::eOVERLAP) || (interaction->getType() == InteractionType::eTRIGGER)); @@ -1640,66 +1523,21 @@ void Sc::Scene::setFilterShaderData(const void* data, PxU32 dataSize) } } -void Sc::Scene::setPublicFlags(PxSceneFlags flags) -{ - mPublicFlags = flags; - mDynamicsContext->setSuppressReadback(flags & PxSceneFlag::eSUPPRESS_READBACK); -} - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void Sc::Scene::prepareCollide() -{ - mReportShapePairTimeStamp++; // deleted actors/shapes should get separate pair entries in contact reports - mContactReportsNeedPostSolverVelocity = false; - - getRenderBuffer().clear(); - - // Clear broken constraint list: - clearBrokenConstraintBuffer(); - - // Update from visualization parameters - if(mVisualizationParameterChanged) - { - mVisualizationParameterChanged = false; - - // Update SIPs if visualization is enabled - if( getVisualizationParameter(PxVisualizationParameter::eCONTACT_POINT) || getVisualizationParameter(PxVisualizationParameter::eCONTACT_NORMAL) || - getVisualizationParameter(PxVisualizationParameter::eCONTACT_ERROR) || getVisualizationParameter(PxVisualizationParameter::eCONTACT_FORCE)) - mInternalFlags |= SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_VISUALIZATION; - } - - visualizeStartStep(); - - PxcClearContactCacheStats(); -} - -void Sc::Scene::simulate(PxReal timeStep, PxBaseTask* continuation) +//stepSetup is called in solve, but not collide +void Sc::Scene::stepSetupSolve(PxBaseTask* continuation) { - if(timeStep != 0.0f) - { - mDt = timeStep; - mOneOverDt = 0.0f < mDt ? 1.0f/mDt : 0.0f; - mDynamicsContext->setDt(mDt); - - mAdvanceStep.setContinuation(continuation); - - prepareCollide(); - stepSetupCollide(&mAdvanceStep); - - mCollideStep.setContinuation(&mAdvanceStep); + PX_PROFILE_ZONE("Sim.stepSetupSolve", mContextId); - mAdvanceStep.removeReference(); - mCollideStep.removeReference(); - } + kinematicsSetup(continuation); } void Sc::Scene::advance(PxReal timeStep, PxBaseTask* continuation) { if(timeStep != 0.0f) { - mDt = timeStep; - mOneOverDt = 0.0f < mDt ? 1.0f/mDt : 0.0f; + setElapsedTime(timeStep); mAdvanceStep.setContinuation(continuation); @@ -1709,21 +1547,10 @@ void Sc::Scene::advance(PxReal timeStep, PxBaseTask* continuation) } } -void Sc::Scene::setBounceThresholdVelocity(const PxReal t) -{ - mDynamicsContext->setBounceThreshold(-t); -} - -PxReal Sc::Scene::getBounceThresholdVelocity() const -{ - return -mDynamicsContext->getBounceThreshold(); -} - void Sc::Scene::collide(PxReal timeStep, PxBaseTask* continuation) { mDt = timeStep; - prepareCollide(); stepSetupCollide(continuation); mLLContext->beginUpdate(); @@ -1732,27 +1559,14 @@ void Sc::Scene::collide(PxReal timeStep, PxBaseTask* continuation) mCollideStep.removeReference(); } -PxSolverType::Enum Sc::Scene::getSolverType() const -{ - return mDynamicsContext->getSolverType(); -} - -void Sc::Scene::setFrictionType(PxFrictionType::Enum model) -{ - mDynamicsContext->setFrictionType(model); -} - -PxFrictionType::Enum Sc::Scene::getFrictionType() const -{ - return mDynamicsContext->getFrictionType(); -} - void Sc::Scene::endSimulation() { // Handle user contact filtering // Note: Do this before the contact callbacks get fired since the filter callback might // trigger contact reports (touch lost due to re-filtering) + mBroadphaseManager.prepareOutOfBoundsCallbacks(mAABBManager); + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); mNPhaseCore->fireCustomFilteringCallbacks(outputs); @@ -1773,7 +1587,15 @@ void Sc::Scene::endSimulation() mAABBManager->releaseDeferredAggregateIds(); #endif - endStep(); // - Update time stamps + // End step / update time stamps + { + mTimeStamp++; + // INVALID_SLEEP_COUNTER is 0xffffffff. Therefore the last bit is masked. Look at Body::isForcedToSleep() for example. + // if(timeStamp==PX_INVALID_U32) timeStamp = 0; // Reserve INVALID_ID for something else + mTimeStamp &= 0x7fffffff; + + mReportShapePairTimeStamp++; // to make sure that deleted shapes/actors after fetchResults() create new report pairs + } PxcDisplayContactCacheStats(); } @@ -1798,9 +1620,10 @@ void Sc::Scene::flush(bool sendPendingReports) mTriggerBufferAPI.reset(); mTriggerBufferExtraData->reset(); - clearBrokenConstraintBuffer(); mBrokenConstraints.reset(); + mBroadphaseManager.flush(mAABBManager); + clearSleepWakeBodies(); //!!! If we send out these reports on flush then this would not be necessary mActorIDTracker->reset(); @@ -1837,23 +1660,7 @@ void Sc::Scene::setSimulationEventCallback(PxSimulationEventCallback* callback) } #if PX_SUPPORT_GPU_PHYSX - SoftBodyCore* const* sleepingSoftBodies = mSleepSoftBodies.getEntries(); - for (PxU32 i = 0; i < mSleepSoftBodies.size(); i++) - { - sleepingSoftBodies[i]->getSim()->raiseInternalFlag(BodySim::BF_SLEEP_NOTIFY); - } - - //FEMClothCore* const* sleepingFEMCloths = mSleepFEMCloths.getEntries(); - //for (PxU32 i = 0; i < mSleepFEMCloths.size(); i++) - //{ - // sleepingFEMCloths[i]->getSim()->raiseInternalFlag(BodySim::BF_SLEEP_NOTIFY); - //} - - HairSystemCore* const* sleepingHairSystems = mSleepHairSystems.getEntries(); - for (PxU32 i = 0; i < mSleepHairSystems.size(); i++) - { - sleepingHairSystems[i]->getSim()->raiseInternalFlag(BodySim::BF_SLEEP_NOTIFY); - } + gpu_setSimulationEventCallback(callback); #endif } @@ -1865,52 +1672,8 @@ PxSimulationEventCallback* Sc::Scene::getSimulationEventCallback() const return mSimulationEventCallback; } -//CCD -void Sc::Scene::setCCDContactModifyCallback(PxCCDContactModifyCallback* callback) -{ - mCCDContext->setCCDContactModifyCallback(callback); -} - -//CCD -PxCCDContactModifyCallback* Sc::Scene::getCCDContactModifyCallback() const -{ - return mCCDContext->getCCDContactModifyCallback(); -} - -//CCD -void Sc::Scene::setCCDMaxPasses(PxU32 ccdMaxPasses) -{ - mCCDContext->setCCDMaxPasses(ccdMaxPasses); -} - -//CCD -PxU32 Sc::Scene::getCCDMaxPasses() const -{ - return mCCDContext->getCCDMaxPasses(); -} - -//CCD -void Sc::Scene::setCCDThreshold(PxReal t) -{ - mCCDContext->setCCDThreshold(t); -} - -//CCD -PxReal Sc::Scene::getCCDThreshold() const -{ - return mCCDContext->getCCDThreshold(); -} - void Sc::Scene::removeBody(BodySim& body) //this also notifies any connected joints! { - ConstraintGroupNode* node = body.getConstraintGroup(); - if (node) - { - //invalidate the constraint group: - //this adds all constraints of the group to the dirty list such that groups get re-generated next frame - getProjectionManager().invalidateGroup(*node, NULL); - } - BodyCore& core = body.getBodyCore(); // Remove from sleepBodies array @@ -1983,109 +1746,12 @@ void Sc::Scene::removeConstraint(ConstraintCore& constraint) mConstraintMap.erase(PxPair(bSim, bSim1)); } - BodySim* b = cSim->getAnyBody(); - ConstraintGroupNode* n = b->getConstraintGroup(); - - if (n) - getProjectionManager().invalidateGroup(*n, cSim); mConstraintSimPool->destroy(cSim); } mConstraints.erase(&constraint); } -#if PX_SUPPORT_GPU_PHYSX -void Sc::Scene::addSoftBody(SoftBodyCore& softBody) -{ - SoftBodySim* sim = PX_NEW(SoftBodySim)(softBody, *this); - - if (sim && (sim->getLowLevelSoftBody() == NULL)) - { - PX_DELETE(sim); - return; - } - - mSoftBodies.insert(&softBody); - mStats->gpuMemSizeSoftBodies += softBody.getGpuMemStat(); -} - -void Sc::Scene::removeSoftBody(SoftBodyCore& softBody) -{ - SoftBodySim* a = softBody.getSim(); - PX_DELETE(a); - mSoftBodies.erase(&softBody); - mStats->gpuMemSizeSoftBodies -= softBody.getGpuMemStat(); -} - -void Sc::Scene::addFEMCloth(FEMClothCore& femCloth) -{ - FEMClothSim* sim = PX_NEW(FEMClothSim)(femCloth, *this); - - if (sim && (sim->getLowLevelFEMCloth() == NULL)) - { - PX_DELETE(sim); - return; - } - - mFEMCloths.insert(&femCloth); - mStats->gpuMemSizeFEMCloths += femCloth.getGpuMemStat(); -} - -void Sc::Scene::removeFEMCloth(FEMClothCore& femCloth) -{ - FEMClothSim* a = femCloth.getSim(); - PX_DELETE(a); - mFEMCloths.erase(&femCloth); - mStats->gpuMemSizeFEMCloths -= femCloth.getGpuMemStat(); -} - -void Sc::Scene::addParticleSystem(ParticleSystemCore& particleSystem) -{ - ParticleSystemSim* sim = PX_NEW(ParticleSystemSim)(particleSystem, *this); - - Dy::ParticleSystem* dyParticleSystem = sim->getLowLevelParticleSystem(); - - if (sim && (dyParticleSystem == NULL)) - { - PX_DELETE(sim); - return; - } - - mParticleSystems.insert(&particleSystem); - mStats->gpuMemSizeParticles += particleSystem.getShapeCore().getGpuMemStat(); -} - -void Sc::Scene::removeParticleSystem(ParticleSystemCore& particleSystem) -{ - ParticleSystemSim* a = particleSystem.getSim(); - PX_DELETE(a); - mParticleSystems.erase(&particleSystem); - mStats->gpuMemSizeParticles -= particleSystem.getShapeCore().getGpuMemStat(); -} - -void Sc::Scene::addHairSystem(HairSystemCore& hairSystem) -{ - HairSystemSim* sim = PX_NEW(HairSystemSim)(hairSystem, *this); - - if (sim && (sim->getLowLevelHairSystem() == NULL)) - { - PX_DELETE(sim); - return; - } - - mHairSystems.insert(&hairSystem); - mStats->gpuMemSizeHairSystems += hairSystem.getShapeCore().getGpuMemStat(); -} - -void Sc::Scene::removeHairSystem(HairSystemCore& hairSystem) -{ - HairSystemSim* sim = hairSystem.getSim(); - PX_DELETE(sim); - mHairSystems.erase(&hairSystem); - mStats->gpuMemSizeHairSystems -= hairSystem.getShapeCore().getGpuMemStat(); -} -#endif - void Sc::Scene::addArticulation(ArticulationCore& articulation, BodyCore& root) { ArticulationSim* sim = PX_NEW(ArticulationSim)(articulation, *this, root); @@ -2177,4405 +1843,1261 @@ void Sc::Scene::removeArticulationSimControl(Sc::ArticulationCore& core) mSimulationController->releaseArticulation(sim->getLowLevelArticulation(), sim->getIslandNodeIndex()); } -#if PX_SUPPORT_GPU_PHYSX -void Sc::Scene::addSoftBodySimControl(Sc::SoftBodyCore& core) +void* Sc::Scene::allocateConstraintBlock(PxU32 size) { - Sc::SoftBodySim* sim = core.getSim(); - - if (sim) - { - mSimulationController->addSoftBody(sim->getLowLevelSoftBody(), sim->getNodeIndex()); - - mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), sim->getPxActor()); - } + if(size<=128) + return mMemBlock128Pool.construct(); + else if(size<=256) + return mMemBlock256Pool.construct(); + else if(size<=384) + return mMemBlock384Pool.construct(); + else + return PX_ALLOC(size, "ConstraintBlock"); } -void Sc::Scene::removeSoftBodySimControl(Sc::SoftBodyCore& core) +void Sc::Scene::deallocateConstraintBlock(void* ptr, PxU32 size) { - Sc::SoftBodySim* sim = core.getSim(); - - if (sim) - { - mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID()); - mSimulationController->releaseSoftBody(sim->getLowLevelSoftBody()); - } + if(size<=128) + mMemBlock128Pool.destroy(reinterpret_cast(ptr)); + else if(size<=256) + mMemBlock256Pool.destroy(reinterpret_cast(ptr)); + else if(size<=384) + mMemBlock384Pool.destroy(reinterpret_cast(ptr)); + else + PX_FREE(ptr); } -void Sc::Scene::addFEMClothSimControl(Sc::FEMClothCore& core) +void Sc::Scene::postReportsCleanup() { - Sc::FEMClothSim* sim = core.getSim(); + mElementIDPool->processPendingReleases(); + mElementIDPool->clearDeletedIDMap(); - if (sim) - { - mSimulationController->addFEMCloth(sim->getLowLevelFEMCloth(), sim->getNodeIndex()); + mActorIDTracker->processPendingReleases(); + mActorIDTracker->clearDeletedIDMap(); - mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), sim->getPxActor(), true); - } + mConstraintIDTracker->processPendingReleases(); + mConstraintIDTracker->clearDeletedIDMap(); + + mSimulationController->flush(); } -void Sc::Scene::removeFEMClothSimControl(Sc::FEMClothCore& core) -{ - Sc::FEMClothSim* sim = core.getSim(); +PX_COMPILE_TIME_ASSERT(sizeof(PxTransform32)==sizeof(PxsCachedTransform)); - if (sim) - { - mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), true); - mSimulationController->releaseFEMCloth(sim->getLowLevelFEMCloth()); - } -} - -void Sc::Scene::addParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId) +// PT: TODO: move this out of Sc? this is only called by Np +void Sc::Scene::syncSceneQueryBounds(SqBoundsSync& sync, SqRefFinder& finder) { - mSimulationController->addParticleFilter(sim.getLowLevelSoftBody(), core->getSim()->getLowLevelParticleSystem(), - particleId, userBufferId, tetId); -} + const PxsTransformCache& cache = mLLContext->getTransformCache(); -void Sc::Scene::removeParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId) -{ - mSimulationController->removeParticleFilter(sim.getLowLevelSoftBody(), core->getSim()->getLowLevelParticleSystem(), particleId, userBufferId, tetId); + mSqBoundsManager->syncBounds(sync, finder, mBoundsArray->begin(), reinterpret_cast(cache.getTransforms()), mContextId, mDirtyShapeSimMap); } -PxU32 Sc::Scene::addParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId, const PxVec4& barycentric) -{ - PxNodeIndex nodeIndex = core->getSim()->getNodeIndex(); +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - PxU32 handle = mSimulationController->addParticleAttachment(sim.getLowLevelSoftBody(), core->getSim()->getLowLevelParticleSystem(), - particleId, userBufferId, tetId, barycentric, sim.isActive()); +void Sc::Scene::resizeReleasedBodyIDMaps(PxU32 maxActors, PxU32 numActors) +{ + mLostTouchPairsDeletedBodyIDs.resize(maxActors); + mActorIDTracker->resizeDeletedIDMap(maxActors,numActors); + mElementIDPool->resizeDeletedIDMap(maxActors,numActors); +} - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; +void Sc::Scene::finalizeContactStreamAndCreateHeader(PxContactPairHeader& header, const ActorPairReport& aPair, ContactStreamManager& cs, PxU32 removedShapeTestMask) +{ + PxU8* stream = mNPhaseCore->getContactReportPairData(cs.bufferIndex); + PxU32 streamManagerFlag = cs.getFlags(); + ContactShapePair* contactPairs = cs.getShapePairs(stream); + const PxU16 nbShapePairs = cs.currentPairCount; + PX_ASSERT(nbShapePairs > 0); - if (interaction.mCount == 0) + if (streamManagerFlag & removedShapeTestMask) { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eSOFT_BODY_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); - interaction.mIndex = edgeIdx; + // At least one shape of this actor pair has been deleted. Need to traverse the contact buffer, + // find the pairs which contain deleted shapes and set the flags accordingly. + + ContactStreamManager::convertDeletedShapesInContactStream(contactPairs, nbShapePairs, getElementIDPool()); } - interaction.mCount++; - return handle; -} + PX_ASSERT(contactPairs); -void Sc::Scene::removeParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 handle) -{ - PxNodeIndex nodeIndex = core->getSim()->getNodeIndex(); - - mSimulationController->removeParticleAttachment(sim.getLowLevelSoftBody(), handle); + ObjectIDTracker& ActorIDTracker = getActorIDTracker(); + header.actors[0] = aPair.getPxActorA(); + header.actors[1] = aPair.getPxActorB(); + PxU16 headerFlags = 0; + if (ActorIDTracker.isDeletedID(aPair.getActorAID())) + headerFlags |= PxContactPairHeaderFlag::eREMOVED_ACTOR_0; + if (ActorIDTracker.isDeletedID(aPair.getActorBID())) + headerFlags |= PxContactPairHeaderFlag::eREMOVED_ACTOR_1; + header.flags = PxContactPairHeaderFlags(headerFlags); + header.pairs = reinterpret_cast(contactPairs); + header.nbPairs = nbShapePairs; - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) + PxU16 extraDataSize = cs.extraDataSize; + if (!extraDataSize) + header.extraDataStream = NULL; + else { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); + PX_ASSERT(extraDataSize >= sizeof(ContactStreamHeader)); + extraDataSize -= sizeof(ContactStreamHeader); + header.extraDataStream = stream + sizeof(ContactStreamHeader); + + if (streamManagerFlag & ContactStreamManagerFlag::eNEEDS_POST_SOLVER_VELOCITY) + { + PX_ASSERT(!(headerFlags & PxTo16(PxContactPairHeaderFlag::eREMOVED_ACTOR_0 | PxContactPairHeaderFlag::eREMOVED_ACTOR_1))); + cs.setContactReportPostSolverVelocity(stream, aPair.getActorA(), aPair.getActorB()); + } } + header.extraDataStreamSize = extraDataSize; } -void Sc::Scene::addRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 vertId) +const PxArray& Sc::Scene::getQueuedContactPairHeaders() { - PxNodeIndex nodeIndex; + const PxU32 removedShapeTestMask = PxU32(ContactStreamManagerFlag::eTEST_FOR_REMOVED_SHAPES); - if (core) + ActorPairReport*const* actorPairs = mNPhaseCore->getContactReportActorPairs(); + PxU32 nbActorPairs = mNPhaseCore->getNbContactReportActorPairs(); + mQueuedContactPairHeaders.reserve(nbActorPairs); + mQueuedContactPairHeaders.clear(); + + for (PxU32 i = 0; i < nbActorPairs; i++) { - nodeIndex = core->getSim()->getNodeIndex(); - } + if (i < (nbActorPairs - 1)) + PxPrefetchLine(actorPairs[i + 1]); - mSimulationController->addRigidFilter(sim.getLowLevelSoftBody(), sim.getNodeIndex(), - nodeIndex, vertId); -} + ActorPairReport* aPair = actorPairs[i]; + ContactStreamManager& cs = aPair->getContactStreamManager(); + if (cs.getFlags() & ContactStreamManagerFlag::eINVALID_STREAM) + continue; -void Sc::Scene::removeRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 vertId) -{ - PxNodeIndex nodeIndex; + if (i + 1 < nbActorPairs) + PxPrefetch(&(actorPairs[i + 1]->getContactStreamManager())); - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); + PxContactPairHeader &pairHeader = mQueuedContactPairHeaders.insert(); + finalizeContactStreamAndCreateHeader(pairHeader, *aPair, cs, removedShapeTestMask); + + cs.maxPairCount = cs.currentPairCount; + cs.setMaxExtraDataSize(cs.extraDataSize); } - mSimulationController->removeRigidFilter(sim.getLowLevelSoftBody(), nodeIndex, vertId); + return mQueuedContactPairHeaders; } -PxU32 Sc::Scene::addRigidAttachment(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 vertId, const PxVec3& actorSpacePose, - PxConeLimitedConstraint* constraint) +/* +Threading: called in the context of the user thread, but only after the physics thread has finished its run +*/ +void Sc::Scene::fireQueuedContactCallbacks() { - PxNodeIndex nodeIndex; - PxsRigidBody* body = NULL; - - if (core) + if(mSimulationEventCallback) { - nodeIndex = core->getSim()->getNodeIndex(); - body = &core->getSim()->getLowLevelBody(); - } + const PxU32 removedShapeTestMask = PxU32(ContactStreamManagerFlag::eTEST_FOR_REMOVED_SHAPES); - PxU32 handle = mSimulationController->addRigidAttachment(sim.getLowLevelSoftBody(), sim.getNodeIndex(), body, - nodeIndex, vertId, actorSpacePose, constraint, sim.isActive()); + ActorPairReport*const* actorPairs = mNPhaseCore->getContactReportActorPairs(); + PxU32 nbActorPairs = mNPhaseCore->getNbContactReportActorPairs(); + for(PxU32 i=0; i < nbActorPairs; i++) + { + if (i < (nbActorPairs - 1)) + PxPrefetchLine(actorPairs[i+1]); - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + ActorPairReport* aPair = actorPairs[i]; + ContactStreamManager* cs = &aPair->getContactStreamManager(); + if (cs == NULL || cs->getFlags() & ContactStreamManagerFlag::eINVALID_STREAM) + continue; + + if (i + 1 < nbActorPairs) + PxPrefetch(&(actorPairs[i+1]->getContactStreamManager())); - if (interaction.mCount == 0) - { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eSOFT_BODY_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); - interaction.mIndex = edgeIdx; + PxContactPairHeader pairHeader; + finalizeContactStreamAndCreateHeader(pairHeader, *aPair, *cs, removedShapeTestMask); + + mSimulationEventCallback->onContact(pairHeader, pairHeader.pairs, pairHeader.nbPairs); + + // estimates for next frame + cs->maxPairCount = cs->currentPairCount; + cs->setMaxExtraDataSize(cs->extraDataSize); + } } - interaction.mCount++; - return handle; } -void Sc::Scene::removeRigidAttachment(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 handle) +PX_FORCE_INLINE void markDeletedShapes(Sc::ObjectIDTracker& idTracker, Sc::TriggerPairExtraData& tped, PxTriggerPair& pair) { - PxNodeIndex nodeIndex; - - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - } - - mSimulationController->removeRigidAttachment(sim.getLowLevelSoftBody(), handle); + PxTriggerPairFlags::InternalType flags = 0; + if (idTracker.isDeletedID(tped.shape0ID)) + flags |= PxTriggerPairFlag::eREMOVED_SHAPE_TRIGGER; + if (idTracker.isDeletedID(tped.shape1ID)) + flags |= PxTriggerPairFlag::eREMOVED_SHAPE_OTHER; - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) - { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); - } + pair.flags = PxTriggerPairFlags(flags); } -void Sc::Scene::addTetRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 tetIdx) +void Sc::Scene::fireTriggerCallbacks() { - PxNodeIndex nodeIndex; - - if (core) + // triggers + const PxU32 nbTriggerPairs = mTriggerBufferAPI.size(); + PX_ASSERT(nbTriggerPairs == mTriggerBufferExtraData->size()); + if(nbTriggerPairs) { - nodeIndex = core->getSim()->getNodeIndex(); - } + // cases to take into account: + // - no simulation/trigger shape has been removed -> no need to test shape references for removed shapes + // - simulation/trigger shapes have been removed -> test the events that have + // a marker for removed shapes set + // + const bool hasRemovedShapes = mElementIDPool->getDeletedIDCount() > 0; - mSimulationController->addTetRigidFilter(sim.getLowLevelSoftBody(), nodeIndex, tetIdx); -} + if(mSimulationEventCallback) + { + if (!hasRemovedShapes) + mSimulationEventCallback->onTrigger(mTriggerBufferAPI.begin(), nbTriggerPairs); + else + { + for(PxU32 i = 0; i < nbTriggerPairs; i++) + { + PxTriggerPair& triggerPair = mTriggerBufferAPI[i]; -void Sc::Scene::removeTetRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 tetIdx) -{ - PxNodeIndex nodeIndex; + if ((PxTriggerPairFlags::InternalType(triggerPair.flags) & TriggerPairFlag::eTEST_FOR_REMOVED_SHAPES)) + markDeletedShapes(*mElementIDPool, (*mTriggerBufferExtraData)[i], triggerPair); + } - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); + mSimulationEventCallback->onTrigger(mTriggerBufferAPI.begin(), nbTriggerPairs); + } + } } - mSimulationController->removeTetRigidFilter(sim.getLowLevelSoftBody(), nodeIndex, tetIdx); + + // PT: clear the buffer **even when there's no simulationEventCallback**. + mTriggerBufferAPI.clear(); + mTriggerBufferExtraData->clear(); } -PxU32 Sc::Scene::addTetRigidAttachment(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, - PxConeLimitedConstraint* constraint) +/* +Threading: called in the context of the user thread, but only after the physics thread has finished its run +*/ +void Sc::Scene::fireCallbacksPostSync() { - PxNodeIndex nodeIndex; - PxsRigidBody* body = NULL; + // + // Fire sleep & woken callbacks + // - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - body = &core->getSim()->getLowLevelBody(); - } - - PxU32 handle = mSimulationController->addTetRigidAttachment(sim.getLowLevelSoftBody(), body, nodeIndex, - tetIdx, barycentric, actorSpacePose, constraint, sim.isActive()); - - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + // A body should be either in the sleep or the woken list. If it is in both, remove it from the list it was + // least recently added to. - if (interaction.mCount == 0) - { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eSOFT_BODY_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); - interaction.mIndex = edgeIdx; - } - interaction.mCount++; - return handle; -} + if(!mSleepBodyListValid) + cleanUpSleepBodies(); -void Sc::Scene::addSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1) -{ - Sc::SoftBodySim& bSim = *core.getSim(); + if(!mWokeBodyListValid) + cleanUpWokenBodies(); - mSimulationController->addSoftBodyFilter(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIdx0, tetIdx1); -} +#if PX_SUPPORT_GPU_PHYSX + const PxU32 maxGpuSizeNeeded = gpu_cleanUpSleepAndWokenBodies(); +#endif -void Sc::Scene::removeSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1) -{ - Sc::SoftBodySim& bSim = *core.getSim(); - mSimulationController->removeSoftBodyFilter(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIdx0, tetIdx1); -} + if(mSimulationEventCallback || mOnSleepingStateChanged) + { + // allocate temporary data + const PxU32 nbSleep = mSleepBodies.size(); + const PxU32 nbWoken = mWokeBodies.size(); +#if PX_SUPPORT_GPU_PHYSX + const PxU32 arrSize = PxMax(PxMax(nbSleep, nbWoken), maxGpuSizeNeeded); +#else + const PxU32 arrSize = PxMax(nbSleep, nbWoken); +#endif + PxActor** actors = arrSize ? reinterpret_cast(PX_ALLOC(arrSize*sizeof(PxActor*), "PxActor*")) : NULL; + if(actors) + { + if(nbSleep) + { + PxU32 destSlot = 0; + BodyCore* const* sleepingBodies = mSleepBodies.getEntries(); + for(PxU32 i=0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) + actors[destSlot++] = body->getPxActor(); + if (mOnSleepingStateChanged) + mOnSleepingStateChanged(*static_cast(body->getPxActor()), true); + } -void Sc::Scene::addSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize) -{ - Sc::SoftBodySim& bSim = *core.getSim(); + if(destSlot && mSimulationEventCallback) + mSimulationEventCallback->onSleep(actors, destSlot); - mSimulationController->addSoftBodyFilters(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIndices0, tetIndices1, tetIndicesSize); -} + //if (PX_DBG_IS_CONNECTED()) + //{ + // for (PxU32 i = 0; i < nbSleep; ++i) + // { + // BodyCore* body = mSleepBodies[i]; + // PX_ASSERT(body->getActorType() == PxActorType::eRIGID_DYNAMIC); + // } + //} + } -void Sc::Scene::removeSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize) -{ - Sc::SoftBodySim& bSim = *core.getSim(); - mSimulationController->removeSoftBodyFilters(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIndices0, tetIndices1, tetIndicesSize); -} +#if PX_SUPPORT_GPU_PHYSX + gpu_fireOnSleepCallback(actors); +#endif -PxU32 Sc::Scene::addSoftBodyAttachment(SoftBodyCore& core, PxU32 tetIdx0, const PxVec4& tetBarycentric0, Sc::SoftBodySim& sim, PxU32 tetIdx1, const PxVec4& tetBarycentric1, - PxConeLimitedConstraint* constraint) -{ - Sc::SoftBodySim& bSim = *core.getSim(); + // do the same thing for bodies that have just woken up - PxU32 handle = mSimulationController->addSoftBodyAttachment(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIdx0, tetIdx1, - tetBarycentric0, tetBarycentric1, constraint, sim.isActive() || bSim.isActive()); + if(nbWoken) + { + PxU32 destSlot = 0; + BodyCore* const* wokenBodies = mWokeBodies.getEntries(); + for(PxU32 i=0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) + actors[destSlot++] = body->getPxActor(); + if (mOnSleepingStateChanged) + mOnSleepingStateChanged(*static_cast(body->getPxActor()), false); + } - PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + if(destSlot && mSimulationEventCallback) + mSimulationEventCallback->onWake(actors, destSlot); + } - if (interaction.mCount == 0) - { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), bSim.getNodeIndex(), NULL, IG::Edge::eSOFT_BODY_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); - interaction.mIndex = edgeIdx; +#if PX_SUPPORT_GPU_PHYSX + gpu_fireOnWakeCallback(actors); +#endif + PX_FREE(actors); + } } - interaction.mCount++; - return handle; -} - -void Sc::Scene::removeSoftBodyAttachment(SoftBodyCore& core, Sc::SoftBodySim& sim, PxU32 handle) -{ - Sc::SoftBodySim& bSim = *core.getSim(); - mSimulationController->removeSoftBodyAttachment(bSim.getLowLevelSoftBody(), handle); - - PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) - { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); - } + clearSleepWakeBodies(); } -void Sc::Scene::addClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx) +void Sc::Scene::postCallbacksPreSync() { - Sc::FEMClothSim& bSim = *core.getSim(); + PX_PROFILE_ZONE("Sim.postCallbackPreSync", mContextId); + // clear contact stream data + mNPhaseCore->clearContactReportStream(); + mNPhaseCore->clearContactReportActorPairs(false); - mSimulationController->addClothFilter(sim.getLowLevelSoftBody(), bSim.getLowLevelFEMCloth(), triIdx,tetIdx); -} + postCallbacksPreSyncKinematics(); -void Sc::Scene::removeClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx) -{ - Sc::FEMClothSim& bSim = *core.getSim(); - mSimulationController->removeClothFilter(sim.getLowLevelSoftBody(), bSim.getLowLevelFEMCloth(), triIdx, tetIdx); + releaseConstraints(true); //release constraint blocks at the end of the frame, so user can retrieve the blocks } -PxU32 Sc::Scene::addClothAttachment(Sc::FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, Sc::SoftBodySim& sim, PxU32 tetIdx, - const PxVec4& tetBarycentric, PxConeLimitedConstraint* constraint) +void Sc::Scene::getStats(PxSimulationStatistics& s) const { - Sc::FEMClothSim& bSim = *core.getSim(); + mStats->readOut(s, mLLContext->getSimStats()); + s.nbStaticBodies = mNbRigidStatics; + s.nbDynamicBodies = mNbRigidDynamics; + s.nbKinematicBodies = mNbRigidKinematic; + s.nbArticulations = mArticulations.size(); - PxU32 handle = mSimulationController->addClothAttachment(sim.getLowLevelSoftBody(), bSim.getLowLevelFEMCloth(), triIdx, triBarycentric, - tetIdx, tetBarycentric, constraint, sim.isActive()); + s.nbAggregates = mAABBManager->getNbActiveAggregates(); + for(PxU32 i=0; i pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; +#if PX_SUPPORT_GPU_PHYSX + if (mHeapMemoryAllocationManager) + { + s.gpuMemHeap = mHeapMemoryAllocationManager->getDeviceMemorySize(); - if (interaction.mCount == 0) + const PxsHeapStats& deviceHeapStats = mHeapMemoryAllocationManager->getDeviceHeapStats(); + s.gpuMemHeapBroadPhase = deviceHeapStats.stats[PxsHeapStats::eBROADPHASE]; + s.gpuMemHeapNarrowPhase = deviceHeapStats.stats[PxsHeapStats::eNARROWPHASE]; + s.gpuMemHeapSolver = deviceHeapStats.stats[PxsHeapStats::eSOLVER]; + s.gpuMemHeapArticulation = deviceHeapStats.stats[PxsHeapStats::eARTICULATION]; + s.gpuMemHeapSimulation = deviceHeapStats.stats[PxsHeapStats::eSIMULATION]; + s.gpuMemHeapSimulationArticulation = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_ARTICULATION]; + s.gpuMemHeapSimulationParticles = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_PARTICLES]; + s.gpuMemHeapSimulationSoftBody = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_SOFTBODY]; + s.gpuMemHeapSimulationFEMCloth = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_FEMCLOTH]; + s.gpuMemHeapSimulationHairSystem = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_HAIRSYSTEM]; + s.gpuMemHeapParticles = deviceHeapStats.stats[PxsHeapStats::eSHARED_PARTICLES]; + s.gpuMemHeapFEMCloths = deviceHeapStats.stats[PxsHeapStats::eSHARED_FEMCLOTH]; + s.gpuMemHeapSoftBodies = deviceHeapStats.stats[PxsHeapStats::eSHARED_SOFTBODY]; + s.gpuMemHeapHairSystems = deviceHeapStats.stats[PxsHeapStats::eSHARED_HAIRSYSTEM]; + s.gpuMemHeapOther = deviceHeapStats.stats[PxsHeapStats::eOTHER]; + } + else +#endif { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), bSim.getNodeIndex(), NULL, IG::Edge::eFEM_CLOTH_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); - interaction.mIndex = edgeIdx; + s.gpuMemHeap = 0; + s.gpuMemParticles = 0; + s.gpuMemSoftBodies = 0; + s.gpuMemFEMCloths = 0; + s.gpuMemHairSystems = 0; + s.gpuMemHeapBroadPhase = 0; + s.gpuMemHeapNarrowPhase = 0; + s.gpuMemHeapSolver = 0; + s.gpuMemHeapArticulation = 0; + s.gpuMemHeapSimulation = 0; + s.gpuMemHeapSimulationArticulation = 0; + s.gpuMemHeapSimulationParticles = 0; + s.gpuMemHeapSimulationSoftBody = 0; + s.gpuMemHeapSimulationFEMCloth = 0; + s.gpuMemHeapSimulationHairSystem = 0; + s.gpuMemHeapParticles = 0; + s.gpuMemHeapSoftBodies = 0; + s.gpuMemHeapFEMCloths = 0; + s.gpuMemHeapHairSystems = 0; + s.gpuMemHeapOther = 0; } - interaction.mCount++; - - return handle; } -void Sc::Scene::removeClothAttachment(Sc::FEMClothCore& core, Sc::SoftBodySim& sim, PxU32 handle) +void Sc::Scene::addShapes(NpShape *const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& bodySim, PxBounds3* outBounds) { - PX_UNUSED(core); - Sc::FEMClothSim& bSim = *core.getSim(); - mSimulationController->removeClothAttachment(sim.getLowLevelSoftBody(), handle); + const PxNodeIndex nodeIndex = bodySim.getNodeIndex(); + + PxvNphaseImplementationContext* context = mLLContext->getNphaseImplementationContext(); - PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) + for(PxU32 i=0;iremoveConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); + // PT: TODO: drop the offsets and let me include NpShape.h from here! This is just NpShape::getCore().... + ShapeCore& sc = *reinterpret_cast(size_t(shapes[i])+ptrOffset); + + //PxBounds3* target = uninflatedBounds ? uninflatedBounds + i : uninflatedBounds; + //mShapeSimPool->construct(sim, sc, llBody, target); + + ShapeSim* shapeSim = mShapeSimPool->construct(bodySim, sc); + mNbGeometries[sc.getGeometryType()]++; + + mSimulationController->addShape(&shapeSim->getLLShapeSim(), shapeSim->getElementID()); + + if (outBounds) + outBounds[i] = mBoundsArray->getBounds(shapeSim->getElementID()); + + //I register the shape if its either not an articulation link or if the nodeIndex has already been + //assigned. On insertion, the articulation will not have this nodeIndex correctly assigned at this stage + if (bodySim.getActorType() != PxActorType::eARTICULATION_LINK || !nodeIndex.isStaticBody()) + context->registerShape(nodeIndex, sc.getCore(), shapeSim->getElementID(), bodySim.getPxActor()); } } -void Sc::Scene::addRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 vertId) +void Sc::Scene::removeShapes(Sc::RigidSim& sim, PxInlineArray& shapesBuffer , PxInlineArray& removedShapes, bool wakeOnLostTouch) { - PxNodeIndex nodeIndex; - - if (core) + PxU32 nbElems = sim.getNbElements(); + Sc::ElementSim** elems = sim.getElements(); + while (nbElems--) { - nodeIndex = core->getSim()->getNodeIndex(); + Sc::ShapeSim* s = static_cast(*elems++); + // can do two 2x the allocs in the worst case, but actors with >64 shapes are not common + shapesBuffer.pushBack(s); + removedShapes.pushBack(&s->getCore()); } - mSimulationController->addRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, vertId); + for(PxU32 i=0;igetSim()->getNodeIndex(); - } + // sim objects do all the necessary work of adding themselves to broad phase, + // activation, registering with the interaction system, etc - mSimulationController->removeRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, vertId); + StaticSim* sim = mStaticSimPool->construct(*this, ro); + + mNbRigidStatics++; + addShapes(shapes, nbShapes, shapePtrOffset, *sim, uninflatedBounds); } -PxU32 Sc::Scene::addRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint) +void Sc::Scene::removeStatic(StaticCore& ro, PxInlineArray& removedShapes, bool wakeOnLostTouch) { - PxNodeIndex nodeIndex; - PxsRigidBody* body = NULL; + PX_ASSERT(ro.getActorCoreType() == PxActorType::eRIGID_STATIC); - if (core) + StaticSim* sim = ro.getSim(); + if(sim) { - nodeIndex = core->getSim()->getNodeIndex(); - body = &core->getSim()->getLowLevelBody(); + if(mBatchRemoveState) + { + removeShapes(*sim, mBatchRemoveState->bufferedShapes ,removedShapes, wakeOnLostTouch); + } + else + { + PxInlineArray shapesBuffer; + removeShapes(*sim, shapesBuffer ,removedShapes, wakeOnLostTouch); + } + mStaticSimPool->destroy(static_cast(ro.getSim())); + mNbRigidStatics--; } +} - PxU32 handle = mSimulationController->addRigidAttachment(sim.getLowLevelFEMCloth(), sim.getNodeIndex(), body, nodeIndex, - vertId, actorSpacePose, constraint, sim.isActive()); +void Sc::Scene::addBody(BodyCore& body, NpShape*const *shapes, PxU32 nbShapes, size_t shapePtrOffset, PxBounds3* outBounds, bool compound) +{ + // sim objects do all the necessary work of adding themselves to broad phase, + // activation, registering with the interaction system, etc - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + BodySim* sim = mBodySimPool->construct(*this, body, compound); - if (interaction.mCount == 0) + const bool isArticulationLink = sim->isArticulationLink(); + + if (sim->getLowLevelBody().mCore->mFlags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD && sim->isActive()) { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eFEM_CLOTH_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); - interaction.mIndex = edgeIdx; + if (isArticulationLink) + { + if (sim->getNodeIndex().isValid()) + mSpeculativeCDDArticulationBitMap.growAndSet(sim->getNodeIndex().index()); + } + else + mSpeculativeCCDRigidBodyBitMap.growAndSet(sim->getNodeIndex().index()); } - interaction.mCount++; - return handle; + //if rigid body is articulation link, the node index will be invalid. We should add the link to the scene after we add the + //articulation for gpu + if(sim->getNodeIndex().isValid()) + mSimulationController->addDynamic(&sim->getLowLevelBody(), sim->getNodeIndex()); + if(sim->getSimStateData(true) && sim->getSimStateData(true)->isKine()) + mNbRigidKinematic++; + else + mNbRigidDynamics++; + addShapes(shapes, nbShapes, shapePtrOffset, *sim, outBounds); + + mDynamicsContext->setStateDirty(true); } -void Sc::Scene::removeRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 handle) +void Sc::Scene::removeBody(BodyCore& body, PxInlineArray& removedShapes, bool wakeOnLostTouch) { - PxNodeIndex nodeIndex; - - if (core) + BodySim *sim = body.getSim(); + if(sim) { - nodeIndex = core->getSim()->getNodeIndex(); - } + if(mBatchRemoveState) + { + removeShapes(*sim, mBatchRemoveState->bufferedShapes, removedShapes, wakeOnLostTouch); + } + else + { + PxInlineArray shapesBuffer; + removeShapes(*sim,shapesBuffer, removedShapes, wakeOnLostTouch); + } - mSimulationController->removeRigidAttachment(sim.getLowLevelFEMCloth(), handle); + if(!sim->isArticulationLink()) + { + //clear bit map + if(sim->getLowLevelBody().mCore->mFlags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) + sim->getScene().resetSpeculativeCCDRigidBody(sim->getNodeIndex().index()); + } + else + { + // PT: TODO: missing call to resetSpeculativeCCDArticulationLink ? - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) - { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); + sim->getArticulation()->removeBody(*sim); + } + if(sim->getSimStateData(true) && sim->getSimStateData(true)->isKine()) + { + body.onRemoveKinematicFromScene(); + + mNbRigidKinematic--; + } + else + mNbRigidDynamics--; + + mBodySimPool->destroy(sim); + + mDynamicsContext->setStateDirty(true); } } -void Sc::Scene::addTriRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 triIdx) +// PT: TODO: refactor with addShapes +void Sc::Scene::addShape_(RigidSim& owner, ShapeCore& shapeCore) { - PxNodeIndex nodeIndex; + ShapeSim* sim = mShapeSimPool->construct(owner, shapeCore); + mNbGeometries[shapeCore.getGeometryType()]++; - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - } + //register shape + mSimulationController->addShape(&sim->getLLShapeSim(), sim->getElementID()); - mSimulationController->addTriRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, triIdx); + registerShapeInNphase(&owner.getRigidCore(), shapeCore, sim->getElementID()); } -void Sc::Scene::removeTriRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 triIdx) +// PT: TODO: refactor with removeShapes +void Sc::Scene::removeShape_(ShapeSim& shape, bool wakeOnLostTouch) { - PxNodeIndex nodeIndex; + //BodySim* body = shape.getBodySim(); + //if(body) + // body->postShapeDetach(); + + unregisterShapeFromNphase(shape.getCore(), shape.getElementID()); - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - } + mSimulationController->removeShape(shape.getElementID()); - mSimulationController->removeTriRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, triIdx); + mNbGeometries[shape.getCore().getGeometryType()]--; + shape.removeFromBroadPhase(wakeOnLostTouch); + mShapeSimPool->destroy(&shape); } -PxU32 Sc::Scene::addTriRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 triIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint) +void Sc::Scene::registerShapeInNphase(Sc::RigidCore* rigidCore, const ShapeCore& shape, const PxU32 transformCacheID) { - PxNodeIndex nodeIndex; - PxsRigidBody* body = NULL; - - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - body = &core->getSim()->getLowLevelBody(); - } - - PxU32 handle = mSimulationController->addTriRigidAttachment(sim.getLowLevelFEMCloth(), body, nodeIndex, - triIdx, barycentric, actorSpacePose, constraint, sim.isActive()); + RigidSim* sim = rigidCore->getSim(); + if(sim) + mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), shape.getCore(), transformCacheID, sim->getPxActor()); +} - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; +void Sc::Scene::unregisterShapeFromNphase(const ShapeCore& shape, const PxU32 transformCacheID) +{ + mLLContext->getNphaseImplementationContext()->unregisterShape(shape.getCore(), transformCacheID); +} - if (interaction.mCount == 0) - { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eFEM_CLOTH_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); - interaction.mIndex = edgeIdx; - } - interaction.mCount++; - return handle; +void Sc::Scene::notifyNphaseOnUpdateShapeMaterial(const ShapeCore& shapeCore) +{ + mLLContext->getNphaseImplementationContext()->updateShapeMaterial(shapeCore.getCore()); } -void Sc::Scene::removeTriRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 handle) +void Sc::Scene::startBatchInsertion(BatchInsertionState&state) { - PxNodeIndex nodeIndex; + state.shapeSim = mShapeSimPool->allocateAndPrefetch(); + state.staticSim = mStaticSimPool->allocateAndPrefetch(); + state.bodySim = mBodySimPool->allocateAndPrefetch(); +} - if (core) +void Sc::Scene::addShapes(NpShape*const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& rigidSim, ShapeSim*& prefetchedShapeSim, PxBounds3* outBounds) +{ + for(PxU32 i=0;igetSim()->getNodeIndex(); - } + if(i+1allocateAndPrefetch(); + ShapeCore& sc = *PxPointerOffset(shapes[i], ptrdiff_t(ptrOffset)); + PX_PLACEMENT_NEW(prefetchedShapeSim, ShapeSim(rigidSim, sc)); + const PxU32 elementID = prefetchedShapeSim->getElementID(); - mSimulationController->removeTriRigidAttachment(sim.getLowLevelFEMCloth(), handle); + outBounds[i] = mBoundsArray->getBounds(elementID); - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) - { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); - } + mSimulationController->addShape(&prefetchedShapeSim->getLLShapeSim(), elementID); + mLLContext->getNphaseImplementationContext()->registerShape(rigidSim.getNodeIndex(), sc.getCore(), elementID, rigidSim.getPxActor()); + + prefetchedShapeSim = nextShapeSim; + mNbGeometries[sc.getGeometryType()]++; + } } -void Sc::Scene::addClothFilter(FEMClothCore& core0, PxU32 triIdx0, Sc::FEMClothSim& sim1, PxU32 triIdx1) +void Sc::Scene::addStatic(PxActor* actor, BatchInsertionState& s, PxBounds3* outBounds) { - Sc::FEMClothSim& sim0 = *core0.getSim(); + // static core has been prefetched by caller + Sc::StaticSim* sim = s.staticSim; // static core has been prefetched by the caller - mSimulationController->addClothFilter(sim0.getLowLevelFEMCloth(), sim1.getLowLevelFEMCloth(), triIdx0, triIdx1); -} + const Cm::PtrTable* shapeTable = PxPointerOffset(actor, s.staticShapeTableOffset); + void*const* shapes = shapeTable->getPtrs(); -void Sc::Scene::removeClothFilter(FEMClothCore& core, PxU32 triIdx0, FEMClothSim& sim1, PxU32 triIdx1) -{ - Sc::FEMClothSim& sim0 = *core.getSim(); - mSimulationController->removeClothFilter(sim0.getLowLevelFEMCloth(), sim1.getLowLevelFEMCloth(), triIdx0, triIdx1); + mStaticSimPool->construct(sim, *this, *PxPointerOffset(actor, s.staticActorOffset)); + s.staticSim = mStaticSimPool->allocateAndPrefetch(); + + addShapes(reinterpret_cast(shapes), shapeTable->getCount(), size_t(s.shapeOffset), *sim, s.shapeSim, outBounds); + mNbRigidStatics++; } -PxU32 Sc::Scene::addTriClothAttachment(FEMClothCore& core, PxU32 triIdx0, const PxVec4& barycentric0, Sc::FEMClothSim& sim1, PxU32 triIdx1, const PxVec4& barycentric1) +void Sc::Scene::addBody(PxActor* actor, BatchInsertionState& s, PxBounds3* outBounds, bool compound) { - Sc::FEMClothSim& sim0 = *core.getSim(); - - PxU32 handle = mSimulationController->addTriClothAttachment(sim0.getLowLevelFEMCloth(), sim1.getLowLevelFEMCloth(), triIdx0, triIdx1, - barycentric0, barycentric1, sim1.isActive() || sim0.isActive()); + Sc::BodySim* sim = s.bodySim; // body core has been prefetched by the caller - //return handle; + const Cm::PtrTable* shapeTable = PxPointerOffset(actor, s.dynamicShapeTableOffset); + void*const* shapes = shapeTable->getPtrs(); - PxPair pair(sim0.getNodeIndex().index(), sim1.getNodeIndex().index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + Sc::BodyCore* bodyCore = PxPointerOffset(actor, s.dynamicActorOffset); + mBodySimPool->construct(sim, *this, *bodyCore, compound); + s.bodySim = mBodySimPool->allocateAndPrefetch(); - if (interaction.mCount == 0) + if(sim->getLowLevelBody().mCore->mFlags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim0.getNodeIndex(), sim1.getNodeIndex(), NULL, IG::Edge::eFEM_CLOTH_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); - interaction.mIndex = edgeIdx; - } - interaction.mCount++; - return handle; -} - -void Sc::Scene::removeTriClothAttachment(FEMClothCore& core, FEMClothSim& sim1, PxU32 handle) -{ - Sc::FEMClothSim& sim0 = *core.getSim(); - mSimulationController->removeTriClothAttachment(sim0.getLowLevelFEMCloth(), handle); - - PxPair pair(sim0.getNodeIndex().index(), sim1.getNodeIndex().index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) - { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); + if(sim->isArticulationLink()) + mSpeculativeCDDArticulationBitMap.growAndSet(sim->getNodeIndex().index()); + else + mSpeculativeCCDRigidBodyBitMap.growAndSet(sim->getNodeIndex().index()); } -} -void Sc::Scene::addParticleSystemSimControl(Sc::ParticleSystemCore& core) -{ - Sc::ParticleSystemSim* sim = core.getSim(); + if(sim->getNodeIndex().isValid()) + mSimulationController->addDynamic(&sim->getLowLevelBody(), sim->getNodeIndex()); - if (sim) - { - mSimulationController->addParticleSystem(sim->getLowLevelParticleSystem(), sim->getNodeIndex(), core.getSolverType()); - - mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getCore().getShapeCore().getCore(), sim->getLowLevelParticleSystem()->getElementId(), sim->getPxActor()); - } -} + addShapes(reinterpret_cast(shapes), shapeTable->getCount(), size_t(s.shapeOffset), *sim, s.shapeSim, outBounds); -void Sc::Scene::removeParticleSystemSimControl(Sc::ParticleSystemCore& core) -{ - Sc::ParticleSystemSim* sim = core.getSim(); + const SimStateData* simStateData = bodyCore->getSim()->getSimStateData(true); + if(simStateData && simStateData->isKine()) + mNbRigidKinematic++; + else + mNbRigidDynamics++; - if (sim) - { - mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getCore().getShapeCore().getCore(), sim->getShapeSim().getElementID()); - mSimulationController->releaseParticleSystem(sim->getLowLevelParticleSystem(), core.getSolverType()); - } + mDynamicsContext->setStateDirty(true); } - -void Sc::Scene::addRigidAttachment(Sc::BodyCore* core, Sc::ParticleSystemSim& sim) +void Sc::Scene::finishBatchInsertion(BatchInsertionState& state) { - PxNodeIndex nodeIndex; - - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - } + // a little bit lazy - we could deal with the last one in the batch specially to avoid overallocating by one. - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - - if (interaction.mCount == 0) - { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::ePARTICLE_SYSTEM_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::ePARTICLE_SYSTEM_CONTACT); - interaction.mIndex = edgeIdx; - } - interaction.mCount++; -} - -void Sc::Scene::removeRigidAttachment(Sc::BodyCore* core, Sc::ParticleSystemSim& sim) -{ - PxNodeIndex nodeIndex; - if (core) - nodeIndex = core->getSim()->getNodeIndex(); - - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - interaction.mCount--; - if (interaction.mCount == 0) - { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); - } -} - -void Sc::Scene::addHairSystemSimControl(Sc::HairSystemCore& core) -{ - Sc::HairSystemSim* sim = core.getSim(); - - if (sim) - { - mSimulationController->addHairSystem(sim->getLowLevelHairSystem(), sim->getNodeIndex()); - mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), sim->getPxActor()); - } -} - -void Sc::Scene::removeHairSystemSimControl(Sc::HairSystemCore& core) -{ - Sc::HairSystemSim* sim = core.getSim(); - - if (sim) - { - mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID()); - mSimulationController->releaseHairSystem(sim->getLowLevelHairSystem()); - } + mStaticSimPool->releasePreallocated(static_cast(state.staticSim)); + mBodySimPool->releasePreallocated(static_cast(state.bodySim)); + mShapeSimPool->releasePreallocated(state.shapeSim); } -void Sc::Scene::addRigidAttachment(const Sc::BodyCore* core, const Sc::HairSystemSim& sim) +// PT: TODO: why is this in Sc? +void Sc::Scene::initContactsIterator(ContactIterator& contactIterator, PxsContactManagerOutputIterator& outputs) { - PxNodeIndex nodeIndex; - - if (core) - { - nodeIndex = core->getSim()->getNodeIndex(); - } - - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - - if (interaction.mCount == 0) - { - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eHAIR_SYSTEM_CONTACT); - mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eHAIR_SYSTEM_CONTACT); - interaction.mIndex = edgeIdx; - } - interaction.mCount++; + outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + ElementSimInteraction** first = mInteractions[Sc::InteractionType::eOVERLAP].begin(); + contactIterator = ContactIterator(first, first + mActiveInteractionCount[Sc::InteractionType::eOVERLAP], outputs); } -void Sc::Scene::removeRigidAttachment(const Sc::BodyCore* core, const Sc::HairSystemSim& sim) +void Sc::Scene::setDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2, const PxDominanceGroupPair& dominance) { - PxNodeIndex nodeIndex; - - if(core) - { - nodeIndex = core->getSim()->getNodeIndex(); - } - - PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); - if(mParticleOrSoftBodyRigidInteractionMap.find(pair)) // find returns pointer to const so we cannot use it directly - { - ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - PX_ASSERT(interaction.mCount > 0); - interaction.mCount--; - if(interaction.mCount == 0) + struct { + void operator()(PxU32& bits, PxDominanceGroup shift, PxReal weight) { - mSimpleIslandManager->removeConnection(interaction.mIndex); - mParticleOrSoftBodyRigidInteractionMap.erase(pair); + if(weight != PxReal(0)) + bits |= (PxU32(1) << shift); + else + bits &= ~(PxU32(1) << shift); } - } -} -#endif - -void Sc::Scene::addBrokenConstraint(Sc::ConstraintCore* c) -{ - PX_ASSERT(mBrokenConstraints.find(c) == mBrokenConstraints.end()); - mBrokenConstraints.pushBack(c); -} - -void Sc::Scene::addActiveBreakableConstraint(Sc::ConstraintSim* c, Sc::ConstraintInteraction* ci) -{ - PX_ASSERT(ci && ci->readInteractionFlag(InteractionFlag::eIS_ACTIVE)); - PX_UNUSED(ci); - PX_ASSERT(!mActiveBreakableConstraints.contains(c)); - PX_ASSERT(!c->isBroken()); - mActiveBreakableConstraints.insert(c); - c->setFlag(ConstraintSim::eCHECK_MAX_FORCE_EXCEEDED); -} + } bitsetter; -void Sc::Scene::removeActiveBreakableConstraint(Sc::ConstraintSim* c) -{ - const bool exists = mActiveBreakableConstraints.erase(c); - PX_ASSERT(exists); - PX_UNUSED(exists); - c->clearFlag(ConstraintSim::eCHECK_MAX_FORCE_EXCEEDED); -} + bitsetter(mDominanceBitMatrix[group1], group2, dominance.dominance0); + bitsetter(mDominanceBitMatrix[group2], group1, dominance.dominance1); -void* Sc::Scene::allocateConstraintBlock(PxU32 size) -{ - if(size<=128) - return mMemBlock128Pool.construct(); - else if(size<=256) - return mMemBlock256Pool.construct(); - else if(size<=384) - return mMemBlock384Pool.construct(); - else - return PX_ALLOC(size, "ConstraintBlock"); + mInternalFlags |= SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_DOMINANCE; //force an update on all interactions on matrix change -- very expensive but we have no choice!! } -void Sc::Scene::deallocateConstraintBlock(void* ptr, PxU32 size) +PxDominanceGroupPair Sc::Scene::getDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2) const { - if(size<=128) - mMemBlock128Pool.destroy(reinterpret_cast(ptr)); - else if(size<=256) - mMemBlock256Pool.destroy(reinterpret_cast(ptr)); - else if(size<=384) - mMemBlock384Pool.destroy(reinterpret_cast(ptr)); - else - PX_FREE(ptr); -} - -/*-------------------------------*\ -| Adam's explanation of the RB solver: -| This is a novel idea of mine, -| a combination of ideas on -| Milenkovic's Optimization -| Based Animation, and Trinkle's -| time stepping schemes. -| -| A time step goes like this: -| -| Taking no substeps: -| 0) Compute contact points. -| 1) Update external forces. This may include friction. -| 2) Integrate external forces to current velocities. -| 3) Solve for impulses at contacts which will prevent -| interpenetration at next timestep given some -| velocity integration scheme. -| 4) Use the integration scheme on velocity to -| reach the next state. Here we should not have any -| interpenetration at the old contacts, but perhaps -| at new contacts. If interpenetrating at new contacts, -| just add these to the contact list; no need to repeat -| the time step, because the scheme will get rid of the -| penetration by the next step. -| -| -| Advantages: -| + Large steps, LOD realism. -| + very simple. -| -\*-------------------------------*/ - -void Sc::Scene::advanceStep(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.solveQueueTasks", getContextId()); - - if (mDt != 0.0f) - { - mFinalizationPhase.addDependent(*continuation); - mFinalizationPhase.removeReference(); - - if (mPublicFlags & PxSceneFlag::eENABLE_CCD) - { - mUpdateCCDMultiPass.setContinuation(&mFinalizationPhase); - mAfterIntegration.setContinuation(&mUpdateCCDMultiPass); - mUpdateCCDMultiPass.removeReference(); - } - else - { - mAfterIntegration.setContinuation(&mFinalizationPhase); - } - - mPostSolver.setContinuation(&mAfterIntegration); - mUpdateSimulationController.setContinuation(&mPostSolver); - mUpdateDynamics.setContinuation(&mUpdateSimulationController); - mUpdateBodies.setContinuation(&mUpdateDynamics); - mSolver.setContinuation(&mUpdateBodies); - mPostIslandGen.setContinuation(&mSolver); - mIslandGen.setContinuation(&mPostIslandGen); - mPostNarrowPhase.addDependent(mIslandGen); - mPostNarrowPhase.removeReference(); - - mSecondPassNarrowPhase.setContinuation(&mPostNarrowPhase); - - mFinalizationPhase.removeReference(); - mAfterIntegration.removeReference(); - mPostSolver.removeReference(); - mUpdateSimulationController.removeReference(); - mUpdateDynamics.removeReference(); - mUpdateBodies.removeReference(); - mSolver.removeReference(); - mPostIslandGen.removeReference(); - mIslandGen.removeReference(); - mPostNarrowPhase.removeReference(); - mSecondPassNarrowPhase.removeReference(); - } + const PxU8 dom0 = PxU8((mDominanceBitMatrix[group1]>>group2) & 0x1 ? 1u : 0u); + const PxU8 dom1 = PxU8((mDominanceBitMatrix[group2]>>group1) & 0x1 ? 1u : 0u); + return PxDominanceGroupPair(dom0, dom1); } -void Sc::Scene::collideStep(PxBaseTask* continuation) +PxU32 Sc::Scene::getDefaultContactReportStreamBufferSize() const { - PX_PROFILE_ZONE("Sim.collideQueueTasks", getContextId()); - PX_PROFILE_START_CROSSTHREAD("Basic.collision", getContextId()); - - mStats->simStart(); - mLLContext->beginUpdate(); - - mSimulationController->flushInsertions(); - - mPostNarrowPhase.setTaskManager(*continuation->getTaskManager()); - mPostNarrowPhase.addReference(); - - mFinalizationPhase.setTaskManager(*continuation->getTaskManager()); - mFinalizationPhase.addReference(); - - mRigidBodyNarrowPhase.setContinuation(continuation); - mPreRigidBodyNarrowPhase.setContinuation(&mRigidBodyNarrowPhase); - mUpdateShapes.setContinuation(&mPreRigidBodyNarrowPhase); - - mRigidBodyNarrowPhase.removeReference(); - mPreRigidBodyNarrowPhase.removeReference(); - mUpdateShapes.removeReference(); + return mNPhaseCore->getDefaultContactReportStreamBufferSize(); } -void Sc::Scene::broadPhase(PxBaseTask* continuation) +void Sc::Scene::buildActiveActors() { - PX_PROFILE_START_CROSSTHREAD("Basic.broadPhase", getContextId()); - - mProcessLostPatchesTask.setContinuation(&mPostNarrowPhase); - mProcessLostPatchesTask.removeReference(); - -#if PX_SUPPORT_GPU_PHYSX - //update soft bodies world bound - Sc::SoftBodyCore* const* softBodies = mSoftBodies.getEntries(); - PxU32 size = mSoftBodies.size(); - if (mUseGpuBp) - { - for (PxU32 i = 0; i < size; ++i) - { - softBodies[i]->getSim()->updateBoundsInAABBMgr(); - } - } - else - { - for (PxU32 i = 0; i < size; ++i) - { - softBodies[i]->getSim()->updateBounds(); - } - } - - // update FEM-cloth world bound - Sc::FEMClothCore* const* femCloths = mFEMCloths.getEntries(); - size = mFEMCloths.size(); - if (mUseGpuBp) - { - for (PxU32 i = 0; i < size; ++i) - { - femCloths[i]->getSim()->updateBoundsInAABBMgr(); - } - } - else { - for (PxU32 i = 0; i < size; ++i) + PxU32 numActiveBodies = 0; + BodyCore*const* PX_RESTRICT activeBodies; + if (!(getFlags() & PxSceneFlag::eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS)) { - femCloths[i]->getSim()->updateBounds(); + numActiveBodies = getNumActiveBodies(); + activeBodies = getActiveBodiesArray(); } - } - - //upate the actor handle of particle system in AABB manager - Sc::ParticleSystemCore* const* particleSystems = mParticleSystems.getEntries(); - - size = mParticleSystems.size(); - if (mUseGpuBp) - { - for (PxU32 i = 0; i < size; ++i) - particleSystems[i]->getSim()->updateBoundsInAABBMgr(); - } - else - { - for (PxU32 i = 0; i < size; ++i) - particleSystems[i]->getSim()->updateBounds(); - } - - //update hair system world bound - Sc::HairSystemCore* const* hairSystems = mHairSystems.getEntries(); - PxU32 nHairSystems = mHairSystems.size(); - if (mUseGpuBp) - { - for (PxU32 i = 0; i < nHairSystems; ++i) - { - hairSystems[i]->getSim()->updateBoundsInAABBMgr(); - } - } - else - { - for (PxU32 i = 0; i < nHairSystems; ++i) - { - hairSystems[i]->getSim()->updateBounds(); - } - } - -#endif - - mCCDBp = false; - - mBpSecondPass.setContinuation(continuation); - mBpFirstPass.setContinuation(&mBpSecondPass); - - mBpSecondPass.removeReference(); - mBpFirstPass.removeReference(); -} - -void Sc::Scene::broadPhaseFirstPass(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Basic.broadPhaseFirstPass", getContextId()); - - const PxU32 numCpuTasks = continuation->getTaskManager()->getCpuDispatcher()->getWorkerCount(); - mAABBManager->updateBPFirstPass(numCpuTasks, mLLContext->getTaskPool(), mHasContactDistanceChanged, continuation); - - PxU32 maxAABBHandles = PxMax(mAABBManager->getChangedAABBMgActorHandleMap().getWordCount() * 32, getElementIDPool().getMaxID()); - - mSimulationController->mergeChangedAABBMgHandle(maxAABBHandles, mPublicFlags & PxSceneFlag::eSUPPRESS_READBACK); -} - -void Sc::Scene::broadPhaseSecondPass(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Basic.broadPhaseSecondPass", getContextId()); - - mBpUpdate.setContinuation(continuation); - mPreIntegrate.setContinuation(&mBpUpdate); - - mPreIntegrate.removeReference(); - mBpUpdate.removeReference(); -} - -void Sc::Scene::preIntegrate(PxBaseTask* continuation) -{ - if (!mCCDBp && isUsingGpuDynamicsOrBp()) - mSimulationController->preIntegrateAndUpdateBound(continuation, mGravity, mDt); -} - -void Sc::Scene::updateBroadPhase(PxBaseTask* continuation) -{ - PxBaseTask* rigidBodyNPhaseUnlock = mCCDPass ? NULL : &mRigidBodyNPhaseUnlock; - - const PxU32 numCpuTasks = continuation->getTaskManager()->getCpuDispatcher()->getWorkerCount(); - - mAABBManager->updateBPSecondPass(numCpuTasks, &mLLContext->getScratchAllocator(), continuation); - - // PT: decoupling: I moved this back from updateBPSecondPass - //if this is mCCDPass, narrowPhaseUnlockTask will be NULL - if(rigidBodyNPhaseUnlock) - rigidBodyNPhaseUnlock->removeReference(); - - if(!mCCDBp && isUsingGpuDynamicsOrBp()) - mSimulationController->updateParticleSystemsAndSoftBodies(); -} - -void Sc::Scene::postBroadPhase(PxBaseTask* continuation) -{ - PX_PROFILE_START_CROSSTHREAD("Basic.postBroadPhase", getContextId()); - - //Notify narrow phase that broad phase has completed - mLLContext->getNphaseImplementationContext()->postBroadPhaseUpdateContactManager(continuation); - mAABBManager->postBroadPhase(continuation, *getFlushPool()); -} - -void Sc::Scene::postBroadPhaseContinuation(PxBaseTask* continuation) -{ - mAABBManager->getChangedAABBMgActorHandleMap().clear(); - - // - Finishes broadphase update - // - Adds new interactions (and thereby contact managers if needed) - finishBroadPhase(continuation); -} - -void Sc::Scene::postBroadPhaseStage2(PxBaseTask* continuation) -{ - // - Wakes actors that lost touch if appropriate - processLostTouchPairs(); - //Release unused Cms back to the pool (later, this needs to be done in a thread-safe way from multiple worker threads - mIslandInsertion.setContinuation(continuation); - mRegisterContactManagers.setContinuation(continuation); - mRegisterInteractions.setContinuation(continuation); - mRegisterSceneInteractions.setContinuation(continuation); - mIslandInsertion.removeReference(); - mRegisterContactManagers.removeReference(); - mRegisterInteractions.removeReference(); - mRegisterSceneInteractions.removeReference(); - - { - PX_PROFILE_ZONE("Sim.processNewOverlaps.release", getContextId()); - for (PxU32 a = 0; a < mPreallocatedContactManagers.size(); ++a) - { - if ((size_t(mPreallocatedContactManagers[a]) & 1) == 0) - mLLContext->getContactManagerPool().put(mPreallocatedContactManagers[a]); - } - - for (PxU32 a = 0; a < mPreallocatedShapeInteractions.size(); ++a) - { - if ((size_t(mPreallocatedShapeInteractions[a]) & 1) == 0) - mNPhaseCore->mShapeInteractionPool.deallocate(mPreallocatedShapeInteractions[a]); - } - - for (PxU32 a = 0; a < mPreallocatedInteractionMarkers.size(); ++a) - { - if ((size_t(mPreallocatedInteractionMarkers[a]) & 1) == 0) - mNPhaseCore->mInteractionMarkerPool.deallocate(mPreallocatedInteractionMarkers[a]); - } - } -} - -void Sc::Scene::postBroadPhaseStage3(PxBaseTask* /*continuation*/) -{ - finishBroadPhaseStage2(0); - - PX_PROFILE_STOP_CROSSTHREAD("Basic.postBroadPhase", getContextId()); - PX_PROFILE_STOP_CROSSTHREAD("Basic.broadPhase", getContextId()); -} - -class DirtyShapeUpdatesTask : public Cm::Task -{ -public: - static const PxU32 MaxShapes = 256; - - PxsTransformCache& mCache; - Bp::BoundsArray& mBoundsArray; - Sc::ShapeSim* mShapes[MaxShapes]; - PxU32 mNbShapes; - - DirtyShapeUpdatesTask(PxU64 contextID, PxsTransformCache& cache, Bp::BoundsArray& boundsArray) : - Cm::Task (contextID), - mCache (cache), - mBoundsArray(boundsArray), - mNbShapes (0) - { - } - - virtual void runInternal() - { - for (PxU32 a = 0; a < mNbShapes; ++a) - { - mShapes[a]->updateCached(mCache, mBoundsArray); - } - } - - virtual const char* getName() const { return "DirtyShapeUpdatesTask"; } - -private: - PX_NOCOPY(DirtyShapeUpdatesTask) -}; - -void Sc::Scene::preRigidBodyNarrowPhase(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Scene.preNarrowPhase", getContextId()); - - updateContactDistances(continuation); - - //Process dirty shapeSims... - PxBitMap::Iterator dirtyShapeIter(mDirtyShapeSimMap); - - PxsTransformCache& cache = mLLContext->getTransformCache(); - Bp::BoundsArray& boundsArray = mAABBManager->getBoundsArray(); - - Cm::FlushPool& pool = mLLContext->getTaskPool(); - PxBitMapPinned& changedMap = mAABBManager->getChangedAABBMgActorHandleMap(); - - DirtyShapeUpdatesTask* task = PX_PLACEMENT_NEW(pool.allocate(sizeof(DirtyShapeUpdatesTask)), DirtyShapeUpdatesTask)(getContextId(), cache, boundsArray); - - bool hasDirtyShapes = false; - PxU32 index; - while ((index = dirtyShapeIter.getNext()) != PxBitMap::Iterator::DONE) - { - Sc::ShapeSim* shapeSim = reinterpret_cast(mAABBManager->getUserData(index)); - if (shapeSim) - { - hasDirtyShapes = true; - changedMap.growAndSet(index); - task->mShapes[task->mNbShapes++] = shapeSim; - if (task->mNbShapes == DirtyShapeUpdatesTask::MaxShapes) - { - task->setContinuation(continuation); - task->removeReference(); - task = PX_PLACEMENT_NEW(pool.allocate(sizeof(DirtyShapeUpdatesTask)), DirtyShapeUpdatesTask)(getContextId(), cache, boundsArray); - } - } - } - - if (hasDirtyShapes) - { - //Setting the boundsArray and transform cache as dirty so that they get DMAd to GPU if GPU dynamics and BP are being used respectively. - //These bits are no longer set when we update the cached state for actors due to an optimization avoiding setting these dirty bits multiple times. - getBoundsArray().setChangedState(); - getLowLevelContext()->getTransformCache().setChangedState(); - } - - if (task->mNbShapes != 0) - { - task->setContinuation(continuation); - task->removeReference(); - } - - mDirtyShapeSimMap.clear(); -} - -void Sc::Scene::updateBoundsAndShapes(PxBaseTask* /*continuation*/) -{ - //if the scene isn't use gpu dynamic and gpu broad phase and the user raise suppress readback flag, - //the sdk will refuse to create the scene. - const bool useDirectGpuApi = mPublicFlags & PxSceneFlag::eSUPPRESS_READBACK; - mSimulationController->updateBoundsAndShapes(*mAABBManager, mUseGpuBp, useDirectGpuApi); -} - -void Sc::Scene::rigidBodyNarrowPhase(PxBaseTask* continuation) -{ - PX_PROFILE_START_CROSSTHREAD("Basic.narrowPhase", getContextId()); - - mCCDPass = 0; - - mPostBroadPhase3.addDependent(*continuation); - mPostBroadPhase2.setContinuation(&mPostBroadPhase3); - mPostBroadPhaseCont.setContinuation(&mPostBroadPhase2); - mPostBroadPhase.setContinuation(&mPostBroadPhaseCont); - mBroadPhase.setContinuation(&mPostBroadPhase); - - mRigidBodyNPhaseUnlock.setContinuation(continuation); - mRigidBodyNPhaseUnlock.addReference(); - - mUpdateBoundAndShapeTask.addDependent(mBroadPhase); - - mLLContext->resetThreadContexts(); - - mLLContext->updateContactManager(mDt, mBoundsArray->hasChanged(), mHasContactDistanceChanged, continuation, - &mRigidBodyNPhaseUnlock, &mUpdateBoundAndShapeTask); // Starts update of contact managers - - mPostBroadPhase3.removeReference(); - mPostBroadPhase2.removeReference(); - mPostBroadPhaseCont.removeReference(); - mPostBroadPhase.removeReference(); - mBroadPhase.removeReference(); - - mUpdateBoundAndShapeTask.removeReference(); -} - -void Sc::Scene::unblockNarrowPhase(PxBaseTask*) -{ - /*if (!mCCDBp && mUseGpuRigidBodies) - mSimulationController->updateParticleSystemsAndSoftBodies();*/ - // - mLLContext->getNphaseImplementationContext()->startNarrowPhaseTasks(); -} - -void Sc::Scene::postNarrowPhase(PxBaseTask* /*continuation*/) -{ - setCollisionPhaseToInactive(); - - mHasContactDistanceChanged = false; - mLLContext->fetchUpdateContactManager(); //Sync on contact gen results! - - if (!mCCDBp && isUsingGpuDynamicsOrBp()) - { - mSimulationController->sortContacts(); - } - - releaseConstraints(false); - - PX_PROFILE_STOP_CROSSTHREAD("Basic.narrowPhase", getContextId()); - PX_PROFILE_STOP_CROSSTHREAD("Basic.collision", getContextId()); -} - -void Sc::Scene::fetchPatchEvents(PxBaseTask*) -{ - //PxU32 foundPatchCount, lostPatchCount; - - //{ - // PX_PROFILE_ZONE("Sim.preIslandGen.managerPatchEvents", getContextId()); - // mLLContext->getManagerPatchEventCount(foundPatchCount, lostPatchCount); - - // //mLLContext->fillManagerPatchChangedEvents(mFoundPatchManagers.begin(), foundPatchCount, mLostPatchManagers.begin(), lostPatchCount); - //} -} - -void Sc::Scene::processNarrowPhaseTouchEvents() -{ - PX_PROFILE_ZONE("Sim.preIslandGen", getContextId()); - - PxsContext* context = mLLContext; - - // Update touch states from LL - PxU32 newTouchCount, lostTouchCount; - PxU32 ccdTouchCount = 0; - { - PX_PROFILE_ZONE("Sim.preIslandGen.managerTouchEvents", getContextId()); - context->getManagerTouchEventCount(reinterpret_cast(&newTouchCount), reinterpret_cast(&lostTouchCount), NULL); - //PX_ALLOCA(newTouches, PxvContactManagerTouchEvent, newTouchCount); - //PX_ALLOCA(lostTouches, PxvContactManagerTouchEvent, lostTouchCount); - - mTouchFoundEvents.forceSize_Unsafe(0); - mTouchFoundEvents.reserve(newTouchCount); - mTouchFoundEvents.forceSize_Unsafe(newTouchCount); - - mTouchLostEvents.forceSize_Unsafe(0); - mTouchLostEvents.reserve(lostTouchCount); - mTouchLostEvents.forceSize_Unsafe(lostTouchCount); - - context->fillManagerTouchEvents(mTouchFoundEvents.begin(), reinterpret_cast(newTouchCount), mTouchLostEvents.begin(), - reinterpret_cast(lostTouchCount), NULL, reinterpret_cast(ccdTouchCount)); - - mTouchFoundEvents.forceSize_Unsafe(newTouchCount); - mTouchLostEvents.forceSize_Unsafe(lostTouchCount); - } - - context->getSimStats().mNbNewTouches = newTouchCount; - context->getSimStats().mNbLostTouches = lostTouchCount; -} - -static PX_FORCE_INLINE Sc::ShapeInteraction* getSI(PxvContactManagerTouchEvent& evt) -{ - return reinterpret_cast(evt.getCMTouchEventUserData()); -} - -class InteractionNewTouchTask : public Cm::Task -{ - PxvContactManagerTouchEvent* mEvents; - const PxU32 mNbEvents; - PxsContactManagerOutputIterator mOutputs; - Sc::NPhaseCore* mNphaseCore; - -public: - InteractionNewTouchTask(PxU64 contextID, PxvContactManagerTouchEvent* events, PxU32 nbEvents, PxsContactManagerOutputIterator& outputs, Sc::NPhaseCore* nPhaseCore) : - Cm::Task (contextID), - mEvents (events), - mNbEvents (nbEvents), - mOutputs (outputs), - mNphaseCore (nPhaseCore) - { - } - - virtual const char* getName() const - { - return "InteractionNewTouchTask"; - } - - void hackInContinuation(PxBaseTask* cont) - { - PX_ASSERT(mCont == NULL); - mCont = cont; - if (mCont) - mCont->addReference(); - } - - virtual void runInternal() - { - mNphaseCore->lockReports(); - for (PxU32 i = 0; i < mNbEvents; ++i) - { - Sc::ShapeInteraction* si = getSI(mEvents[i]); - PX_ASSERT(si); - mNphaseCore->managerNewTouch(*si); - si->managerNewTouch(0, true, mOutputs); - } - mNphaseCore->unlockReports(); - } -private: - PX_NOCOPY(InteractionNewTouchTask) -}; - -void Sc::Scene::processNarrowPhaseTouchEventsStage2(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sc::Scene::processNarrowPhaseTouchEventsStage2", getContextId()); - mLLContext->getNphaseImplementationContext()->waitForContactsReady(); - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - const PxU32 newTouchCount = mTouchFoundEvents.size(); - - { - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - InteractionNewTouchTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(InteractionNewTouchTask)), InteractionNewTouchTask)(getContextId(), mTouchFoundEvents.begin(), newTouchCount, outputs, mNPhaseCore); - task->setContinuation(continuation); - task->removeReference(); - } - - /*{ - PX_PROFILE_ZONE("Sim.preIslandGen.newTouchesInteraction", getContextId()); - for (PxU32 i = 0; i < newTouchCount; ++i) - { - ShapeInteraction* si = reinterpret_cast(mTouchFoundEvents[i].userData); - PX_ASSERT(si); - mNPhaseCore->managerNewTouch(*si); - si->managerNewTouch(0, true, outputs, useAdaptiveForce); - } - }*/ - -} - -void Sc::Scene::setEdgesConnected(PxBaseTask*) -{ - PX_PROFILE_ZONE("Sim.preIslandGen.islandTouches", getContextId()); - { - PX_PROFILE_ZONE("Sim.preIslandGen.setEdgesConnected", getContextId()); - const PxU32 newTouchCount = mTouchFoundEvents.size(); - for(PxU32 i = 0; i < newTouchCount; ++i) - { - ShapeInteraction* si = getSI(mTouchFoundEvents[i]); - if(!si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) - mSimpleIslandManager->setEdgeConnected(si->getEdgeIndex(), IG::Edge::eCONTACT_MANAGER); - } - } - - mSimpleIslandManager->secondPassIslandGen(); - - wakeObjectsUp(ActorSim::AS_PART_OF_ISLAND_GEN); -} - -void Sc::Scene::processNarrowPhaseLostTouchEventsIslands(PxBaseTask*) -{ - PX_PROFILE_ZONE("Sc::Scene.islandLostTouches", getContextId()); - const PxU32 count = mTouchLostEvents.size(); - for(PxU32 i=0; i setEdgeDisconnected(si->getEdgeIndex()); - } -} - -void Sc::Scene::processNarrowPhaseLostTouchEvents(PxBaseTask*) -{ - PX_PROFILE_ZONE("Sc::Scene.processNarrowPhaseLostTouchEvents", getContextId()); - mLLContext->getNphaseImplementationContext()->waitForContactsReady(); - PxsContactManagerOutputIterator outputs = this->mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - const PxU32 count = mTouchLostEvents.size(); - for(PxU32 i=0; imanagerLostTouch(0, true, outputs) && !si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) - addToLostTouchList(si->getShape0().getActor(), si->getShape1().getActor()); - } -} - -void Sc::Scene::processLostSolverPatches(PxBaseTask* /*continuation*/) -{ - PxvNphaseImplementationContext* nphase = mLLContext->getNphaseImplementationContext(); - mDynamicsContext->processLostPatches(*mSimpleIslandManager, nphase->getFoundPatchManagers(), nphase->getNbFoundPatchManagers(), nphase->getFoundPatchOutputCounts()); -} - -void Sc::Scene::processFoundSolverPatches(PxBaseTask* /*continuation*/) -{ - PxvNphaseImplementationContext* nphase = mLLContext->getNphaseImplementationContext(); - mDynamicsContext->processFoundPatches(*mSimpleIslandManager, nphase->getFoundPatchManagers(), nphase->getNbFoundPatchManagers(), nphase->getFoundPatchOutputCounts()); -} - -void Sc::Scene::islandGen(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sc::Scene::islandGen", getContextId()); -// PX_PROFILE_START_CROSSTHREAD("Basic.rigidBodySolver", getContextId()); - - //mLLContext->runModifiableContactManagers(); //KS - moved here so that we can get up-to-date touch found/lost events in IG - - /*mProcessLostPatchesTask.setContinuation(&mUpdateDynamics); - mProcessLostPatchesTask.removeReference();*/ - //mFetchPatchEventsTask.setContinuation(&mProcessLostPatchesTask); - - //mFetchPatchEventsTask.removeReference(); - processNarrowPhaseTouchEvents(); - - mProcessFoundPatchesTask.setContinuation(continuation); - mProcessFoundPatchesTask.removeReference(); - - processNarrowPhaseTouchEventsStage2(&mPostSolver); -} - -void Sc::Scene::putObjectsToSleep(PxU32 infoFlag) -{ - PX_PROFILE_ZONE("Sc::Scene::putObjectsToSleep", getContextId()); - const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - - //Set to sleep all bodies that were in awake islands that have just been put to sleep. - const PxU32 nbBodiesToSleep = islandSim.getNbNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); - const PxNodeIndex*const bodyIndices = islandSim.getNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); - - PxU32 nbBodiesDeactivated = 0; - for(PxU32 i=0;i(reinterpret_cast(rigidBody) - Sc::BodySim::getRigidBodyOffset()); - bodySim->setActive(false, infoFlag); - nbBodiesDeactivated++; - } - } - - const PxU32 nbArticulationsToSleep = islandSim.getNbNodesToDeactivate(IG::Node::eARTICULATION_TYPE); - const PxNodeIndex*const articIndices = islandSim.getNodesToDeactivate(IG::Node::eARTICULATION_TYPE); - - for(PxU32 i=0;isetActive(false, infoFlag); - nbBodiesDeactivated++; - } - } - -#if PX_SUPPORT_GPU_PHYSX - const PxU32 nbSoftBodiesToSleep = islandSim.getNbNodesToDeactivate(IG::Node::eSOFTBODY_TYPE); - const PxNodeIndex*const softBodiesIndices = islandSim.getNodesToDeactivate(IG::Node::eSOFTBODY_TYPE); - - for (PxU32 i = 0; igetSoftBodySim(); - if (softBodySim && !islandSim.getNode(softBodiesIndices[i]).isActive()) - { - softBodySim->setActive(false, infoFlag); - nbBodiesDeactivated++; - } - } - - const PxU32 nbFemClothesToSleep = islandSim.getNbNodesToDeactivate(IG::Node::eFEMCLOTH_TYPE); - const PxNodeIndex*const femClothesIndices = islandSim.getNodesToDeactivate(IG::Node::eFEMCLOTH_TYPE); - - for (PxU32 i = 0; i < nbFemClothesToSleep; i++) - { - Sc::FEMClothSim* femClothSim = islandSim.getLLFEMCloth(femClothesIndices[i])->getFEMClothSim(); - if (femClothSim && !islandSim.getNode(femClothesIndices[i]).isActive()) - { - femClothSim->setActive(false, infoFlag); - nbBodiesDeactivated++; - } - } - - const PxU32 nbHairSystemsToSleep = islandSim.getNbNodesToDeactivate(IG::Node::eHAIRSYSTEM_TYPE); - const PxNodeIndex*const hairSystemIndices = islandSim.getNodesToDeactivate(IG::Node::eHAIRSYSTEM_TYPE); - - for (PxU32 i = 0; i < nbHairSystemsToSleep; i++) - { - Sc::HairSystemSim* hairSystemSim = islandSim.getLLHairSystem(hairSystemIndices[i])->getHairSystemSim(); - if (hairSystemSim && !islandSim.getNode(hairSystemIndices[i]).isActive()) - { - hairSystemSim->setActive(false, infoFlag); - nbBodiesDeactivated++; - } - } -#endif - - if (nbBodiesDeactivated != 0) - mDynamicsContext->setStateDirty(true); -} - -void Sc::Scene::wakeObjectsUp(PxU32 infoFlag) -{ - //Wake up all bodies that were in sleeping islands that have just been hit by a moving object. - - const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - - const PxU32 nbBodiesToWake = islandSim.getNbNodesToActivate(IG::Node::eRIGID_BODY_TYPE); - const PxNodeIndex*const bodyIndices = islandSim.getNodesToActivate(IG::Node::eRIGID_BODY_TYPE); - - PxU32 nbBodiesWoken = 0; - for(PxU32 i=0;i(reinterpret_cast(rigidBody) - Sc::BodySim::getRigidBodyOffset()); - bodySim->setActive(true, infoFlag); - nbBodiesWoken++; - } - } - - const PxU32 nbArticulationsToWake = islandSim.getNbNodesToActivate(IG::Node::eARTICULATION_TYPE); - const PxNodeIndex*const articIndices = islandSim.getNodesToActivate(IG::Node::eARTICULATION_TYPE); - - for(PxU32 i=0;isetActive(true, infoFlag); - nbBodiesWoken++; - } - } - -#if PX_SUPPORT_GPU_PHYSX - const PxU32 nbSoftBodyToWake = islandSim.getNbNodesToActivate(IG::Node::eSOFTBODY_TYPE); - const PxNodeIndex*const softBodyIndices = islandSim.getNodesToActivate(IG::Node::eSOFTBODY_TYPE); - - for (PxU32 i = 0; igetSoftBodySim(); - if (softBodySim && islandSim.getNode(softBodyIndices[i]).isActive()) - { - softBodySim->setActive(true, infoFlag); - nbBodiesWoken++; - } - } - - const PxU32 nbFEMClothToWake = islandSim.getNbNodesToActivate(IG::Node::eFEMCLOTH_TYPE); - const PxNodeIndex*const femClothIndices = islandSim.getNodesToActivate(IG::Node::eFEMCLOTH_TYPE); - - for (PxU32 i = 0; i < nbFEMClothToWake; i++) - { - Sc::FEMClothSim* femClothSim = islandSim.getLLFEMCloth(femClothIndices[i])->getFEMClothSim(); - if (femClothSim && islandSim.getNode(femClothIndices[i]).isActive()) - { - femClothSim->setActive(true, infoFlag); - nbBodiesWoken++; - } - } - - const PxU32 nbHairSystemsToWake = islandSim.getNbNodesToActivate(IG::Node::eHAIRSYSTEM_TYPE); - const PxNodeIndex*const hairSystemIndices = islandSim.getNodesToActivate(IG::Node::eHAIRSYSTEM_TYPE); - - for (PxU32 i = 0; i < nbHairSystemsToWake; i++) - { - Sc::HairSystemSim* hairSystemSim = islandSim.getLLHairSystem(hairSystemIndices[i])->getHairSystemSim(); - if (hairSystemSim && islandSim.getNode(hairSystemIndices[i]).isActive()) - { - hairSystemSim->setActive(true, infoFlag); - nbBodiesWoken++; - } - } -#endif - - if(nbBodiesWoken != 0) - mDynamicsContext->setStateDirty(true); -} - -void Sc::Scene::postIslandGen(PxBaseTask* continuationTask) -{ - PX_PROFILE_ZONE("Sim.postIslandGen", getContextId()); - - mSetEdgesConnectedTask.setContinuation(continuationTask); - mSetEdgesConnectedTask.removeReference(); - - // - Performs collision detection for trigger interactions - mNPhaseCore->processTriggerInteractions(continuationTask); -} - -void Sc::Scene::solver(PxBaseTask* continuation) -{ - PX_PROFILE_START_CROSSTHREAD("Basic.rigidBodySolver", getContextId()); - //Update forces per body in parallel. This can overlap with the other work in this phase. - beforeSolver(continuation); - - PX_PROFILE_ZONE("Sim.postNarrowPhaseSecondPass", getContextId()); - //Narrowphase is completely finished so the streams can be swapped. - mLLContext->swapStreams(); - - //PxsContactManagerOutputIterator outputs = this->mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - //mNPhaseCore->processPersistentContactEvents(outputs, continuation); -} - -void Sc::Scene::updateBodies(PxBaseTask* continuation) -{ - PX_UNUSED(continuation); - - //dma bodies and articulation data to gpu - mSimulationController->updateBodies(continuation); -} - -void Sc::Scene::updateShapes(PxBaseTask* continuation) -{ - //dma shapes data to gpu - mSimulationController->updateShapes(continuation); -} - -Cm::FlushPool* Sc::Scene::getFlushPool() -{ - return &mLLContext->getTaskPool(); -} - -bool Sc::activateInteraction(Sc::Interaction* interaction, void* data) -{ - switch(interaction->getType()) - { - case InteractionType::eOVERLAP: - return static_cast(interaction)->onActivate_(data); - - case InteractionType::eTRIGGER: - return static_cast(interaction)->onActivate_(data); - - case InteractionType::eMARKER: - return static_cast(interaction)->onActivate_(data); - - case InteractionType::eCONSTRAINTSHADER: - return static_cast(interaction)->onActivate_(data); - - case InteractionType::eARTICULATION: - return static_cast(interaction)->onActivate_(data); - - case InteractionType::eTRACKED_IN_SCENE_COUNT: - case InteractionType::eINVALID: - PX_ASSERT(0); - break; - } - return false; -} - -static bool deactivateInteraction(Sc::Interaction* interaction, const Sc::InteractionType::Enum type) -{ - using namespace Sc; - - switch(type) - { - case InteractionType::eOVERLAP: - return static_cast(interaction)->onDeactivate_(); - - case InteractionType::eTRIGGER: - return static_cast(interaction)->onDeactivate_(); - - case InteractionType::eMARKER: - return static_cast(interaction)->onDeactivate_(); - - case InteractionType::eCONSTRAINTSHADER: - return static_cast(interaction)->onDeactivate_(); - - case InteractionType::eARTICULATION: - return static_cast(interaction)->onDeactivate_(); - - case InteractionType::eTRACKED_IN_SCENE_COUNT: - case InteractionType::eINVALID: - PX_ASSERT(0); - break; - } - return false; -} - -void Sc::Scene::postThirdPassIslandGen(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sc::Scene::postThirdPassIslandGen", getContextId()); - putObjectsToSleep(ActorSim::AS_PART_OF_ISLAND_GEN); - - { - PX_PROFILE_ZONE("Sc::Scene::putInteractionsToSleep", getContextId()); - const IG::IslandSim& islandSim = mSimpleIslandManager->getSpeculativeIslandSim(); - - //KS - only deactivate contact managers based on speculative state to trigger contact gen. When the actors were deactivated based on accurate state - //joints should have been deactivated. - - const PxU32 NbTypes = 5; - const IG::Edge::EdgeType types[NbTypes] = { - IG::Edge::eCONTACT_MANAGER, - IG::Edge::eSOFT_BODY_CONTACT, - IG::Edge::eFEM_CLOTH_CONTACT, - IG::Edge::ePARTICLE_SYSTEM_CONTACT, - IG::Edge::eHAIR_SYSTEM_CONTACT }; - - for(PxU32 t = 0; t < NbTypes; ++t) - { - const PxU32 nbDeactivatingEdges = islandSim.getNbDeactivatingEdges(types[t]); - const IG::EdgeIndex* deactivatingEdgeIds = islandSim.getDeactivatingEdges(types[t]); - - for(PxU32 i = 0; i < nbDeactivatingEdges; ++i) - { - Sc::Interaction* interaction = mSimpleIslandManager->getInteraction(deactivatingEdgeIds[i]); - - if(interaction && interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) - { - if(!islandSim.getEdge(deactivatingEdgeIds[i]).isActive()) - { - const InteractionType::Enum type = interaction->getType(); - const bool proceed = deactivateInteraction(interaction, type); - if(proceed && (type < InteractionType::eTRACKED_IN_SCENE_COUNT)) - notifyInteractionDeactivated(interaction); - } - } - } - } - } - - PxvNphaseImplementationContext* implCtx = mLLContext->getNphaseImplementationContext(); - implCtx->waitForContactsReady(); - PxsContactManagerOutputIterator outputs = implCtx->getContactManagerOutputs(); - mNPhaseCore->processPersistentContactEvents(outputs, continuation); -} - -void Sc::Scene::processLostContacts(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sc::Scene::processLostContacts", getContextId()); - mProcessNarrowPhaseLostTouchTasks.setContinuation(continuation); - mProcessNarrowPhaseLostTouchTasks.removeReference(); - - //mLostTouchReportsTask.setContinuation(&mProcessLostContactsTask3); - mProcessNPLostTouchEvents.setContinuation(continuation); - mProcessNPLostTouchEvents.removeReference(); - - { - PX_PROFILE_ZONE("Sim.findInteractionsPtrs", getContextId()); - - Bp::AABBManagerBase* aabbMgr = mAABBManager; - PxU32 destroyedOverlapCount; - Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - ElementSim* volume0 = reinterpret_cast(p->mUserData0); - ElementSim* volume1 = reinterpret_cast(p->mUserData1); - p->mPairUserData = mNPhaseCore->onOverlapRemovedStage1(volume0, volume1); - p++; - } - } -} - -void Sc::Scene::lostTouchReports(PxBaseTask*) -{ - PX_PROFILE_ZONE("Sim.lostTouchReports", getContextId()); - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - Bp::AABBManagerBase* aabbMgr = mAABBManager; - PxU32 destroyedOverlapCount; - - mNPhaseCore->lockReports(); - - { - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - if(p->mPairUserData) - { - Sc::ElementSimInteraction* elemInteraction = reinterpret_cast(p->mPairUserData); - if(elemInteraction->getType() == Sc::InteractionType::eOVERLAP) - mNPhaseCore->lostTouchReports(static_cast(elemInteraction), PxU32(PairReleaseFlag::eWAKE_ON_LOST_TOUCH), NULL, 0, outputs); - } - p++; - } - } - mNPhaseCore->unlockReports(); -} - -void Sc::Scene::unregisterInteractions(PxBaseTask*) -{ - PX_PROFILE_ZONE("Sim.unregisterInteractions", getContextId()); - - Bp::AABBManagerBase* aabbMgr = mAABBManager; - PxU32 destroyedOverlapCount; - - { - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - if(p->mPairUserData) - { - Sc::ElementSimInteraction* elemInteraction = reinterpret_cast(p->mPairUserData); - if(elemInteraction->getType() == Sc::InteractionType::eOVERLAP || elemInteraction->getType() == Sc::InteractionType::eMARKER) - { - unregisterInteraction(elemInteraction); - mNPhaseCore->unregisterInteraction(elemInteraction); - } - } - p++; - } - } -} - -void Sc::Scene::destroyManagers(PxBaseTask*) -{ - PX_PROFILE_ZONE("Sim.destroyManagers", getContextId()); - - mPostThirdPassIslandGenTask.setContinuation(mProcessLostContactsTask3.getContinuation()); - - mSimpleIslandManager->thirdPassIslandGen(&mPostThirdPassIslandGenTask); - - Bp::AABBManagerBase* aabbMgr = mAABBManager; - PxU32 destroyedOverlapCount; - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - if(p->mPairUserData) - { - Sc::ElementSimInteraction* elemInteraction = reinterpret_cast(p->mPairUserData); - if(elemInteraction->getType() == Sc::InteractionType::eOVERLAP) - { - Sc::ShapeInteraction* si = static_cast(elemInteraction); - if(si->getContactManager()) - si->destroyManager(); - } - } - p++; - } -} - -void Sc::Scene::processLostContacts2(PxBaseTask* continuation) -{ - mDestroyManagersTask.setContinuation(continuation); - mLostTouchReportsTask.setContinuation(&mDestroyManagersTask); - mLostTouchReportsTask.removeReference(); - - mUnregisterInteractionsTask.setContinuation(continuation); - mUnregisterInteractionsTask.removeReference(); - - { - PX_PROFILE_ZONE("Sim.clearIslandData", getContextId()); -// PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - Bp::AABBManagerBase* aabbMgr = mAABBManager; - PxU32 destroyedOverlapCount; - { - Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - Sc::ElementSimInteraction* pair = reinterpret_cast(p->mPairUserData); - if(pair) - { - if(pair->getType() == InteractionType::eOVERLAP) - { - ShapeInteraction* si = static_cast(pair); - si->clearIslandGenData(); - } - } - p++; - } - } - } - - mDestroyManagersTask.removeReference(); -} - -void Sc::Scene::processLostContacts3(PxBaseTask* /*continuation*/) -{ - { - PX_PROFILE_ZONE("Sim.processLostOverlapsStage2", getContextId()); - - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - Bp::AABBManagerBase* aabbMgr = mAABBManager; - PxU32 destroyedOverlapCount; - - { - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - ElementSim* volume0 = reinterpret_cast(p->mUserData0); - ElementSim* volume1 = reinterpret_cast(p->mUserData1); - - mNPhaseCore->onOverlapRemoved(volume0, volume1, false, p->mPairUserData, outputs); - p++; - } - } - - { - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eTRIGGER, destroyedOverlapCount); - while(destroyedOverlapCount--) - { - ElementSim* volume0 = reinterpret_cast(p->mUserData0); - ElementSim* volume1 = reinterpret_cast(p->mUserData1); - - mNPhaseCore->onOverlapRemoved(volume0, volume1, false, NULL, outputs); - p++; - } - } - - aabbMgr->freeBuffers(); - } - - mPostThirdPassIslandGenTask.removeReference(); -} - -//This is called after solver finish -void Sc::Scene::updateSimulationController(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.updateSimulationController", getContextId()); - - PxsTransformCache& cache = getLowLevelContext()->getTransformCache(); - Bp::BoundsArray& boundArray = getBoundsArray(); - - PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); - - mSimulationController->gpuDmabackData(cache, boundArray, changedAABBMgrActorHandles, mPublicFlags & PxSceneFlag::eSUPPRESS_READBACK); - - //for pxgdynamicscontext: copy solver body data to body core - { - PX_PROFILE_ZONE("Sim.updateBodyCore", getContextId()); - mDynamicsContext->updateBodyCore(continuation); - } - //mSimulationController->update(cache, boundArray, changedAABBMgrActorHandles); - - /*mProcessLostPatchesTask.setContinuation(&mFinalizationPhase); - mProcessLostPatchesTask.removeReference();*/ -} - -void Sc::Scene::updateDynamics(PxBaseTask* continuation) -{ - //Allow processLostContactsTask to run until after 2nd pass of solver completes (update bodies, run sleeping logic etc.) - mProcessLostContactsTask3.setContinuation(static_cast(continuation)->getContinuation()); - mProcessLostContactsTask2.setContinuation(&mProcessLostContactsTask3); - mProcessLostContactsTask.setContinuation(&mProcessLostContactsTask2); - - ////dma bodies and shapes data to gpu - //mSimulationController->updateBodiesAndShapes(); - - mLLContext->getNpMemBlockPool().acquireConstraintMemory(); - - PX_PROFILE_START_CROSSTHREAD("Basic.dynamics", getContextId()); - PxU32 maxPatchCount = mLLContext->getMaxPatchCount(); - - mAABBManager->reallocateChangedAABBMgActorHandleMap(getElementIDPool().getMaxID()); - - //mNPhaseCore->processPersistentContactEvents(outputs, continuation); - - PxvNphaseImplementationContext* nphase = mLLContext->getNphaseImplementationContext(); - - mDynamicsContext->update(*mSimpleIslandManager, continuation, &mProcessLostContactsTask, - nphase, maxPatchCount, mMaxNbArticulationLinks, mDt, mGravity, mAABBManager->getChangedAABBMgActorHandleMap()); - - mSimpleIslandManager->clearDestroyedEdges(); - - mProcessLostContactsTask3.removeReference(); - mProcessLostContactsTask2.removeReference(); - mProcessLostContactsTask.removeReference(); -} - -//CCD -void Sc::Scene::updateCCDMultiPass(PxBaseTask* parentContinuation) -{ - getCcdBodies().forceSize_Unsafe(mSimulationControllerCallback->getNbCcdBodies()); - - // second run of the broadphase for making sure objects we have integrated did not tunnel. - if(mPublicFlags & PxSceneFlag::eENABLE_CCD) - { - if (mContactReportsNeedPostSolverVelocity) - { - // the CCD code will overwrite the post solver body velocities, hence, we need to extract the info - // first if any CCD enabled pair requested it. - collectPostSolverVelocitiesBeforeCCD(); - } - - //We use 2 CCD task chains to be able to chain together an arbitrary number of ccd passes - if(mPostCCDPass.size() != 2) - { - mPostCCDPass.clear(); - mUpdateCCDSinglePass.clear(); - mCCDBroadPhase.clear(); - mCCDBroadPhaseAABB.clear(); - mPostCCDPass.reserve(2); - mUpdateCCDSinglePass.reserve(2); - mUpdateCCDSinglePass2.reserve(2); - mUpdateCCDSinglePass3.reserve(2); - mCCDBroadPhase.reserve(2); - mCCDBroadPhaseAABB.reserve(2); - for (int j = 0; j < 2; j++) - { - mPostCCDPass.pushBack(Cm::DelegateTask(getContextId(), this, "ScScene.postCCDPass")); - mUpdateCCDSinglePass.pushBack(Cm::DelegateTask(getContextId(), this, "ScScene.updateCCDSinglePass")); - mUpdateCCDSinglePass2.pushBack(Cm::DelegateTask(getContextId(), this, "ScScene.updateCCDSinglePassStage2")); - mUpdateCCDSinglePass3.pushBack(Cm::DelegateTask(getContextId(), this, "ScScene.updateCCDSinglePassStage3")); - mCCDBroadPhase.pushBack(Cm::DelegateTask(getContextId(), this, "ScScene.ccdBroadPhase")); - mCCDBroadPhaseAABB.pushBack(Cm::DelegateTask(getContextId(), this, "ScScene.ccdBroadPhaseAABB")); - } - } - - //reset thread context in a place we know all tasks possibly accessing it, are in sync with. (see US6664) - mLLContext->resetThreadContexts(); - - mCCDContext->updateCCDBegin(); - - mCCDBroadPhase[0].setContinuation(parentContinuation); - mCCDBroadPhaseAABB[0].setContinuation(&mCCDBroadPhase[0]); - mCCDBroadPhase[0].removeReference(); - mCCDBroadPhaseAABB[0].removeReference(); - } -} - -//CCD -class UpdateCCDBoundsTask : public Cm::Task -{ - Bp::BoundsArray* mBoundArray; - PxsTransformCache* mTransformCache; - Sc::BodySim** mBodySims; - PxU32 mNbToProcess; - PxI32* mNumFastMovingShapes; - -public: - - static const PxU32 MaxPerTask = 256; - - UpdateCCDBoundsTask(PxU64 contextID, Bp::BoundsArray* boundsArray, PxsTransformCache* transformCache, Sc::BodySim** bodySims, PxU32 nbToProcess, PxI32* numFastMovingShapes) : - Cm::Task (contextID), - mBoundArray (boundsArray), - mTransformCache (transformCache), - mBodySims (bodySims), - mNbToProcess (nbToProcess), - mNumFastMovingShapes(numFastMovingShapes) - { - } - - virtual const char* getName() const { return "UpdateCCDBoundsTask";} - - PxIntBool updateSweptBounds(Sc::ShapeSim* sim, Sc::BodySim* body) - { - PX_ASSERT(body==sim->getBodySim()); - - const PxU32 elementID = sim->getElementID(); - - const Sc::ShapeCore& shapeCore = sim->getCore(); - const PxTransform& endPose = mTransformCache->getTransformCache(elementID).transform; - - const PxGeometry& shapeGeom = shapeCore.getGeometry(); - - const PxsRigidBody& rigidBody = body->getLowLevelBody(); - const PxsBodyCore& bodyCore = body->getBodyCore().getCore(); - PX_ALIGN(16, PxTransform shape2World); - Cm::getDynamicGlobalPoseAligned(rigidBody.mLastTransform, shapeCore.getShape2Actor(), bodyCore.getBody2Actor(), shape2World); - - const float ccdThreshold = computeCCDThreshold(shapeGeom); - PxBounds3 bounds = Gu::computeBounds(shapeGeom, endPose); - PxIntBool isFastMoving; - if(1) - { - // PT: this alternative implementation avoids computing the start bounds for slow moving objects. - isFastMoving = (shape2World.p - endPose.p).magnitudeSquared() >= ccdThreshold * ccdThreshold ? 1 : 0; - if (isFastMoving) - { - const PxBounds3 startBounds = Gu::computeBounds(shapeGeom, shape2World); - bounds.include(startBounds); - } - } - else - { - const PxBounds3 startBounds = Gu::computeBounds(shapeGeom, shape2World); - - isFastMoving = (startBounds.getCenter() - bounds.getCenter()).magnitudeSquared() >= ccdThreshold * ccdThreshold ? 1 : 0; - - if(isFastMoving) - bounds.include(startBounds); - } - - PX_ASSERT(bounds.minimum.x <= bounds.maximum.x - && bounds.minimum.y <= bounds.maximum.y - && bounds.minimum.z <= bounds.maximum.z); - - mBoundArray->setBounds(bounds, elementID); - - return isFastMoving; - } - - virtual void runInternal() - { - PxU32 activeShapes = 0; - const PxU32 nb = mNbToProcess; - for(PxU32 i=0; i(*elems++); - if(sim->getFlags() & PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) - { - const PxIntBool fastMovingShape = updateSweptBounds(sim, &bodySim); - activeShapes += fastMovingShape; - - isFastMoving = isFastMoving | fastMovingShape; - } - } - - bodySim.getLowLevelBody().getCore().isFastMoving = isFastMoving!=0; - } - - PxAtomicAdd(mNumFastMovingShapes, PxI32(activeShapes)); - } -}; - -//CCD -void Sc::Scene::ccdBroadPhaseAABB(PxBaseTask* continuation) -{ - PX_PROFILE_START_CROSSTHREAD("Sim.ccdBroadPhaseComplete", getContextId()); - PX_PROFILE_ZONE("Sim.ccdBroadPhaseAABB", getContextId()); - PX_UNUSED(continuation); - - PxU32 currentPass = mCCDContext->getCurrentCCDPass(); - - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - mNumFastMovingShapes = 0; - - //If we are on the 1st pass or we had some sweep hits previous CCD pass, we need to run CCD again - if( currentPass == 0 || mCCDContext->getNumSweepHits()) - { - PxsTransformCache& transformCache = getLowLevelContext()->getTransformCache(); - for (PxU32 i = 0; i < mCcdBodies.size(); i+= UpdateCCDBoundsTask::MaxPerTask) - { - const PxU32 nbToProcess = PxMin(UpdateCCDBoundsTask::MaxPerTask, mCcdBodies.size() - i); - UpdateCCDBoundsTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(UpdateCCDBoundsTask)), UpdateCCDBoundsTask)(getContextId(), mBoundsArray, &transformCache, &mCcdBodies[i], nbToProcess, &mNumFastMovingShapes); - task->setContinuation(continuation); - task->removeReference(); - } - } -} - -//CCD -void Sc::Scene::ccdBroadPhase(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.ccdBroadPhase", getContextId()); - - PxU32 currentPass = mCCDContext->getCurrentCCDPass(); - const PxU32 ccdMaxPasses = mCCDContext->getCCDMaxPasses(); - mCCDPass = currentPass+1; - - //If we are on the 1st pass or we had some sweep hits previous CCD pass, we need to run CCD again - if( (currentPass == 0 || mCCDContext->getNumSweepHits()) && mNumFastMovingShapes != 0) - { - const PxU32 currIndex = currentPass & 1; - const PxU32 nextIndex = 1 - currIndex; - //Initialize the CCD task chain unless this is the final pass - if(currentPass != (ccdMaxPasses - 1)) - { - mCCDBroadPhase[nextIndex].setContinuation(continuation); - mCCDBroadPhaseAABB[nextIndex].setContinuation(&mCCDBroadPhase[nextIndex]); - } - mPostCCDPass[currIndex].setContinuation(currentPass == ccdMaxPasses-1 ? continuation : &mCCDBroadPhaseAABB[nextIndex]); - mUpdateCCDSinglePass3[currIndex].setContinuation(&mPostCCDPass[currIndex]); - mUpdateCCDSinglePass2[currIndex].setContinuation(&mUpdateCCDSinglePass3[currIndex]); - mUpdateCCDSinglePass[currIndex].setContinuation(&mUpdateCCDSinglePass2[currIndex]); - - //Do the actual broad phase - PxBaseTask* continuationTask = &mUpdateCCDSinglePass[currIndex]; -// const PxU32 numCpuTasks = continuationTask->getTaskManager()->getCpuDispatcher()->getWorkerCount(); - - mCCDBp = true; - - mBpSecondPass.setContinuation(continuationTask); - mBpFirstPass.setContinuation(&mBpSecondPass); - - mBpSecondPass.removeReference(); - mBpFirstPass.removeReference(); - - //mAABBManager->updateAABBsAndBP(numCpuTasks, mLLContext->getTaskPool(), &mLLContext->getScratchAllocator(), false, continuationTask, NULL); - - //Allow the CCD task chain to continue - mPostCCDPass[currIndex].removeReference(); - mUpdateCCDSinglePass3[currIndex].removeReference(); - mUpdateCCDSinglePass2[currIndex].removeReference(); - mUpdateCCDSinglePass[currIndex].removeReference(); - if(currentPass != (ccdMaxPasses - 1)) - { - mCCDBroadPhase[nextIndex].removeReference(); - mCCDBroadPhaseAABB[nextIndex].removeReference(); - } - } - else if (currentPass == 0) - { - PX_PROFILE_STOP_CROSSTHREAD("Sim.ccdBroadPhaseComplete", getContextId()); - mCCDContext->resetContactManagers(); - } -} - -//CCD -void Sc::Scene::updateCCDSinglePass(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.updateCCDSinglePass", getContextId()); - mReportShapePairTimeStamp++; // This will makes sure that new report pairs will get created instead of re-using the existing ones. - - mAABBManager->postBroadPhase(NULL, *getFlushPool()); - finishBroadPhase(continuation); - - const PxU32 currentPass = mCCDContext->getCurrentCCDPass() + 1; // 0 is reserved for discrete collision phase - if(currentPass == 1) // reset the handle map so we only update CCD objects from here on - { - PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); - //changedAABBMgrActorHandles.clear(); - for(PxU32 i = 0; i < mCcdBodies.size();i++) - { - // PT: ### changedMap pattern #1 - PxU32 nbElems = mCcdBodies[i]->getNbElements(); - Sc::ElementSim** elems = mCcdBodies[i]->getElements(); - while (nbElems--) - { - Sc::ShapeSim* sim = static_cast(*elems++); - if (sim->getFlags()&PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) // TODO: need trigger shape here? - changedAABBMgrActorHandles.growAndSet(sim->getElementID()); - } - } - } -} - -//CCD -void Sc::Scene::updateCCDSinglePassStage2(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.updateCCDSinglePassStage2", getContextId()); - postBroadPhaseStage2(continuation); -} - -//CCD -void Sc::Scene::updateCCDSinglePassStage3(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.updateCCDSinglePassStage3", getContextId()); - mReportShapePairTimeStamp++; // This will makes sure that new report pairs will get created instead of re-using the existing ones. - - const PxU32 currentPass = mCCDContext->getCurrentCCDPass() + 1; // 0 is reserved for discrete collision phase - finishBroadPhaseStage2(currentPass); - PX_PROFILE_STOP_CROSSTHREAD("Sim.ccdBroadPhaseComplete", getContextId()); - - //reset thread context in a place we know all tasks possibly accessing it, are in sync with. (see US6664) - mLLContext->resetThreadContexts(); - - mCCDContext->updateCCD(mDt, continuation, mSimpleIslandManager->getAccurateIslandSim(), (mPublicFlags & PxSceneFlag::eDISABLE_CCD_RESWEEP), mNumFastMovingShapes); -} - -class ScKinematicPoseUpdateTask : public Cm::Task -{ - Sc::BodyCore*const* mKinematics; - PxU32 mNbKinematics; - -public: - static const PxU32 NbKinematicsPerTask = 1024; - - ScKinematicPoseUpdateTask(Sc::BodyCore*const* kinematics, PxU32 nbKinematics, PxU64 contextID) : - Cm::Task(contextID), mKinematics(kinematics), mNbKinematics(nbKinematics) - { - } - - virtual void runInternal() - { - for (PxU32 a = 0; a < mNbKinematics; ++a) - { - if ((a + 16) < mNbKinematics) - { - PxPrefetchLine(static_cast(mKinematics[a + 16])); - - if ((a + 4) < mNbKinematics) - { - PxPrefetchLine(static_cast(mKinematics[a + 4])->getSim()); - PxPrefetchLine(static_cast(mKinematics[a + 4])->getSim()->getSimStateData_Unchecked()); - } - } - Sc::BodyCore* b = static_cast(mKinematics[a]); - PX_ASSERT(b->getSim()->isKinematic()); - PX_ASSERT(b->getSim()->isActive()); - b->getSim()->updateKinematicPose(); - } - } - - virtual const char* getName() const - { - return "ScScene.ScKinematicPoseUpdateTask"; - } -}; - -void Sc::Scene::integrateKinematicPose() -{ - PX_PROFILE_ZONE("Sim.integrateKinematicPose", getContextId()); - - const PxU32 nbKinematics = getActiveKinematicBodiesCount(); - BodyCore*const* kinematics = getActiveKinematicBodies(); - - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - for(PxU32 i=0; isetContinuation(&mConstraintProjection); - task->removeReference(); - } -} - -class ScKinematicShapeUpdateTask : public Cm::Task -{ - Sc::BodyCore*const* mKinematics; - PxU32 mNbKinematics; - PxsTransformCache& mCache; - Bp::BoundsArray& mBoundsArray; - - PX_NOCOPY(ScKinematicShapeUpdateTask) - -public: - static const PxU32 NbKinematicsShapesPerTask = 1024; - - ScKinematicShapeUpdateTask(Sc::BodyCore*const* kinematics, PxU32 nbKinematics, PxsTransformCache& cache, Bp::BoundsArray& boundsArray, PxU64 contextID) : - Cm::Task(contextID), mKinematics(kinematics), mNbKinematics(nbKinematics), mCache(cache), mBoundsArray(boundsArray) - { - } - - virtual void runInternal() - { - for (PxU32 a = 0; a < mNbKinematics; ++a) - { - Sc::BodyCore* b = static_cast(mKinematics[a]); - PX_ASSERT(b->getSim()->isKinematic()); - PX_ASSERT(b->getSim()->isActive()); - - b->getSim()->updateCached(mCache, mBoundsArray); - } - } - - virtual const char* getName() const - { - return "ScScene.KinematicShapeUpdateTask"; - } -}; - -void Sc::Scene::updateKinematicCached(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.updateKinematicCached", getContextId()); - - const PxU32 nbKinematics = getActiveKinematicBodiesCount(); - BodyCore*const* kinematics = getActiveKinematicBodies(); - - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - PxU32 startIndex = 0; - PxU32 nbShapes = 0; - - { - PX_PROFILE_ZONE("ShapeUpdate", getContextId()); - for(PxU32 i=0; i(kinematics[i])->getSim(); - PX_ASSERT(sim->isKinematic()); - PX_ASSERT(sim->isActive()); - - nbShapes += sim->getNbShapes(); - - if (nbShapes >= ScKinematicShapeUpdateTask::NbKinematicsShapesPerTask) - { - ScKinematicShapeUpdateTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScKinematicShapeUpdateTask)), ScKinematicShapeUpdateTask) - (kinematics + startIndex, (i + 1) - startIndex, mLLContext->getTransformCache(), *mBoundsArray, mContextId); - - task->setContinuation(continuation); - task->removeReference(); - startIndex = i + 1; - nbShapes = 0; - } - } - - if(nbShapes) - { - ScKinematicShapeUpdateTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScKinematicShapeUpdateTask)), ScKinematicShapeUpdateTask) - (kinematics + startIndex, nbKinematics - startIndex, mLLContext->getTransformCache(), *mBoundsArray, mContextId); - - task->setContinuation(continuation); - task->removeReference(); - } - } - - if(nbKinematics) - { - PxBitMapPinned& changedAABBMap = mAABBManager->getChangedAABBMgActorHandleMap(); - mLLContext->getTransformCache().setChangedState(); - mBoundsArray->setChangedState(); - for (PxU32 i = 0; i < nbKinematics; ++i) - { - Sc::BodySim* bodySim = static_cast(kinematics[i])->getSim(); - - if ((i+16) < nbKinematics) - { - PxPrefetchLine(kinematics[i + 16]); - if ((i + 8) < nbKinematics) - { - PxPrefetchLine(kinematics[i + 8]->getSim()); - } - } - - // PT: ### changedMap pattern #1 - PxU32 nbElems = bodySim->getNbElements(); - Sc::ElementSim** elems = bodySim->getElements(); - while (nbElems--) - { - Sc::ShapeSim* sim = static_cast(*elems++); - //KS - TODO - can we parallelize this? The problem with parallelizing is that it's a bit operation, - //so we would either need to use atomic operations or have some high-level concept that guarantees - //that threads don't write to the same word in the map simultaneously - if (sim->getFlags()&PxU32(PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eTRIGGER_SHAPE)) - { - changedAABBMap.set(sim->getElementID()); - } - } - - mSimulationController->updateDynamic(NULL, bodySim->getNodeIndex()); - } - } -} - -class ConstraintProjectionTask : public Cm::Task -{ -private: - PX_NOCOPY(ConstraintProjectionTask) - -public: - ConstraintProjectionTask(Sc::ConstraintGroupNode* const* projectionRoots, PxU32 projectionRootCount, PxArray& projectedBodies, PxsContext* llContext) : - Cm::Task (llContext->getContextId()), - mProjectionRoots (projectionRoots), - mProjectionRootCount(projectionRootCount), - mProjectedBodies (projectedBodies), - mLLContext (llContext) - { - } - - virtual void runInternal() - { - PX_PROFILE_ZONE("ConstraintProjection", mContextID); - PxcNpThreadContext* context = mLLContext->getNpThreadContext(); - PxArray& tempArray = context->mBodySimPool; - tempArray.forceSize_Unsafe(0); - for(PxU32 i=0; i < mProjectionRootCount; i++) - { - PX_ASSERT(mProjectionRoots[i]->hasProjectionTreeRoot()); // else, it must not be in the projection root list - Sc::ConstraintGroupNode::projectPose(*mProjectionRoots[i], tempArray); - mProjectionRoots[i]->clearFlag(Sc::ConstraintGroupNode::eIN_PROJECTION_PASS_LIST); - } - - if (tempArray.size() > 0) - { - mLLContext->getLock().lock(); - for (PxU32 a = 0; a < tempArray.size(); ++a) - mProjectedBodies.pushBack(tempArray[a]); - mLLContext->getLock().unlock(); - } - - mLLContext->putNpThreadContext(context); - } - - virtual const char* getName() const - { - return "ScScene.constraintProjectionWork"; - } - -public: - static const PxU32 sProjectingConstraintsPerTask = 256; // just a guideline, will not match exactly most of the time - -private: - Sc::ConstraintGroupNode* const* mProjectionRoots; - const PxU32 mProjectionRootCount; - PxArray& mProjectedBodies; - PxsContext* mLLContext; -}; - -void Sc::Scene::constraintProjection(PxBaseTask* continuation) -{ - if(mConstraints.size() == 0) - return; - PxU32 constraintGroupRootCount = 0; - //BodyCore*const* activeBodies = getActiveBodiesArray(); - //PxU32 activeBodyCount = getNumActiveBodies(); - IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - PxU32 activeBodyCount = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); - const PxNodeIndex* activeNodeIds = islandSim.getActiveNodes(IG::Node::eRIGID_BODY_TYPE); - - PX_ASSERT(!mTmpConstraintGroupRootBuffer); - PxU32 index = 0; - - const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); - - if(activeBodyCount) - { - mTmpConstraintGroupRootBuffer = reinterpret_cast(mLLContext->getScratchAllocator().alloc(sizeof(ConstraintGroupNode*) * activeBodyCount, true)); - if(mTmpConstraintGroupRootBuffer) - { - while(activeBodyCount--) - { - PxsRigidBody* rBody = islandSim.getRigidBody(activeNodeIds[index++]); - - Sc::BodySim* sim = reinterpret_cast(reinterpret_cast(rBody) - rigidBodyOffset); - //This move to PxgPostSolveWorkerTask for the gpu dynamic - //bodySim->sleepCheck(mDt, mOneOverDt, mEnableStabilization); - - if(sim->getConstraintGroup()) - { - ConstraintGroupNode& root = sim->getConstraintGroup()->getRoot(); - if(!root.readFlag(ConstraintGroupNode::eIN_PROJECTION_PASS_LIST) && root.hasProjectionTreeRoot()) - { - mTmpConstraintGroupRootBuffer[constraintGroupRootCount++] = &root; - root.raiseFlag(ConstraintGroupNode::eIN_PROJECTION_PASS_LIST); - } - } - } - - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - PxU32 constraintsToProjectCount = 0; - PxU32 startIndex = 0; - for(PxU32 i=0; i < constraintGroupRootCount; i++) - { - ConstraintGroupNode* root = mTmpConstraintGroupRootBuffer[i]; - - constraintsToProjectCount += root->getProjectionCountHint(); // for load balancing - if (constraintsToProjectCount >= ConstraintProjectionTask::sProjectingConstraintsPerTask) - { - ConstraintProjectionTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ConstraintProjectionTask)), - ConstraintProjectionTask(mTmpConstraintGroupRootBuffer + startIndex, i - startIndex + 1, mProjectedBodies, mLLContext)); - task->setContinuation(continuation); - task->removeReference(); - - constraintsToProjectCount = 0; - startIndex = i + 1; - } - } - - if (constraintsToProjectCount) - { - PX_ASSERT(startIndex < constraintGroupRootCount); - - ConstraintProjectionTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ConstraintProjectionTask)), - ConstraintProjectionTask(mTmpConstraintGroupRootBuffer + startIndex, constraintGroupRootCount - startIndex, mProjectedBodies, mLLContext)); - task->setContinuation(continuation); - task->removeReference(); - } - } - else - { - outputError(__LINE__, "List for collecting constraint projection roots could not be allocated. No projection will take place."); - } - } -} - -void Sc::Scene::postSolver(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sc::Scene::postSolver", getContextId()); - PxcNpMemBlockPool& blockPool = mLLContext->getNpMemBlockPool(); - - //Merge... - mDynamicsContext->mergeResults(); - blockPool.releaseConstraintMemory(); - //Swap friction! - blockPool.swapFrictionStreams(); - - mCcdBodies.clear(); - mProjectedBodies.clear(); - -#if PX_ENABLE_SIM_STATS - mLLContext->getSimStats().mPeakConstraintBlockAllocations = blockPool.getPeakConstraintBlockCount(); -#else - PX_CATCH_UNDEFINED_ENABLE_SIM_STATS -#endif - - mConstraintProjection.setContinuation(continuation); - - integrateKinematicPose(); - - mConstraintProjection.removeReference(); - - PxU32 size = mDirtyArticulationSims.size(); - Sc::ArticulationSim* const* articSims = mDirtyArticulationSims.getEntries(); - //clear the acceleration term for articulation if the application raised PxForceMode::eIMPULSE in addForce function. This change - //will make sure articulation and rigid body behave the same - for (PxU32 i = 0; i < size; ++i) - { - Sc::ArticulationSim* PX_RESTRICT articSim = articSims[i]; - articSim->clearAcceleration(mDt); - } - - //clear the dirty articulation list - mDirtyArticulationSims.clear(); - - //afterIntegration(continuation); -} - -//CCD -void Sc::Scene::postCCDPass(PxBaseTask* /*continuation*/) -{ - // - Performs sleep check - // - Updates touch flags - - PxU32 currentPass = mCCDContext->getCurrentCCDPass(); - PX_ASSERT(currentPass > 0); // to make sure changes to the CCD pass counting get noticed. For contact reports, 0 means discrete collision phase. - - int newTouchCount, lostTouchCount, ccdTouchCount; - mLLContext->getManagerTouchEventCount(&newTouchCount, &lostTouchCount, &ccdTouchCount); - PX_ALLOCA(newTouches, PxvContactManagerTouchEvent, newTouchCount); - PX_ALLOCA(lostTouches, PxvContactManagerTouchEvent, lostTouchCount); - PX_ALLOCA(ccdTouches, PxvContactManagerTouchEvent, ccdTouchCount); - - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - // Note: For contact notifications it is important that the new touch pairs get processed before the lost touch pairs. - // This allows to know for sure if a pair of actors lost all touch (see eACTOR_PAIR_LOST_TOUCH). - mLLContext->fillManagerTouchEvents(newTouches, newTouchCount, lostTouches, lostTouchCount, ccdTouches, ccdTouchCount); - for(PxI32 i=0; imanagerNewTouch(*si); - si->managerNewTouch(currentPass, true, outputs); - if (!si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) - { - mSimpleIslandManager->setEdgeConnected(si->getEdgeIndex(), IG::Edge::eCONTACT_MANAGER); - } - } - for(PxI32 i=0; imanagerLostTouch(currentPass, true, outputs) && !si->readFlag(ShapeInteraction::CONTACTS_RESPONSE_DISABLED)) - addToLostTouchList(si->getShape0().getActor(), si->getShape1().getActor()); - - mSimpleIslandManager->setEdgeDisconnected(si->getEdgeIndex()); - } - for(PxI32 i=0; isendCCDRetouch(currentPass, outputs); - } - checkForceThresholdContactEvents(currentPass); - { - PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); - - for (PxU32 i = 0, s = mCcdBodies.size(); i < s; i++) - { - BodySim*const body = mCcdBodies[i]; - if(i+8 < s) - PxPrefetch(mCcdBodies[i+8], 512); - - PX_ASSERT(body->getBody2World().p.isFinite()); - PX_ASSERT(body->getBody2World().q.isFinite()); - - body->updateCached(&changedAABBMgrActorHandles); - } - - ArticulationCore* const* articList = mArticulations.getEntries(); - for(PxU32 i=0;igetSim()->updateCached(&changedAABBMgrActorHandles); - } -} - -void Sc::Scene::finalizationPhase(PxBaseTask* /*continuation*/) -{ - PX_PROFILE_ZONE("Sim.sceneFinalization", getContextId()); - - if (mCCDContext) - { - //KS - force simulation controller to update any bodies updated by the CCD. When running GPU simulation, this would be required - //to ensure that cached body states are updated - const PxU32 nbUpdatedBodies = mCCDContext->getNumUpdatedBodies(); - PxsRigidBody*const* updatedBodies = mCCDContext->getUpdatedBodies(); - - const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); - - for (PxU32 a = 0; a < nbUpdatedBodies; ++a) - { - Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(updatedBodies[a]) - rigidBodyOffset); - updateBodySim(*bodySim); - } - - mCCDContext->clearUpdatedBodies(); - } - - if (mTmpConstraintGroupRootBuffer) - { - mLLContext->getScratchAllocator().free(mTmpConstraintGroupRootBuffer); - mTmpConstraintGroupRootBuffer = NULL; - } - - fireOnAdvanceCallback(); // placed here because it needs to be done after sleep check and after potential CCD passes - - checkConstraintBreakage(); // Performs breakage tests on breakable constraints - - PX_PROFILE_STOP_CROSSTHREAD("Basic.rigidBodySolver", getContextId()); - - mTaskPool.clear(); - - mReportShapePairTimeStamp++; // important to do this before fetchResults() is called to make sure that delayed deleted actors/shapes get - // separate pair entries in contact reports -} - -void Sc::Scene::postReportsCleanup() -{ - mElementIDPool->processPendingReleases(); - mElementIDPool->clearDeletedIDMap(); - - mActorIDTracker->processPendingReleases(); - mActorIDTracker->clearDeletedIDMap(); - - mConstraintIDTracker->processPendingReleases(); - mConstraintIDTracker->clearDeletedIDMap(); - - mSimulationController->flush(); -} - -PX_COMPILE_TIME_ASSERT(sizeof(PxTransform32)==sizeof(PxsCachedTransform)); - -// PT: TODO: move this out of Sc? this is only called by Np -void Sc::Scene::syncSceneQueryBounds(SqBoundsSync& sync, SqRefFinder& finder) -{ - const PxsTransformCache& cache = mLLContext->getTransformCache(); - - mSqBoundsManager->syncBounds(sync, finder, mBoundsArray->begin(), reinterpret_cast(cache.getTransforms()), getContextId(), mDirtyShapeSimMap); -} - -class ScKinematicUpdateTask : public Cm::Task -{ - Sc::BodyCore*const* mKinematics; - const PxU32 mNbKinematics; - const PxReal mOneOverDt; - - PX_NOCOPY(ScKinematicUpdateTask) -public: - - static const PxU32 NbKinematicsPerTask = 1024; - - ScKinematicUpdateTask(Sc::BodyCore*const* kinematics, PxU32 nbKinematics, PxReal oneOverDt, PxU64 contextID) : - Cm::Task(contextID), mKinematics(kinematics), mNbKinematics(nbKinematics), mOneOverDt(oneOverDt) - { - } - - virtual void runInternal() - { - Sc::BodyCore*const* kinematics = mKinematics; - PxU32 nb = mNbKinematics; - const float oneOverDt = mOneOverDt; - - while(nb--) - { - Sc::BodyCore* b = *kinematics++; - PX_ASSERT(b->getSim()->isKinematic()); - PX_ASSERT(b->getSim()->isActive()); - - b->getSim()->calculateKinematicVelocity(oneOverDt); - } - } - - virtual const char* getName() const - { - return "ScScene.KinematicUpdateTask"; - } -}; - -void Sc::Scene::kinematicsSetup(PxBaseTask* continuation) -{ - const PxU32 nbKinematics = getActiveKinematicBodiesCount(); - if(!nbKinematics) - return; - - BodyCore*const* kinematics = getActiveKinematicBodies(); - - // PT: create a copy of active bodies for the taks to operate on while the main array is - // potentially resized by operations running in parallel. - if(mActiveKinematicsCopyCapacitygetTaskPool(); - - // PT: TODO: better load balancing? This will be single threaded for less than 1K kinematics - for(PxU32 i = 0; i < nbKinematics; i += ScKinematicUpdateTask::NbKinematicsPerTask) - { - ScKinematicUpdateTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScKinematicUpdateTask)), ScKinematicUpdateTask) - (kinematics + i, PxMin(ScKinematicUpdateTask::NbKinematicsPerTask, nbKinematics - i), mOneOverDt, mContextId); - - task->setContinuation(continuation); - task->removeReference(); - } - - if((mPublicFlags & PxSceneFlag::eENABLE_GPU_DYNAMICS)) - { - // PT: running this serially for now because it's unsafe: mNPhaseCore->updateDirtyInteractions() (called after this) - // can also call mSimulationController.updateDynamic() via BodySim::internalWakeUpBase - PxU32 nb = nbKinematics; - while(nb--) - { - Sc::BodyCore* b = *kinematics++; - Sc::BodySim* bodySim = b->getSim(); - PX_ASSERT(!bodySim->getArticulation()); - mSimulationController->updateDynamic(NULL, bodySim->getNodeIndex()); - } - } -} - -//stepSetup is called in solve, but not collide -void Sc::Scene::stepSetupSolve(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.stepSetupSolve", getContextId()); - - kinematicsSetup(continuation); -} - -void Sc::Scene::stepSetupCollide(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.stepSetupCollide", getContextId()); - - { - PX_PROFILE_ZONE("Sim.projectionTreeUpdates", getContextId()); - mProjectionManager->processPendingUpdates(mLLContext->getScratchAllocator()); - } - - kinematicsSetup(continuation); - - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - // Update all dirty interactions - mNPhaseCore->updateDirtyInteractions(outputs); - mInternalFlags &= ~(SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_DOMINANCE | SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_VISUALIZATION); -} - -void Sc::Scene::processLostTouchPairs() -{ - PX_PROFILE_ZONE("Sc::Scene::processLostTouchPairs", getContextId()); - for (PxU32 i=0; iinternalWakeUp(); - if (!deletedBody2) - mLostTouchPairs[i].body2->internalWakeUp(); - continue; - } - - // If both are sleeping, we let them sleep - // (for example, two sleeping objects touch and the user teleports one (without waking it up)) - if (!mLostTouchPairs[i].body1->isActive() && - !mLostTouchPairs[i].body2->isActive()) - { - continue; - } - - // If only one has fallen asleep, we wake them both - if (!mLostTouchPairs[i].body1->isActive() || - !mLostTouchPairs[i].body2->isActive()) - { - mLostTouchPairs[i].body1->internalWakeUp(); - mLostTouchPairs[i].body2->internalWakeUp(); - } - } - - mLostTouchPairs.clear(); - mLostTouchPairsDeletedBodyIDs.clear(); -} - -class ScBeforeSolverTask : public Cm::Task -{ -public: - static const PxU32 MaxBodiesPerTask = 256; - PxNodeIndex mBodies[MaxBodiesPerTask]; - PxU32 mNumBodies; - const PxReal mDt; - IG::SimpleIslandManager* mIslandManager; - PxsSimulationController* mSimulationController; - -public: - - ScBeforeSolverTask(PxReal dt, IG::SimpleIslandManager* islandManager, PxsSimulationController* simulationController, PxU64 contextID) : - Cm::Task (contextID), - mDt (dt), - mIslandManager (islandManager), - mSimulationController (simulationController) - { - } - - virtual void runInternal() - { - PX_PROFILE_ZONE("Sim.ScBeforeSolverTask", mContextID); - const IG::IslandSim& islandSim = mIslandManager->getAccurateIslandSim(); - const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); - - PxsRigidBody* updatedBodySims[MaxBodiesPerTask]; - PxU32 updatedBodyNodeIndices[MaxBodiesPerTask]; - PxU32 nbUpdatedBodySims = 0; - - PxU32 nb = mNumBodies; - const PxNodeIndex* bodies = mBodies; - while(nb--) - { - const PxNodeIndex index = *bodies++; - - if(islandSim.getActiveNodeIndex(index) != PX_INVALID_NODE) - { - if (islandSim.getNode(index).mType == IG::Node::eRIGID_BODY_TYPE) - { - PxsRigidBody* body = islandSim.getRigidBody(index); - Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(body) - rigidBodyOffset); - bodySim->updateForces(mDt, updatedBodySims, updatedBodyNodeIndices, nbUpdatedBodySims, NULL); - } - } - } - - if(nbUpdatedBodySims) - mSimulationController->updateBodies(updatedBodySims, updatedBodyNodeIndices, nbUpdatedBodySims); - } - - virtual const char* getName() const - { - return "ScScene.beforeSolver"; - } - -private: - PX_NOCOPY(ScBeforeSolverTask) -}; - -class ScArticBeforeSolverCCDTask : public Cm::Task -{ -public: - const PxNodeIndex* const mArticIndices; - const PxU32 mNumArticulations; - const PxReal mDt; - IG::SimpleIslandManager* mIslandManager; - -public: - - ScArticBeforeSolverCCDTask(const PxNodeIndex* const articIndices, PxU32 nbArtics, PxReal dt, IG::SimpleIslandManager* islandManager, PxU64 contextID) : - Cm::Task(contextID), - mArticIndices(articIndices), - mNumArticulations(nbArtics), - mDt(dt), - mIslandManager(islandManager) - { - } - - virtual void runInternal() - { - PX_PROFILE_ZONE("Sim.ScArticBeforeSolverCCDTask", mContextID); - const IG::IslandSim& islandSim = mIslandManager->getAccurateIslandSim(); - - for (PxU32 a = 0; a < mNumArticulations; ++a) - { - Sc::ArticulationSim* articSim = islandSim.getArticulationSim(mArticIndices[a]); - - articSim->saveLastCCDTransform(); - } - } - - virtual const char* getName() const - { - return "ScScene.ScArticBeforeSolverCCDTask"; - } - -private: - PX_NOCOPY(ScArticBeforeSolverCCDTask) -}; - -class ScArticBeforeSolverTask : public Cm::Task -{ -public: - Sc::ArticulationSim* const* mArticSims; - const PxU32 mNumArticulations; - const PxReal mDt; - IG::SimpleIslandManager* mIslandManager; - -public: - - ScArticBeforeSolverTask(Sc::ArticulationSim* const* articSims, PxU32 nbArtics, PxReal dt, IG::SimpleIslandManager* islandManager, PxU64 contextID) : - Cm::Task(contextID), - mArticSims(articSims), - mNumArticulations(nbArtics), - mDt(dt), - mIslandManager(islandManager) - { - } - - virtual void runInternal() - { - PX_PROFILE_ZONE("Sim.ScArticBeforeSolverTask", mContextID); - //const IG::IslandSim& islandSim = mIslandManager->getAccurateIslandSim(); - - for (PxU32 a = 0; a < mNumArticulations; ++a) - { - Sc::ArticulationSim* PX_RESTRICT articSim = mArticSims[a]; - //articSim->checkResize(); - articSim->updateForces(mDt, false); - articSim->setDirtyFlag(Sc::ArticulationSimDirtyFlag::eNONE); - } - } - - virtual const char* getName() const - { - return "ScScene.ScArticBeforeSolverTask"; - } - -private: - PX_NOCOPY(ScArticBeforeSolverTask) -}; - -void Sc::Scene::beforeSolver(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sim.updateForces", getContextId()); - - // Note: For contact notifications it is important that force threshold checks are done after new/lost touches have been processed - // because pairs might get added to the list processed below - - // Atoms that passed contact force threshold - ThresholdStream& thresholdStream = mDynamicsContext->getThresholdStream(); - thresholdStream.clear(); - - const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - - const PxU32 nbActiveBodies = islandSim.getNbActiveNodes(IG::Node::eRIGID_BODY_TYPE); - - mNumDeactivatingNodes[IG::Node::eRIGID_BODY_TYPE] = 0;//islandSim.getNbNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); - mNumDeactivatingNodes[IG::Node::eARTICULATION_TYPE] = 0;//islandSim.getNbNodesToDeactivate(IG::Node::eARTICULATION_TYPE); - mNumDeactivatingNodes[IG::Node::eSOFTBODY_TYPE] = 0; - mNumDeactivatingNodes[IG::Node::eFEMCLOTH_TYPE] = 0; - mNumDeactivatingNodes[IG::Node::ePARTICLESYSTEM_TYPE] = 0; - mNumDeactivatingNodes[IG::Node::eHAIRSYSTEM_TYPE] = 0; - - const PxU32 MaxBodiesPerTask = ScBeforeSolverTask::MaxBodiesPerTask; - - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - mSimulationController->reserve(nbActiveBodies); - - { - PxBitMap::Iterator iter(mVelocityModifyMap); - - for (PxU32 i = iter.getNext(); i != PxBitMap::Iterator::DONE; /*i = iter.getNext()*/) - { - ScBeforeSolverTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScBeforeSolverTask)), ScBeforeSolverTask(mDt, mSimpleIslandManager, mSimulationController, getContextId())); - PxU32 count = 0; - for (; count < MaxBodiesPerTask && i != PxBitMap::Iterator::DONE; i = iter.getNext()) - { - PxsRigidBody* body = islandSim.getRigidBody(PxNodeIndex(i)); - bool retainsAccelerations = false; - if (body) - { - task->mBodies[count++] = PxNodeIndex(i); - - retainsAccelerations = (body->mCore->mFlags & PxRigidBodyFlag::eRETAIN_ACCELERATIONS); - } - - if(!retainsAccelerations) - { - mVelocityModifyMap.reset(i); - } - } - task->mNumBodies = count; - task->setContinuation(continuation); - task->removeReference(); - } - } - - const PxU32 nbArticsPerTask = 32; - - const PxU32 nbDirtyArticulations = mDirtyArticulationSims.size(); - Sc::ArticulationSim* const* artiSim = mDirtyArticulationSims.getEntries(); - for (PxU32 a = 0; a < nbDirtyArticulations; a += nbArticsPerTask) - { - const PxU32 nbToProcess = PxMin(PxU32(nbDirtyArticulations - a), nbArticsPerTask); - - ScArticBeforeSolverTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScArticBeforeSolverTask)), ScArticBeforeSolverTask(artiSim + a, nbToProcess, - mDt, mSimpleIslandManager, getContextId())); - - task->setContinuation(continuation); - task->removeReference(); - } - - //if the scene has ccd flag on, we should call ScArticBeforeSolverCCDTask to copy the last transform to the current transform - if (mPublicFlags & PxSceneFlag::eENABLE_CCD) - { - //CCD - const PxU32 nbActiveArticulations = islandSim.getNbActiveNodes(IG::Node::eARTICULATION_TYPE); - const PxNodeIndex* const articIndices = islandSim.getActiveNodes(IG::Node::eARTICULATION_TYPE); - - for (PxU32 a = 0; a < nbActiveArticulations; a += nbArticsPerTask) - { - const PxU32 nbToProcess = PxMin(PxU32(nbActiveArticulations - a), nbArticsPerTask); - ScArticBeforeSolverCCDTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(ScArticBeforeSolverCCDTask)), ScArticBeforeSolverCCDTask(articIndices + a, nbToProcess, - mDt, mSimpleIslandManager, getContextId())); - - task->setContinuation(continuation); - task->removeReference(); - } - } - - for (PxU32 a = 0; a < nbDirtyArticulations; a++) - { - mSimulationController->updateArticulationExtAccel(artiSim[a]->getLowLevelArticulation(), artiSim[a]->getIslandNodeIndex()); - } - - mBodyGravityDirty = false; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -class UpdateProjectedPoseTask : public Cm::Task -{ - Sc::BodySim** mProjectedBodies; - const PxU32 mNbBodiesToProcess; - - PX_NOCOPY(UpdateProjectedPoseTask) -public: - - UpdateProjectedPoseTask(PxU64 contextID, Sc::BodySim** projectedBodies, PxU32 nbBodiesToProcess) : - Cm::Task (contextID), - mProjectedBodies (projectedBodies), - mNbBodiesToProcess (nbBodiesToProcess) - { - } - - virtual void runInternal() - { - for (PxU32 a = 0; a < mNbBodiesToProcess; ++a) - { - mProjectedBodies[a]->updateCached(NULL); - } - } - - virtual const char* getName() const - { - return "ScScene.UpdateProjectedPoseTask"; - } -}; - -void Sc::Scene::afterIntegration(PxBaseTask* continuation) -{ - PX_PROFILE_ZONE("Sc::Scene::afterIntegration", getContextId()); - mLLContext->getTransformCache().resetChangedState(); //Reset the changed state. If anything outside of the GPU kernels updates any shape's transforms, this will be raised again - getBoundsArray().resetChangedState(); - - PxsTransformCache& cache = getLowLevelContext()->getTransformCache(); - Bp::BoundsArray& boundArray = getBoundsArray(); - - { - PX_PROFILE_ZONE("AfterIntegration::lockStage", getContextId()); - mLLContext->getLock().lock(); - - { - PX_PROFILE_ZONE("SimController", getContextId()); - mSimulationController->updateScBodyAndShapeSim(cache, boundArray, continuation); - } - - const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - - const PxU32 rigidBodyOffset = Sc::BodySim::getRigidBodyOffset(); - - const PxU32 numBodiesToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); - - const PxNodeIndex*const deactivatingIndices = islandSim.getNodesToDeactivate(IG::Node::eRIGID_BODY_TYPE); - - PxU32 previousNumBodiesToDeactivate = mNumDeactivatingNodes[IG::Node::eRIGID_BODY_TYPE]; - - { - PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); - PX_PROFILE_ZONE("AfterIntegration::deactivateStage", getContextId()); - for (PxU32 i = previousNumBodiesToDeactivate; i < numBodiesToDeactivate; i++) - { - PxsRigidBody* rigid = islandSim.getRigidBody(deactivatingIndices[i]); - Sc::BodySim* bodySim = reinterpret_cast(reinterpret_cast(rigid) - rigidBodyOffset); - //we need to set the rigid body back to the previous pose for the deactivated objects. This emulates the previous behavior where island gen ran before the solver, ensuring - //that bodies that should be deactivated this frame never reach the solver. We now run the solver in parallel with island gen, so objects that should be deactivated this frame - //still reach the solver and are integrated. However, on the frame when they should be deactivated, we roll back to their state at the beginning of the frame to ensure that the - //user perceives the same behavior as before. - - PxsBodyCore& bodyCore = bodySim->getBodyCore().getCore(); - - //if(!islandSim.getNode(bodySim->getNodeIndex()).isActive()) - rigid->setPose(rigid->getLastCCDTransform()); - - bodySim->updateCached(&changedAABBMgrActorHandles); - updateBodySim(*bodySim); - - //solver is running in parallel with IG(so solver might solving the body which IG identify as deactivatedNodes). After we moved sleepCheck into the solver after integration, sleepChecks - //might have processed bodies that are now considered deactivated. This could have resulted in either freezing or unfreezing one of these bodies this frame, so we need to process those - //events to ensure that the SqManager's bounds arrays are consistently maintained. Also, we need to clear the frame flags for these bodies. - - if (rigid->isFreezeThisFrame()) - bodySim->freezeTransforms(&mAABBManager->getChangedAABBMgActorHandleMap()); - - //KS - the IG deactivates bodies in parallel with the solver. It appears that under certain circumstances, the solver's integration (which performs - //sleep checks) could decide that the body is no longer a candidate for sleeping on the same frame that the island gen decides to deactivate the island - //that the body is contained in. This is a rare occurrence but the behavior we want to emulate is that of IG running before solver so we should therefore - //permit the IG to make the authoritative decision over whether the body should be active or inactive. - bodyCore.wakeCounter = 0.0f; - bodyCore.linearVelocity = PxVec3(0.0f); - bodyCore.angularVelocity = PxVec3(0.0f); - - rigid->clearAllFrameFlags(); - } - } - - const PxU32 maxBodiesPerTask = 256; - - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); - - { - PX_PROFILE_ZONE("AfterIntegration::dispatchTasks", getContextId()); - for (PxU32 a = 0; a < mProjectedBodies.size(); a += maxBodiesPerTask) - { - UpdateProjectedPoseTask* task = - PX_PLACEMENT_NEW(flushPool.allocate(sizeof(UpdateProjectedPoseTask)), UpdateProjectedPoseTask)(getContextId(), &mProjectedBodies[a], PxMin(maxBodiesPerTask, mProjectedBodies.size() - a)); - task->setContinuation(continuation); - task->removeReference(); - } - } - - { - PxBitMapPinned& changedAABBMgrActorHandles = mAABBManager->getChangedAABBMgActorHandleMap(); - PX_PROFILE_ZONE("AfterIntegration::growAndSet", getContextId()); - for (PxU32 a = 0; a < mProjectedBodies.size(); ++a) - { - if (!mProjectedBodies[a]->isFrozen()) - { - // PT: ### changedMap pattern #1 - PxU32 nbElems = mProjectedBodies[a]->getNbElements(); - Sc::ElementSim** elems = mProjectedBodies[a]->getElements(); - while (nbElems--) - { - Sc::ShapeSim* sim = static_cast(*elems++); - if (sim->isInBroadPhase()) - changedAABBMgrActorHandles.growAndSet(sim->getElementID()); - } - } - } - } - { - PX_PROFILE_ZONE("AfterIntegration::managerAndDynamic", getContextId()); - const PxU32 unrollSize = 256; - for (PxU32 a = 0; a < mProjectedBodies.size(); a += unrollSize) - { - PxsRigidBody* tempBodies[unrollSize]; - PxU32 nodeIds[unrollSize]; - const PxU32 nbToProcess = PxMin(unrollSize, mProjectedBodies.size() - a); - for (PxU32 i = 0; i < nbToProcess; ++i) - { - tempBodies[i] = &mProjectedBodies[a + i]->getLowLevelBody(); - nodeIds[i] = mProjectedBodies[a + i]->getNodeIndex().index(); - } - //KS - it seems that grabbing the CUDA context/releasing it is expensive so we should minimize how - //frequently we do that. Batch processing like this helps - mSimulationController->updateBodies(tempBodies, nodeIds, nbToProcess); - } - } - - updateKinematicCached(continuation); - - mLLContext->getLock().unlock(); - } - - IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); - - const PxU32 nbActiveArticulations = islandSim.getNbActiveNodes(IG::Node::eARTICULATION_TYPE); - - if(nbActiveArticulations) - { - mSimulationController->updateArticulationAfterIntegration(mLLContext, mAABBManager, mCcdBodies, continuation, islandSim, mDt); - } - - const PxU32 numArticsToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eARTICULATION_TYPE); - - const PxNodeIndex*const deactivatingArticIndices = islandSim.getNodesToDeactivate(IG::Node::eARTICULATION_TYPE); - - PxU32 previousNumArticsToDeactivate = mNumDeactivatingNodes[IG::Node::eARTICULATION_TYPE]; - - for (PxU32 i = previousNumArticsToDeactivate; i < numArticsToDeactivate; ++i) - { - Sc::ArticulationSim* artic = islandSim.getArticulationSim(deactivatingArticIndices[i]); - - artic->putToSleep(); - } - - //PxU32 previousNumClothToDeactivate = mNumDeactivatingNodes[IG::Node::eFEMCLOTH_TYPE]; - //const PxU32 numClothToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eFEMCLOTH_TYPE); - //const IG::NodeIndex*const deactivatingClothIndices = islandSim.getNodesToDeactivate(IG::Node::eFEMCLOTH_TYPE); - - //for (PxU32 i = previousNumClothToDeactivate; i < numClothToDeactivate; ++i) - //{ - // FEMCloth* cloth = islandSim.getLLFEMCloth(deactivatingClothIndices[i]); - // mSimulationController->deactivateCloth(cloth); - //} - - //PxU32 previousNumSoftBodiesToDeactivate = mNumDeactivatingNodes[IG::Node::eSOFTBODY_TYPE]; - //const PxU32 numSoftBodiesToDeactivate = islandSim.getNbNodesToDeactivate(IG::Node::eSOFTBODY_TYPE); - //const IG::NodeIndex*const deactivatingSoftBodiesIndices = islandSim.getNodesToDeactivate(IG::Node::eSOFTBODY_TYPE); - - //for (PxU32 i = previousNumSoftBodiesToDeactivate; i < numSoftBodiesToDeactivate; ++i) - //{ - // Dy::SoftBody* softbody = islandSim.getLLSoftBody(deactivatingSoftBodiesIndices[i]); - // printf("after Integration: Deactivating soft body %i\n", softbody->getGpuRemapId()); - // //mSimulationController->deactivateSoftbody(softbody); - // softbody->getSoftBodySim()->setActive(false, 0); - //} - - PX_PROFILE_STOP_CROSSTHREAD("Basic.dynamics", getContextId()); - - checkForceThresholdContactEvents(0); -} - -void Sc::Scene::checkForceThresholdContactEvents(const PxU32 ccdPass) -{ - PX_PROFILE_ZONE("Sim.checkForceThresholdContactEvents", getContextId()); - - // Note: For contact notifications it is important that force threshold checks are done after new/lost touches have been processed - // because pairs might get added to the list processed below - - // Bodies that passed contact force threshold - - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - ThresholdStream& thresholdStream = mDynamicsContext->getForceChangedThresholdStream(); - - const PxU32 nbThresholdElements = thresholdStream.size(); - - for (PxU32 i = 0; i< nbThresholdElements; ++i) - { - ThresholdStreamElement& elem = thresholdStream[i]; - ShapeInteraction* si = elem.shapeInteraction; - - //If there is a shapeInteraction and the shapeInteraction points to a contactManager (i.e. the CM was not destroyed in parallel with the solver) - if (si != NULL) - { - PxU32 pairFlags = si->getPairFlags(); - if (pairFlags & ShapeInteraction::CONTACT_FORCE_THRESHOLD_PAIRS) - { - si->swapAndClearForceThresholdExceeded(); - - if (elem.accumulatedForce > elem.threshold * mDt) - { - si->raiseFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_NOW); - - PX_ASSERT(si->hasTouch()); - - //If the accumulatedForce is large than the threshold in the current frame and the accumulatedForce is less than the threshold in the previous frame, - //and the user request notify for found event, we will raise eNOTIFY_THRESHOLD_FORCE_FOUND - if ((!si->readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_BEFORE)) && (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND)) - { - si->processUserNotification(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_FOUND, 0, false, ccdPass, false, outputs); - } - else if (si->readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_BEFORE) && (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS)) - { - si->processUserNotification(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_PERSISTS, 0, false, ccdPass, false, outputs); - } - } - else - { - //If the accumulatedForce is less than the threshold in the current frame and the accumulatedForce is large than the threshold in the previous frame, - //and the user request notify for found event, we will raise eNOTIFY_THRESHOLD_FORCE_LOST - if (si->readFlag(ShapeInteraction::FORCE_THRESHOLD_EXCEEDED_BEFORE) && (pairFlags & PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST)) - { - si->processUserNotification(PxPairFlag::eNOTIFY_THRESHOLD_FORCE_LOST, 0, false, ccdPass, false, outputs); - } - } - } - } - } -} - -void Sc::Scene::endStep() -{ - mTimeStamp++; -// INVALID_SLEEP_COUNTER is 0xffffffff. Therefore the last bit is masked. Look at Body::isForcedToSleep() for example. -// if(timeStamp==PX_INVALID_U32) timeStamp = 0; // Reserve INVALID_ID for something else - mTimeStamp &= 0x7fffffff; - - mReportShapePairTimeStamp++; // to make sure that deleted shapes/actors after fetchResults() create new report pairs -} - -void Sc::Scene::resizeReleasedBodyIDMaps(PxU32 maxActors, PxU32 numActors) -{ - mLostTouchPairsDeletedBodyIDs.resize(maxActors); - mActorIDTracker->resizeDeletedIDMap(maxActors,numActors); - mElementIDPool->resizeDeletedIDMap(maxActors,numActors); -} - -/** -Render objects before simulation starts -*/ -void Sc::Scene::visualizeStartStep() -{ - PX_PROFILE_ZONE("Sim.visualizeStartStep", getContextId()); - -#if PX_ENABLE_DEBUG_VISUALIZATION - if(!getVisualizationScale()) - { - // make sure visualization inside simulate was skipped - PX_ASSERT(getRenderBuffer().empty()); - return; // early out if visualization scale is 0 - } - - PxRenderOutput out(getRenderBuffer()); - - if(getVisualizationParameter(PxVisualizationParameter::eCOLLISION_COMPOUNDS)) - mAABBManager->visualize(out); - - // Visualize joints - Sc::ConstraintCore*const * constraints = mConstraints.getEntries(); - for(PxU32 i=0, size = mConstraints.size();igetSim()->visualize(getRenderBuffer()); - - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - - mNPhaseCore->visualize(out, outputs); -#else - PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION -#endif -} - -//CCD -void Sc::Scene::collectPostSolverVelocitiesBeforeCCD() -{ - if (mContactReportsNeedPostSolverVelocity) - { - ActorPairReport*const* actorPairs = mNPhaseCore->getContactReportActorPairs(); - PxU32 nbActorPairs = mNPhaseCore->getNbContactReportActorPairs(); - for(PxU32 i=0; i < nbActorPairs; i++) - { - if (i < (nbActorPairs - 1)) - PxPrefetchLine(actorPairs[i+1]); - - ActorPairReport* aPair = actorPairs[i]; - - ContactStreamManager& cs = aPair->getContactStreamManager(); - - PxU32 streamManagerFlag = cs.getFlags(); - if(streamManagerFlag & ContactStreamManagerFlag::eINVALID_STREAM) - continue; - - PxU8* stream = mNPhaseCore->getContactReportPairData(cs.bufferIndex); - - if(i + 1 < nbActorPairs) - PxPrefetch(&(actorPairs[i+1]->getContactStreamManager())); - - if (!cs.extraDataSize) - continue; - else if (streamManagerFlag & ContactStreamManagerFlag::eNEEDS_POST_SOLVER_VELOCITY) - cs.setContactReportPostSolverVelocity(stream, aPair->getActorA(), aPair->getActorB()); - } - } -} - -void Sc::Scene::finalizeContactStreamAndCreateHeader(PxContactPairHeader& header, const ActorPairReport& aPair, ContactStreamManager& cs, PxU32 removedShapeTestMask) -{ - PxU8* stream = mNPhaseCore->getContactReportPairData(cs.bufferIndex); - PxU32 streamManagerFlag = cs.getFlags(); - ContactShapePair* contactPairs = cs.getShapePairs(stream); - const PxU16 nbShapePairs = cs.currentPairCount; - PX_ASSERT(nbShapePairs > 0); - - if (streamManagerFlag & removedShapeTestMask) - { - // At least one shape of this actor pair has been deleted. Need to traverse the contact buffer, - // find the pairs which contain deleted shapes and set the flags accordingly. - - ContactStreamManager::convertDeletedShapesInContactStream(contactPairs, nbShapePairs, getElementIDPool()); - } - PX_ASSERT(contactPairs); - - ObjectIDTracker& ActorIDTracker = getActorIDTracker(); - header.actors[0] = aPair.getPxActorA(); - header.actors[1] = aPair.getPxActorB(); - PxU16 headerFlags = 0; - if (ActorIDTracker.isDeletedID(aPair.getActorAID())) - headerFlags |= PxContactPairHeaderFlag::eREMOVED_ACTOR_0; - if (ActorIDTracker.isDeletedID(aPair.getActorBID())) - headerFlags |= PxContactPairHeaderFlag::eREMOVED_ACTOR_1; - header.flags = PxContactPairHeaderFlags(headerFlags); - header.pairs = reinterpret_cast(contactPairs); - header.nbPairs = nbShapePairs; - - PxU16 extraDataSize = cs.extraDataSize; - if (!extraDataSize) - header.extraDataStream = NULL; - else - { - PX_ASSERT(extraDataSize >= sizeof(ContactStreamHeader)); - extraDataSize -= sizeof(ContactStreamHeader); - header.extraDataStream = stream + sizeof(ContactStreamHeader); - - if (streamManagerFlag & ContactStreamManagerFlag::eNEEDS_POST_SOLVER_VELOCITY) - { - PX_ASSERT(!(headerFlags & PxTo16(PxContactPairHeaderFlag::eREMOVED_ACTOR_0 | PxContactPairHeaderFlag::eREMOVED_ACTOR_1))); - cs.setContactReportPostSolverVelocity(stream, aPair.getActorA(), aPair.getActorB()); - } - } - header.extraDataStreamSize = extraDataSize; -} - -const PxArray& Sc::Scene::getQueuedContactPairHeaders() -{ - const PxU32 removedShapeTestMask = PxU32(ContactStreamManagerFlag::eTEST_FOR_REMOVED_SHAPES); - - ActorPairReport*const* actorPairs = mNPhaseCore->getContactReportActorPairs(); - PxU32 nbActorPairs = mNPhaseCore->getNbContactReportActorPairs(); - mQueuedContactPairHeaders.reserve(nbActorPairs); - mQueuedContactPairHeaders.clear(); - - for (PxU32 i = 0; i < nbActorPairs; i++) - { - if (i < (nbActorPairs - 1)) - PxPrefetchLine(actorPairs[i + 1]); - - ActorPairReport* aPair = actorPairs[i]; - ContactStreamManager& cs = aPair->getContactStreamManager(); - if (cs.getFlags() & ContactStreamManagerFlag::eINVALID_STREAM) - continue; - - if (i + 1 < nbActorPairs) - PxPrefetch(&(actorPairs[i + 1]->getContactStreamManager())); - - PxContactPairHeader &pairHeader = mQueuedContactPairHeaders.insert(); - finalizeContactStreamAndCreateHeader(pairHeader, *aPair, cs, removedShapeTestMask); - - cs.maxPairCount = cs.currentPairCount; - cs.setMaxExtraDataSize(cs.extraDataSize); - } - - return mQueuedContactPairHeaders; -} - -/* -Threading: called in the context of the user thread, but only after the physics thread has finished its run -*/ -void Sc::Scene::fireQueuedContactCallbacks() -{ - if(mSimulationEventCallback) - { - const PxU32 removedShapeTestMask = PxU32(ContactStreamManagerFlag::eTEST_FOR_REMOVED_SHAPES); - - ActorPairReport*const* actorPairs = mNPhaseCore->getContactReportActorPairs(); - PxU32 nbActorPairs = mNPhaseCore->getNbContactReportActorPairs(); - for(PxU32 i=0; i < nbActorPairs; i++) - { - if (i < (nbActorPairs - 1)) - PxPrefetchLine(actorPairs[i+1]); - - ActorPairReport* aPair = actorPairs[i]; - ContactStreamManager* cs = &aPair->getContactStreamManager(); - if (cs == NULL || cs->getFlags() & ContactStreamManagerFlag::eINVALID_STREAM) - continue; - - if (i + 1 < nbActorPairs) - PxPrefetch(&(actorPairs[i+1]->getContactStreamManager())); - - PxContactPairHeader pairHeader; - finalizeContactStreamAndCreateHeader(pairHeader, *aPair, *cs, removedShapeTestMask); - - mSimulationEventCallback->onContact(pairHeader, pairHeader.pairs, pairHeader.nbPairs); - - // estimates for next frame - cs->maxPairCount = cs->currentPairCount; - cs->setMaxExtraDataSize(cs->extraDataSize); - } - } -} - -PX_FORCE_INLINE void markDeletedShapes(Sc::ObjectIDTracker& idTracker, Sc::TriggerPairExtraData& tped, PxTriggerPair& pair) -{ - PxTriggerPairFlags::InternalType flags = 0; - if (idTracker.isDeletedID(tped.shape0ID)) - flags |= PxTriggerPairFlag::eREMOVED_SHAPE_TRIGGER; - if (idTracker.isDeletedID(tped.shape1ID)) - flags |= PxTriggerPairFlag::eREMOVED_SHAPE_OTHER; - - pair.flags = PxTriggerPairFlags(flags); -} - -void Sc::Scene::fireTriggerCallbacks() -{ - // triggers - const PxU32 nbTriggerPairs = mTriggerBufferAPI.size(); - PX_ASSERT(nbTriggerPairs == mTriggerBufferExtraData->size()); - if(nbTriggerPairs) - { - // cases to take into account: - // - no simulation/trigger shape has been removed -> no need to test shape references for removed shapes - // - simulation/trigger shapes have been removed -> test the events that have - // a marker for removed shapes set - // - const bool hasRemovedShapes = mElementIDPool->getDeletedIDCount() > 0; - - if(mSimulationEventCallback) - { - if (!hasRemovedShapes) - mSimulationEventCallback->onTrigger(mTriggerBufferAPI.begin(), nbTriggerPairs); - else - { - for(PxU32 i = 0; i < nbTriggerPairs; i++) - { - PxTriggerPair& triggerPair = mTriggerBufferAPI[i]; - - if ((PxTriggerPairFlags::InternalType(triggerPair.flags) & TriggerPairFlag::eTEST_FOR_REMOVED_SHAPES)) - markDeletedShapes(*mElementIDPool, (*mTriggerBufferExtraData)[i], triggerPair); - } - - mSimulationEventCallback->onTrigger(mTriggerBufferAPI.begin(), nbTriggerPairs); - } - } - } - - // PT: clear the buffer **even when there's no simulationEventCallback**. - mTriggerBufferAPI.clear(); - mTriggerBufferExtraData->clear(); -} - -void Sc::Scene::fireBrokenConstraintCallbacks() -{ - if(!mSimulationEventCallback) - return; - - const PxU32 count = mBrokenConstraints.size(); - for(PxU32 i=0;igetSim()); - - PxU32 typeID = 0xffffffff; - void* externalRef = c->getPxConnector()->getExternalReference(typeID); - PX_CHECK_MSG(typeID != 0xffffffff, "onConstraintBreak: Invalid constraint type ID."); - - PxConstraintInfo constraintInfo(c->getPxConstraint(), externalRef, typeID); - mSimulationEventCallback->onConstraintBreak(&constraintInfo, 1); - } -} - -/* -Threading: called in the context of the user thread, but only after the physics thread has finished its run -*/ -void Sc::Scene::fireCallbacksPostSync() -{ - // - // Fire sleep & woken callbacks - // - - // A body should be either in the sleep or the woken list. If it is in both, remove it from the list it was - // least recently added to. - - if(!mSleepBodyListValid) - cleanUpSleepBodies(); - - if(!mWokeBodyListValid) - cleanUpWokenBodies(); - -#if PX_SUPPORT_GPU_PHYSX - if (!mSleepSoftBodyListValid) - cleanUpSleepSoftBodies(); - - if (!mWokeBodyListValid) - cleanUpWokenSoftBodies(); - - if (!mSleepHairSystemListValid) - cleanUpSleepHairSystems(); - - if (!mWokeHairSystemListValid) // TODO(jcarius) should this be mWokeBodyListValid? - cleanUpWokenHairSystems(); -#endif - - if(mSimulationEventCallback || mOnSleepingStateChanged) - { - // allocate temporary data - const PxU32 nbSleep = mSleepBodies.size(); - const PxU32 nbWoken = mWokeBodies.size(); -#if PX_SUPPORT_GPU_PHYSX - const PxU32 nbHairSystemSleep = mSleepHairSystems.size(); - const PxU32 nbHairSystemWoken = mWokeHairSystems.size(); - const PxU32 nbSoftBodySleep = mSleepSoftBodies.size(); - const PxU32 nbSoftBodyWoken = mWokeSoftBodies.size(); - const PxU32 arrSize = PxMax(PxMax(nbSleep, nbWoken), PxMax(nbSoftBodySleep, nbHairSystemSleep)); -#else - const PxU32 arrSize = PxMax(nbSleep, nbWoken); -#endif - PxActor** actors = arrSize ? reinterpret_cast(PX_ALLOC(arrSize*sizeof(PxActor*), "PxActor*")) : NULL; - if(actors) - { - if(nbSleep) - { - PxU32 destSlot = 0; - BodyCore* const* sleepingBodies = mSleepBodies.getEntries(); - for(PxU32 i=0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) - actors[destSlot++] = body->getPxActor(); - if (mOnSleepingStateChanged) - mOnSleepingStateChanged(body->getPxActor(), true); - } - - if(destSlot && mSimulationEventCallback) - mSimulationEventCallback->onSleep(actors, destSlot); - - //if (PX_DBG_IS_CONNECTED()) - //{ - // for (PxU32 i = 0; i < nbSleep; ++i) - // { - // BodyCore* body = mSleepBodies[i]; - // PX_ASSERT(body->getActorType() == PxActorType::eRIGID_DYNAMIC); - // } - //} - } - -#if PX_SUPPORT_GPU_PHYSX - //ML: need to create and API for the onSleep for softbody - if (nbSoftBodySleep) - { - PxU32 destSlot = 0; - SoftBodyCore* const* sleepingSoftBodies = mSleepSoftBodies.getEntries(); - for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) - actors[destSlot++] = body->getPxActor(); - if (mOnSleepingStateChanged) - mOnSleepingStateChanged(body->getPxActor(), true); - } - - if (destSlot && mSimulationEventCallback) - mSimulationEventCallback->onSleep(actors, destSlot); - } - - if (nbHairSystemSleep) - { - PxU32 destSlot = 0; - HairSystemCore* const* sleepingHairSystems = mSleepHairSystems.getEntries(); - for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) - actors[destSlot++] = body->getPxActor(); - if (mOnSleepingStateChanged) - mOnSleepingStateChanged(body->getPxActor(), true); - } - - if (destSlot && mSimulationEventCallback) - mSimulationEventCallback->onSleep(actors, destSlot); - } -#endif - - // do the same thing for bodies that have just woken up - - if(nbWoken) - { - PxU32 destSlot = 0; - BodyCore* const* wokenBodies = mWokeBodies.getEntries(); - for(PxU32 i=0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) - actors[destSlot++] = body->getPxActor(); - if (mOnSleepingStateChanged) - mOnSleepingStateChanged(body->getPxActor(), false); - } - - if(destSlot && mSimulationEventCallback) - mSimulationEventCallback->onWake(actors, destSlot); - } - -#if PX_SUPPORT_GPU_PHYSX - //ML: need to create an API for woken soft body - if (nbSoftBodyWoken) - { - PxU32 destSlot = 0; - SoftBodyCore* const* wokenSoftBodies = mWokeSoftBodies.getEntries(); - for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) - actors[destSlot++] = body->getPxActor(); - if (mOnSleepingStateChanged) - mOnSleepingStateChanged(body->getPxActor(), false); - } - - if (destSlot && mSimulationEventCallback) - mSimulationEventCallback->onWake(actors, destSlot); - } - - if (nbHairSystemWoken) - { - PxU32 destSlot = 0; - HairSystemCore* const* wokenHairSystems = mWokeHairSystems.getEntries(); - for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) - actors[destSlot++] = body->getPxActor(); - if (mOnSleepingStateChanged) - mOnSleepingStateChanged(body->getPxActor(), false); - } - - if (destSlot && mSimulationEventCallback) - mSimulationEventCallback->onWake(actors, destSlot); - } -#endif - PX_FREE(actors); - } - } - - clearSleepWakeBodies(); -} - -void Sc::Scene::prepareOutOfBoundsCallbacks() -{ - PxU32 nbOut0; - void** outObjects = mAABBManager->getOutOfBoundsObjects(nbOut0); - - mOutOfBoundsIDs.clear(); - for(PxU32 i=0;i(outObjects[i]); - - Sc::ShapeSim* sim = static_cast(volume); - PxU32 id = sim->getElementID(); - mOutOfBoundsIDs.pushBack(id); - } -} - -bool Sc::Scene::fireOutOfBoundsCallbacks() -{ - bool outputWarning = false; - - // Actors - { - PxU32 nbOut0; - void** outObjects = mAABBManager->getOutOfBoundsObjects(nbOut0); - - const ObjectIDTracker& tracker = getElementIDPool(); - - PxBroadPhaseCallback* cb = mBroadPhaseCallback; - for(PxU32 i=0;i(outObjects[i]); - - Sc::ShapeSim* sim = static_cast(volume); - if(tracker.isDeletedID(mOutOfBoundsIDs[i])) - continue; - - if(cb) - { - ActorSim& actor = volume->getActor(); - RigidSim& rigidSim = static_cast(actor); - PxActor* pxActor = rigidSim.getPxActor(); - PxShape* px = sim->getPxShape(); - cb->onObjectOutOfBounds(*px, *pxActor); - } - else - { - outputWarning = true; - } + else + { + numActiveBodies = getActiveDynamicBodiesCount(); + activeBodies = getActiveDynamicBodies(); } - mAABBManager->clearOutOfBoundsObjects(); - } - - return outputWarning; -} - -void Sc::Scene::fireOnAdvanceCallback() -{ - if(!mSimulationEventCallback) - return; - - const PxU32 nbPosePreviews = mPosePreviewBodies.size(); - if(!nbPosePreviews) - return; - mClientPosePreviewBodies.clear(); - mClientPosePreviewBodies.reserve(nbPosePreviews); + mActiveActors.clear(); - mClientPosePreviewBuffer.clear(); - mClientPosePreviewBuffer.reserve(nbPosePreviews); - - const BodySim*const* PX_RESTRICT posePreviewBodies = mPosePreviewBodies.getEntries(); - for(PxU32 i=0; i(b.getPxActor())); - mClientPosePreviewBuffer.pushBack(c.body2World * c.getBody2Actor().getInverse()); + if (!activeBodies[i]->isFrozen()) + { + PxRigidActor* ra = static_cast(activeBodies[i]->getPxActor()); + PX_ASSERT(ra); + mActiveActors.pushBack(ra); + } } } - const PxU32 bodyCount = mClientPosePreviewBodies.size(); - if(bodyCount) - mSimulationEventCallback->onAdvance(mClientPosePreviewBodies.begin(), mClientPosePreviewBuffer.begin(), bodyCount); +#if PX_SUPPORT_GPU_PHYSX + gpu_buildActiveActors(); +#endif } -void Sc::Scene::postCallbacksPreSync() +// PT: TODO: unify buildActiveActors & buildActiveAndFrozenActors +void Sc::Scene::buildActiveAndFrozenActors() { - PX_PROFILE_ZONE("Sim.postCallbackPreSync", mContextId); - // clear contact stream data - mNPhaseCore->clearContactReportStream(); - mNPhaseCore->clearContactReportActorPairs(false); - - // Put/prepare kinematics to/for sleep and invalidate target pose - // note: this needs to get done after the contact callbacks because - // the target might get read there. - // - PxU32 nbKinematics = getActiveKinematicBodiesCount(); - BodyCore*const* kinematics = getActiveKinematicBodies(); - - //KS - this method must run over the kinematic actors in reverse. - while(nbKinematics--) { - if(nbKinematics > 16) + PxU32 numActiveBodies = 0; + BodyCore*const* PX_RESTRICT activeBodies; + if (!(getFlags() & PxSceneFlag::eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS)) { - PxPrefetchLine(static_cast(kinematics[nbKinematics-16])); + numActiveBodies = getNumActiveBodies(); + activeBodies = getActiveBodiesArray(); } - if (nbKinematics > 4) + else { - PxPrefetchLine((static_cast(kinematics[nbKinematics - 4]))->getSim()); - PxPrefetchLine((static_cast(kinematics[nbKinematics - 4]))->getSim()->getSimStateData_Unchecked()); + numActiveBodies = getActiveDynamicBodiesCount(); + activeBodies = getActiveDynamicBodies(); } - BodyCore* b = static_cast(kinematics[nbKinematics]); - //kinematics++; - PX_ASSERT(b->getSim()->isKinematic()); - PX_ASSERT(b->getSim()->isActive()); + mActiveActors.clear(); + mFrozenActors.clear(); - b->invalidateKinematicTarget(); - b->getSim()->deactivateKinematic(); - } + for (PxU32 i = 0; i < numActiveBodies; i++) + { + PxRigidActor* ra = static_cast(activeBodies[i]->getPxActor()); + PX_ASSERT(ra); - releaseConstraints(true); //release constraint blocks at the end of the frame, so user can retrieve the blocks -} + if (!activeBodies[i]->isFrozen()) + mActiveActors.pushBack(ra); + else + mFrozenActors.pushBack(ra); + } + } -void Sc::Scene::setNbContactDataBlocks(PxU32 numBlocks) -{ - mLLContext->getNpMemBlockPool().setBlockCount(numBlocks); +#if PX_SUPPORT_GPU_PHYSX + gpu_buildActiveAndFrozenActors(); +#endif } -PxU32 Sc::Scene::getNbContactDataBlocksUsed() const +PxActor** Sc::Scene::getActiveActors(PxU32& nbActorsOut) { - return mLLContext->getNpMemBlockPool().getUsedBlockCount(); -} + nbActorsOut = mActiveActors.size(); + + if(!nbActorsOut) + return NULL; -PxU32 Sc::Scene::getMaxNbContactDataBlocksUsed() const -{ - return mLLContext->getNpMemBlockPool().getMaxUsedBlockCount(); + return mActiveActors.begin(); } -PxU32 Sc::Scene::getMaxNbConstraintDataBlocksUsed() const +void Sc::Scene::setActiveActors(PxActor** actors, PxU32 nbActors) { - return mLLContext->getNpMemBlockPool().getPeakConstraintBlockCount(); + mActiveActors.forceSize_Unsafe(0); + mActiveActors.resize(nbActors); + PxMemCopy(mActiveActors.begin(), actors, sizeof(PxActor*) * nbActors); } -void Sc::Scene::setScratchBlock(void* addr, PxU32 size) +PxActor** Sc::Scene::getFrozenActors(PxU32& nbActorsOut) { - return mLLContext->setScratchBlock(addr, size); -} + nbActorsOut = mFrozenActors.size(); -void Sc::Scene::checkConstraintBreakage() -{ - PX_PROFILE_ZONE("Sim.checkConstraintBreakage", getContextId()); + if(!nbActorsOut) + return NULL; - PxU32 count = mActiveBreakableConstraints.size(); - ConstraintSim* const* constraints = mActiveBreakableConstraints.getEntries(); - while(count) - { - count--; - constraints[count]->checkMaxForceExceeded(); // start from the back because broken constraints get removed from the list - } + return mFrozenActors.begin(); } -void Sc::Scene::getStats(PxSimulationStatistics& s) const +void Sc::Scene::reserveTriggerReportBufferSpace(const PxU32 pairCount, PxTriggerPair*& triggerPairBuffer, TriggerPairExtraData*& triggerPairExtraBuffer) { - mStats->readOut(s, mLLContext->getSimStats()); - s.nbStaticBodies = mNbRigidStatics; - s.nbDynamicBodies = mNbRigidDynamics; - s.nbKinematicBodies = mNbRigidKinematic; - s.nbArticulations = mArticulations.size(); - - s.nbAggregates = mAABBManager->getNbActiveAggregates(); - for(PxU32 i=0; igetDeviceMemorySize(); + const PxU32 oldSize = mTriggerBufferAPI.size(); + const PxU32 newSize = oldSize + pairCount; + const PxU32 newCapacity = PxU32(newSize * 1.5f); + mTriggerBufferAPI.reserve(newCapacity); + mTriggerBufferAPI.forceSize_Unsafe(newSize); + triggerPairBuffer = mTriggerBufferAPI.begin() + oldSize; - const PxsHeapStats& deviceHeapStats = mHeapMemoryAllocationManager->getDeviceHeapStats(); - s.gpuMemHeapBroadPhase = deviceHeapStats.stats[PxsHeapStats::eBROADPHASE]; - s.gpuMemHeapNarrowPhase = deviceHeapStats.stats[PxsHeapStats::eNARROWPHASE]; - s.gpuMemHeapSolver = deviceHeapStats.stats[PxsHeapStats::eSOLVER]; - s.gpuMemHeapArticulation = deviceHeapStats.stats[PxsHeapStats::eARTICULATION]; - s.gpuMemHeapSimulation = deviceHeapStats.stats[PxsHeapStats::eSIMULATION]; - s.gpuMemHeapSimulationArticulation = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_ARTICULATION]; - s.gpuMemHeapSimulationParticles = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_PARTICLES]; - s.gpuMemHeapSimulationSoftBody = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_SOFTBODY]; - s.gpuMemHeapSimulationFEMCloth = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_FEMCLOTH]; - s.gpuMemHeapSimulationHairSystem = deviceHeapStats.stats[PxsHeapStats::eSIMULATION_HAIRSYSTEM]; - s.gpuMemHeapParticles = deviceHeapStats.stats[PxsHeapStats::eSHARED_PARTICLES]; - s.gpuMemHeapFEMCloths = deviceHeapStats.stats[PxsHeapStats::eSHARED_FEMCLOTH]; - s.gpuMemHeapSoftBodies = deviceHeapStats.stats[PxsHeapStats::eSHARED_SOFTBODY]; - s.gpuMemHeapHairSystems = deviceHeapStats.stats[PxsHeapStats::eSHARED_HAIRSYSTEM]; - s.gpuMemHeapOther = deviceHeapStats.stats[PxsHeapStats::eOTHER]; - } - else -#endif - { - s.gpuMemHeap = 0; - s.gpuMemParticles = 0; - s.gpuMemSoftBodies = 0; - s.gpuMemFEMCloths = 0; - s.gpuMemHairSystems = 0; - s.gpuMemHeapBroadPhase = 0; - s.gpuMemHeapNarrowPhase = 0; - s.gpuMemHeapSolver = 0; - s.gpuMemHeapArticulation = 0; - s.gpuMemHeapSimulation = 0; - s.gpuMemHeapSimulationArticulation = 0; - s.gpuMemHeapSimulationParticles = 0; - s.gpuMemHeapSimulationSoftBody = 0; - s.gpuMemHeapSimulationFEMCloth = 0; - s.gpuMemHeapSimulationHairSystem = 0; - s.gpuMemHeapParticles = 0; - s.gpuMemHeapSoftBodies = 0; - s.gpuMemHeapFEMCloths = 0; - s.gpuMemHeapHairSystems = 0; - s.gpuMemHeapOther = 0; - } + PX_ASSERT(oldSize == mTriggerBufferExtraData->size()); + mTriggerBufferExtraData->reserve(newCapacity); + mTriggerBufferExtraData->forceSize_Unsafe(newSize); + triggerPairExtraBuffer = mTriggerBufferExtraData->begin() + oldSize; } -void Sc::Scene::addShapes(NpShape *const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& bodySim, PxBounds3* outBounds) +template +static void clearBodies(PxCoalescedHashSet& bodies) { - const PxNodeIndex nodeIndex = bodySim.getNodeIndex(); - - PxvNphaseImplementationContext* context = mLLContext->getNphaseImplementationContext(); - - for(PxU32 i=0;i(size_t(shapes[i])+ptrOffset); - - //PxBounds3* target = uninflatedBounds ? uninflatedBounds + i : uninflatedBounds; - //mShapeSimPool->construct(sim, sc, llBody, target); - - ShapeSim* shapeSim = mShapeSimPool->construct(bodySim, sc); - mNbGeometries[sc.getGeometryType()]++; + ActorSim* body = sleepingOrWokenBodies[i]->getSim(); - mSimulationController->addShape(&shapeSim->getLLShapeSim(), shapeSim->getElementID()); + if(sleepOrWoke) + { + PX_ASSERT(!body->readInternalFlag(ActorSim::BF_WAKEUP_NOTIFY)); + body->clearInternalFlag(ActorSim::BF_SLEEP_NOTIFY); + } + else + { + PX_ASSERT(!body->readInternalFlag(ActorSim::BF_SLEEP_NOTIFY)); + body->clearInternalFlag(ActorSim::BF_WAKEUP_NOTIFY); + } - if (outBounds) - outBounds[i] = mBoundsArray->getBounds(shapeSim->getElementID()); - - //I register the shape if its either not an articulation link or if the nodeIndex has already been - //assigned. On insertion, the articulation will not have this nodeIndex correctly assigned at this stage - if (bodySim.getActorType() != PxActorType::eARTICULATION_LINK || !nodeIndex.isStaticBody()) - context->registerShape(nodeIndex, sc.getCore(), shapeSim->getElementID(), bodySim.getPxActor()); + // A body can be in both lists depending on the sequence of events + body->clearInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST); + body->clearInternalFlag(ActorSim::BF_IS_IN_WAKEUP_LIST); } + bodies.clear(); } -void Sc::Scene::removeShapes(Sc::RigidSim& sim, PxInlineArray& shapesBuffer , PxInlineArray& removedShapes, bool wakeOnLostTouch) +void Sc::Scene::clearSleepWakeBodies() { - PxU32 nbElems = sim.getNbElements(); - Sc::ElementSim** elems = sim.getElements(); - while (nbElems--) - { - Sc::ShapeSim* s = static_cast(*elems++); - // can do two 2x the allocs in the worst case, but actors with >64 shapes are not common - shapesBuffer.pushBack(s); - removedShapes.pushBack(&s->getCore()); - } + // Clear sleep/woken marker flags + clearBodies(mSleepBodies); + clearBodies(mWokeBodies); - for(PxU32 i=0;ireadInternalFlag(ActorSim::BF_WAKEUP_NOTIFY)) + { + PX_ASSERT(!body->readInternalFlag(ActorSim::BF_SLEEP_NOTIFY)); - StaticSim* sim = mStaticSimPool->construct(*this, ro); - - mNbRigidStatics++; - addShapes(shapes, nbShapes, shapePtrOffset, *sim, uninflatedBounds); -} + // Body is in the list of woken bodies, hence, mark this list as dirty such that it gets cleaned up before + // being sent to the user + body->clearInternalFlag(ActorSim::BF_WAKEUP_NOTIFY); + mWokeBodyListValid = false; + } -void Sc::Scene::removeStatic(StaticCore& ro, PxInlineArray& removedShapes, bool wakeOnLostTouch) -{ - PX_ASSERT(ro.getActorCoreType() == PxActorType::eRIGID_STATIC); + body->raiseInternalFlag(ActorSim::BF_SLEEP_NOTIFY); - StaticSim* sim = ro.getSim(); - if(sim) + // Avoid multiple insertion (the user can do multiple transitions between asleep and awake) + if (!body->readInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST)) { - if(mBatchRemoveState) - { - removeShapes(*sim, mBatchRemoveState->bufferedShapes ,removedShapes, wakeOnLostTouch); - } - else - { - PxInlineArray shapesBuffer; - removeShapes(*sim, shapesBuffer ,removedShapes, wakeOnLostTouch); - } - mStaticSimPool->destroy(static_cast(ro.getSim())); - mNbRigidStatics--; + PX_ASSERT(!mSleepBodies.contains(&body->getBodyCore())); + mSleepBodies.insert(&body->getBodyCore()); + body->raiseInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST); } } -void Sc::Scene::setDynamicsDirty() +void Sc::Scene::onBodyWakeUp(BodySim* body) { - mDynamicsContext->setStateDirty(true); -} + if(!mSimulationEventCallback && !mOnSleepingStateChanged) + return; -void Sc::Scene::addBody(BodyCore& body, NpShape*const *shapes, PxU32 nbShapes, size_t shapePtrOffset, PxBounds3* outBounds, bool compound) -{ - // sim objects do all the necessary work of adding themselves to broad phase, - // activation, registering with the interaction system, etc + if (body->readInternalFlag(BodySim::BF_SLEEP_NOTIFY)) + { + PX_ASSERT(!body->readInternalFlag(BodySim::BF_WAKEUP_NOTIFY)); - BodySim* sim = mBodySimPool->construct(*this, body, compound); + // Body is in the list of sleeping bodies, hence, mark this list as dirty such it gets cleaned up before + // being sent to the user + body->clearInternalFlag(BodySim::BF_SLEEP_NOTIFY); + mSleepBodyListValid = false; + } - const bool isArticulationLink = sim->isArticulationLink(); + body->raiseInternalFlag(BodySim::BF_WAKEUP_NOTIFY); - if (sim->getLowLevelBody().mCore->mFlags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD && sim->isActive()) + // Avoid multiple insertion (the user can do multiple transitions between asleep and awake) + if (!body->readInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST)) { - if (isArticulationLink) - { - if (sim->getNodeIndex().isValid()) - mSpeculativeCDDArticulationBitMap.growAndSet(sim->getNodeIndex().index()); - } - else - mSpeculativeCCDRigidBodyBitMap.growAndSet(sim->getNodeIndex().index()); + PX_ASSERT(!mWokeBodies.contains(&body->getBodyCore())); + mWokeBodies.insert(&body->getBodyCore()); + body->raiseInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST); } - //if rigid body is articulation link, the node index will be invalid. We should add the link to the scene after we add the - //articulation for gpu - if(sim->getNodeIndex().isValid()) - mSimulationController->addDynamic(&sim->getLowLevelBody(), sim->getNodeIndex()); - if(sim->getSimStateData(true) && sim->getSimStateData(true)->isKine()) - mNbRigidKinematic++; - else - mNbRigidDynamics++; - addShapes(shapes, nbShapes, shapePtrOffset, *sim, outBounds); - - mDynamicsContext->setStateDirty(true); } -void Sc::Scene::removeBody(BodyCore& body, PxInlineArray& removedShapes, bool wakeOnLostTouch) +PX_INLINE void Sc::Scene::cleanUpSleepBodies() { - BodySim *sim = body.getSim(); - if(sim) + BodyCore* const* bodyArray = mSleepBodies.getEntries(); + PxU32 bodyCount = mSleepBodies.size(); + + IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); + + while (bodyCount--) { - if(mBatchRemoveState) - { - removeShapes(*sim, mBatchRemoveState->bufferedShapes ,removedShapes, wakeOnLostTouch); - } - else - { - PxInlineArray shapesBuffer; - removeShapes(*sim,shapesBuffer, removedShapes, wakeOnLostTouch); - } + ActorSim* actor = bodyArray[bodyCount]->getSim(); + BodySim* body = static_cast(actor); - if (!sim->isArticulationLink()) - { - //clear bit map - if (sim->getLowLevelBody().mCore->mFlags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) - sim->getScene().resetSpeculativeCCDRigidBody(sim->getNodeIndex().index()); - } - else + if (body->readInternalFlag(static_cast(ActorSim::BF_WAKEUP_NOTIFY))) { - sim->getArticulation()->removeBody(*sim); + body->clearInternalFlag(static_cast(ActorSim::BF_IS_IN_WAKEUP_LIST)); + mSleepBodies.erase(bodyArray[bodyCount]); } - if(sim->getSimStateData(true) && sim->getSimStateData(true)->isKine()) + else if (islandSim.getNode(body->getNodeIndex()).isActive()) { - body.onRemoveKinematicFromScene(); + //This body is still active in the island simulation, so the request to deactivate the actor by the application must have failed. Recover by undoing this + mSleepBodies.erase(bodyArray[bodyCount]); + actor->internalWakeUp(); - mNbRigidKinematic--; } - else - mNbRigidDynamics--; - mBodySimPool->destroy(sim); - - mDynamicsContext->setStateDirty(true); } + + mSleepBodyListValid = true; } -// PT: TODO: refactor with addShapes -void Sc::Scene::addShape_(RigidSim& owner, ShapeCore& shapeCore) +PX_INLINE void Sc::Scene::cleanUpWokenBodies() { - ShapeSim* sim = mShapeSimPool->construct(owner, shapeCore); - mNbGeometries[shapeCore.getGeometryType()]++; - - //register shape - mSimulationController->addShape(&sim->getLLShapeSim(), sim->getElementID()); - - registerShapeInNphase(&owner.getRigidCore(), shapeCore, sim->getElementID()); + cleanUpSleepOrWokenBodies(mWokeBodies, BodySim::BF_SLEEP_NOTIFY, mWokeBodyListValid); } -// PT: TODO: refactor with removeShapes -void Sc::Scene::removeShape_(ShapeSim& shape, bool wakeOnLostTouch) +PX_INLINE void Sc::Scene::cleanUpSleepOrWokenBodies(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker) { - //BodySim* body = shape.getBodySim(); - //if(body) - // body->postShapeDetach(); - - unregisterShapeFromNphase(shape.getCore(), shape.getElementID()); + // With our current logic it can happen that a body is added to the sleep as well as the woken body list in the + // same frame. + // + // Examples: + // - Kinematic is created (added to woken list) but has not target (-> deactivation -> added to sleep list) + // - Dynamic is created (added to woken list) but is forced to sleep by user (-> deactivation -> added to sleep list) + // + // This code traverses the sleep/woken body list and removes bodies which have been initially added to the given + // list but do not belong to it anymore. - mSimulationController->removeShape(shape.getElementID()); + BodyCore* const* bodyArray = bodyList.getEntries(); + PxU32 bodyCount = bodyList.size(); + while (bodyCount--) + { + BodySim* body = bodyArray[bodyCount]->getSim(); - mNbGeometries[shape.getCore().getGeometryType()]--; - shape.removeFromBroadPhase(wakeOnLostTouch); - mShapeSimPool->destroy(&shape); -} + if (body->readInternalFlag(static_cast(removeFlag))) + bodyList.erase(bodyArray[bodyCount]); + } -void Sc::Scene::registerShapeInNphase(Sc::RigidCore* rigidCore, const ShapeCore& shape, const PxU32 transformCacheID) -{ - RigidSim* sim = rigidCore->getSim(); - if(sim) - mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), shape.getCore(), transformCacheID, sim->getPxActor()); + validMarker = true; } -void Sc::Scene::unregisterShapeFromNphase(const ShapeCore& shape, const PxU32 transformCacheID) +FeatherstoneArticulation* Sc::Scene::createLLArticulation(Sc::ArticulationSim* sim) { - mLLContext->getNphaseImplementationContext()->unregisterShape(shape.getCore(), transformCacheID); + return mLLArticulationRCPool->construct(sim); } -void Sc::Scene::notifyNphaseOnUpdateShapeMaterial(const ShapeCore& shapeCore) +void Sc::Scene::destroyLLArticulation(FeatherstoneArticulation& articulation) { - mLLContext->getNphaseImplementationContext()->updateShapeMaterial(shapeCore.getCore()); + mLLArticulationRCPool->destroy(static_cast(&articulation)); } -void Sc::Scene::startBatchInsertion(BatchInsertionState&state) +PxU32 Sc::Scene::createAggregate(void* userData, PxU32 maxNumShapes, PxAggregateFilterHint filterHint) { - state.shapeSim = mShapeSimPool->allocateAndPrefetch(); - state.staticSim = mStaticSimPool->allocateAndPrefetch(); - state.bodySim = mBodySimPool->allocateAndPrefetch(); + const physx::Bp::BoundsIndex index = getElementIDPool().createID(); + mBoundsArray->initEntry(index); + mLLContext->getNphaseImplementationContext()->registerAggregate(index); +#ifdef BP_USE_AGGREGATE_GROUP_TAIL + return mAABBManager->createAggregate(index, Bp::FilterGroup::eINVALID, userData, maxNumShapes, filterHint); +#else + // PT: TODO: ideally a static compound would have a static group + const PxU32 rigidId = getRigidIDTracker().createID(); + const Bp::FilterGroup::Enum bpGroup = Bp::FilterGroup::Enum(rigidId + Bp::FilterGroup::eDYNAMICS_BASE); + return mAABBManager->createAggregate(index, bpGroup, userData, selfCollisions); +#endif } -void Sc::Scene::addShapes(NpShape*const* shapes, PxU32 nbShapes, size_t ptrOffset, RigidSim& rigidSim, ShapeSim*& prefetchedShapeSim, PxBounds3* outBounds) +void Sc::Scene::deleteAggregate(PxU32 id) { - for(PxU32 i=0;idestroyAggregate(index, bpGroup, id)) { - if(i+1allocateAndPrefetch(); - ShapeCore& sc = *PxPointerOffset(shapes[i], ptrdiff_t(ptrOffset)); - PX_PLACEMENT_NEW(prefetchedShapeSim, ShapeSim(rigidSim, sc)); - const PxU32 elementID = prefetchedShapeSim->getElementID(); - - outBounds[i] = mBoundsArray->getBounds(elementID); - - mSimulationController->addShape(&prefetchedShapeSim->getLLShapeSim(), elementID); - mLLContext->getNphaseImplementationContext()->registerShape(rigidSim.getNodeIndex(), sc.getCore(), elementID, rigidSim.getPxActor()); + getElementIDPool().releaseID(index); + } +#else + if(mAABBManager->destroyAggregate(index, bpGroup, id)) + { + getElementIDPool().releaseID(index); - prefetchedShapeSim = nextShapeSim; - mNbGeometries[sc.getGeometryType()]++; - } + // PT: this is clumsy.... + const PxU32 rigidId = PxU32(bpGroup) - Bp::FilterGroup::eDYNAMICS_BASE; + getRigidIDTracker().releaseID(rigidId); + } +#endif } -void Sc::Scene::addStatic(PxActor* actor, BatchInsertionState& s, PxBounds3* outBounds) +void Sc::Scene::shiftOrigin(const PxVec3& shift) { - // static core has been prefetched by caller - Sc::StaticSim* sim = s.staticSim; // static core has been prefetched by the caller + // adjust low level context + mLLContext->shiftOrigin(shift); - const Cm::PtrTable* shapeTable = PxPointerOffset(actor, s.staticShapeTableOffset); - void*const* shapes = shapeTable->getPtrs(); + // adjust bounds array + mBoundsArray->shiftOrigin(shift); - mStaticSimPool->construct(sim, *this, *PxPointerOffset(actor, s.staticActorOffset)); - s.staticSim = mStaticSimPool->allocateAndPrefetch(); + // adjust broadphase + mAABBManager->shiftOrigin(shift); - addShapes(reinterpret_cast(shapes), shapeTable->getCount(), size_t(s.shapeOffset), *sim, s.shapeSim, outBounds); - mNbRigidStatics++; + // adjust constraints + ConstraintCore*const * constraints = mConstraints.getEntries(); + for(PxU32 i=0, size = mConstraints.size(); i < size; i++) + constraints[i]->getPxConnector()->onOriginShift(shift); } -void Sc::Scene::addBody(PxActor* actor, BatchInsertionState& s, PxBounds3* outBounds, bool compound) +/////////////////////////////////////////////////////////////////////////////// + +// PT: onActivate() functions should be called when an interaction is activated or created, and return true if activation +// should proceed else return false (for example: joint interaction between two kinematics should not get activated) +bool Sc::activateInteraction(Sc::Interaction* interaction, void* data) { - Sc::BodySim* sim = s.bodySim; // body core has been prefetched by the caller + switch(interaction->getType()) + { + case InteractionType::eOVERLAP: + return static_cast(interaction)->onActivate(data); - const Cm::PtrTable* shapeTable = PxPointerOffset(actor, s.dynamicShapeTableOffset); - void*const* shapes = shapeTable->getPtrs(); + case InteractionType::eTRIGGER: + return static_cast(interaction)->onActivate(data); - Sc::BodyCore* bodyCore = PxPointerOffset(actor, s.dynamicActorOffset); - mBodySimPool->construct(sim, *this, *bodyCore, compound); - s.bodySim = mBodySimPool->allocateAndPrefetch(); + case InteractionType::eMARKER: + // PT: ElementInteractionMarker::onActivate() always returns false (always inactive). + return false; - if(sim->getLowLevelBody().mCore->mFlags & PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD) - { - if(sim->isArticulationLink()) - mSpeculativeCDDArticulationBitMap.growAndSet(sim->getNodeIndex().index()); - else - mSpeculativeCCDRigidBodyBitMap.growAndSet(sim->getNodeIndex().index()); + case InteractionType::eCONSTRAINTSHADER: + return static_cast(interaction)->onActivate(data); + + case InteractionType::eARTICULATION: + return static_cast(interaction)->onActivate(data); + + case InteractionType::eTRACKED_IN_SCENE_COUNT: + case InteractionType::eINVALID: + PX_ASSERT(0); + break; } + return false; +} - if(sim->getNodeIndex().isValid()) - mSimulationController->addDynamic(&sim->getLowLevelBody(), sim->getNodeIndex()); +// PT: onDeactivate() functions should be called when an interaction is deactivated, and return true if deactivation should proceed +// else return false (for example: joint interaction between two kinematics can ignore deactivation because it always is deactivated) +/*static*/ bool deactivateInteraction(Sc::Interaction* interaction, const Sc::InteractionType::Enum type) +{ + switch(type) + { + case InteractionType::eOVERLAP: + return static_cast(interaction)->onDeactivate(); - addShapes(reinterpret_cast(shapes), shapeTable->getCount(), size_t(s.shapeOffset), *sim, s.shapeSim, outBounds); + case InteractionType::eTRIGGER: + return static_cast(interaction)->onDeactivate(); - const SimStateData* simStateData = bodyCore->getSim()->getSimStateData(true); - if(simStateData && simStateData->isKine()) - mNbRigidKinematic++; - else - mNbRigidDynamics++; + case InteractionType::eMARKER: + // PT: ElementInteractionMarker::onDeactivate() always returns true. + return true; - mDynamicsContext->setStateDirty(true); -} + case InteractionType::eCONSTRAINTSHADER: + return static_cast(interaction)->onDeactivate(); -void Sc::Scene::finishBatchInsertion(BatchInsertionState& state) -{ - // a little bit lazy - we could deal with the last one in the batch specially to avoid overallocating by one. - - mStaticSimPool->releasePreallocated(static_cast(state.staticSim)); - mBodySimPool->releasePreallocated(static_cast(state.bodySim)); - mShapeSimPool->releasePreallocated(state.shapeSim); + case InteractionType::eARTICULATION: + return static_cast(interaction)->onDeactivate(); + + case InteractionType::eTRACKED_IN_SCENE_COUNT: + case InteractionType::eINVALID: + PX_ASSERT(0); + break; + } + return false; } -// PT: TODO: why is this in Sc? -void Sc::Scene::initContactsIterator(ContactIterator& contactIterator, PxsContactManagerOutputIterator& outputs) +void Sc::activateInteractions(Sc::ActorSim& actorSim) { - outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); - Interaction** first = mInteractions[Sc::InteractionType::eOVERLAP].begin(); - contactIterator = ContactIterator(first, first + mActiveInteractionCount[Sc::InteractionType::eOVERLAP], outputs); -} + const PxU32 nbInteractions = actorSim.getActorInteractionCount(); + if(!nbInteractions) + return; -void Sc::Scene::setDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2, const PxDominanceGroupPair& dominance) -{ - struct { - void operator()(PxU32& bits, PxDominanceGroup shift, PxReal weight) - { - if(weight != PxReal(0)) - bits |= (PxU32(1) << shift); - else - bits &= ~(PxU32(1) << shift); - } - } bitsetter; + Interaction** interactions = actorSim.getActorInteractions(); + Scene& scene = actorSim.getScene(); - bitsetter(mDominanceBitMatrix[group1], group2, dominance.dominance0); - bitsetter(mDominanceBitMatrix[group2], group1, dominance.dominance1); + for(PxU32 i=0; ireadInteractionFlag(InteractionFlag::eIS_ACTIVE)) + { + const InteractionType::Enum type = interaction->getType(); + const bool isNotIGControlled = type != InteractionType::eOVERLAP && type != InteractionType::eMARKER; -PxDominanceGroupPair Sc::Scene::getDominanceGroupPair(PxDominanceGroup group1, PxDominanceGroup group2) const -{ - const PxU8 dom0 = PxU8((mDominanceBitMatrix[group1]>>group2) & 0x1 ? 1u : 0u); - const PxU8 dom1 = PxU8((mDominanceBitMatrix[group2]>>group1) & 0x1 ? 1u : 0u); - return PxDominanceGroupPair(dom0, dom1); + if(isNotIGControlled) + { + const bool proceed = activateInteraction(interaction, NULL); + if(proceed && (type < InteractionType::eTRACKED_IN_SCENE_COUNT)) + scene.notifyInteractionActivated(interaction); // PT: we can reach this line for trigger interactions + } + } + } } -void Sc::Scene::setSolverBatchSize(PxU32 solverBatchSize) +void Sc::deactivateInteractions(Sc::ActorSim& actorSim) { - mDynamicsContext->setSolverBatchSize(solverBatchSize); -} + const PxU32 nbInteractions = actorSim.getActorInteractionCount(); + if(!nbInteractions) + return; -PxU32 Sc::Scene::getSolverBatchSize() const -{ - return mDynamicsContext->getSolverBatchSize(); -} + Interaction** interactions = actorSim.getActorInteractions(); + Scene& scene = actorSim.getScene(); -void Sc::Scene::setSolverArticBatchSize(PxU32 solverBatchSize) -{ - mDynamicsContext->setSolverArticBatchSize(solverBatchSize); -} + for(PxU32 i=0; igetSolverArticBatchSize(); + if(interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) + { + const InteractionType::Enum type = interaction->getType(); + const bool isNotIGControlled = type != InteractionType::eOVERLAP && type != InteractionType::eMARKER; + if(isNotIGControlled) + { + const bool proceed = deactivateInteraction(interaction, type); + if(proceed && (type < InteractionType::eTRACKED_IN_SCENE_COUNT)) + scene.notifyInteractionDeactivated(interaction); // PT: we can reach this line for trigger interactions + } + } + } } -void Sc::Scene::setCCDMaxSeparation(PxReal separation) +Sc::ConstraintCore* Sc::Scene::findConstraintCore(const Sc::ActorSim* sim0, const Sc::ActorSim* sim1) { - mDynamicsContext->setCCDSeparationThreshold(separation); -} + const PxNodeIndex ind0 = sim0->getNodeIndex(); + const PxNodeIndex ind1 = sim1->getNodeIndex(); -PxReal Sc::Scene::getCCDMaxSeparation() const -{ - return mDynamicsContext->getCCDSeparationThreshold(); + if(ind1 < ind0) + PxSwap(sim0, sim1); + + const PxHashMap, Sc::ConstraintCore*>::Entry* entry = mConstraintMap.find(PxPair(sim0, sim1)); + return entry ? entry->second : NULL; } -void Sc::Scene::setMaxBiasCoefficient(PxReal coeff) +void Sc::Scene::updateBodySim(Sc::BodySim& bodySim) { - mDynamicsContext->setMaxBiasCoefficient(coeff); + Dy::FeatherstoneArticulation* arti = NULL; + Sc::ArticulationSim* artiSim = bodySim.getArticulation(); + if (artiSim) + arti = artiSim->getLowLevelArticulation(); + mSimulationController->updateDynamic(arti, bodySim.getNodeIndex()); } -PxReal Sc::Scene::getMaxBiasCoefficient() const +// PT: start moving PX_SUPPORT_GPU_PHYSX bits to the end of the file. Ideally/eventually they would move to a separate class or file, +// to clearly decouple the CPU and GPU parts of the scene/pipeline. +#if PX_SUPPORT_GPU_PHYSX +void Sc::Scene::gpu_releasePools() { - return mDynamicsContext->getMaxBiasCoefficient(); + PX_DELETE(mLLSoftBodyPool); + PX_DELETE(mLLFEMClothPool); + PX_DELETE(mLLParticleSystemPool); + PX_DELETE(mLLHairSystemPool); } -void Sc::Scene::setFrictionOffsetThreshold(PxReal t) +void Sc::Scene::gpu_release() { - mDynamicsContext->setFrictionOffsetThreshold(t); + PX_DELETE(mHeapMemoryAllocationManager); } -PxReal Sc::Scene::getFrictionOffsetThreshold() const +template +static void addToActiveArray(PxArray& activeArray, ActorSim& actorSim, ActorCore* core) { - return mDynamicsContext->getFrictionOffsetThreshold(); + const PxU32 activeListIndex = activeArray.size(); + actorSim.setActiveListIndex(activeListIndex); + activeArray.pushBack(static_cast(core)); } -void Sc::Scene::setFrictionCorrelationDistance(PxReal t) +void Sc::Scene::gpu_addToActiveList(ActorSim& actorSim, ActorCore* appendedActorCore) { - mDynamicsContext->setCorrelationDistance(t); + if (actorSim.isSoftBody()) + addToActiveArray(mActiveSoftBodies, actorSim, appendedActorCore); + else if (actorSim.isFEMCloth()) + addToActiveArray(mActiveFEMCloths, actorSim, appendedActorCore); + else if (actorSim.isParticleSystem()) + addToActiveArray(mActiveParticleSystems, actorSim, appendedActorCore); + else if (actorSim.isHairSystem()) + addToActiveArray(mActiveHairSystems, actorSim, appendedActorCore); } -PxReal Sc::Scene::getFrictionCorrelationDistance() const +template +static void removeFromActiveArray(PxArray& activeArray, PxU32 removedActiveIndex) { - return mDynamicsContext->getCorrelationDistance(); + const PxU32 newSize = activeArray.size() - 1; + + if(removedActiveIndex != newSize) + { + T* lastBody = activeArray[newSize]; + activeArray[removedActiveIndex] = lastBody; + lastBody->getSim()->setActiveListIndex(removedActiveIndex); + } + activeArray.forceSize_Unsafe(newSize); } -PxU32 Sc::Scene::getDefaultContactReportStreamBufferSize() const +void Sc::Scene::gpu_removeFromActiveList(ActorSim& actorSim, PxU32 removedActiveIndex) { - return mNPhaseCore->getDefaultContactReportStreamBufferSize(); + if(actorSim.isSoftBody()) + removeFromActiveArray(mActiveSoftBodies, removedActiveIndex); + else if(actorSim.isFEMCloth()) + removeFromActiveArray(mActiveFEMCloths, removedActiveIndex); + else if(actorSim.isParticleSystem()) + removeFromActiveArray(mActiveParticleSystems, removedActiveIndex); + else if(actorSim.isHairSystem()) + removeFromActiveArray(mActiveHairSystems, removedActiveIndex); } -void Sc::Scene::buildActiveActors() +void Sc::Scene::gpu_clearSleepWakeBodies() { - { - PxU32 numActiveBodies = 0; - BodyCore*const* PX_RESTRICT activeBodies; - if (!(getPublicFlags() & PxSceneFlag::eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS)) - { - numActiveBodies = getNumActiveBodies(); - activeBodies = getActiveBodiesArray(); - } - else - { - numActiveBodies = getActiveDynamicBodiesCount(); - activeBodies = getActiveDynamicBodies(); - } - - mActiveActors.clear(); + clearBodies(mSleepSoftBodies); + clearBodies(mSleepHairSystems); + clearBodies(mWokeSoftBodies); + clearBodies(mWokeHairSystems); - for (PxU32 i = 0; i < numActiveBodies; i++) - { - if (!activeBodies[i]->isFrozen()) - { - PxRigidActor* ra = static_cast(activeBodies[i]->getPxActor()); - PX_ASSERT(ra); - mActiveActors.pushBack(ra); - } - } - } + mWokeSoftBodyListValid = true; + mSleepSoftBodyListValid = true; + mWokeHairSystemListValid = true; + mSleepHairSystemListValid = true; +} -#if PX_SUPPORT_GPU_PHYSX +void Sc::Scene::gpu_buildActiveActors() +{ { PxU32 numActiveSoftBodies = getNumActiveSoftBodies(); SoftBodyCore*const* PX_RESTRICT activeSoftBodies = getActiveSoftBodiesArray(); @@ -6600,43 +3122,10 @@ void Sc::Scene::buildActiveActors() mActiveHairSystemActors.pushBack(ra); } } - -#endif } -// PT: TODO: unify buildActiveActors & buildActiveAndFrozenActors -void Sc::Scene::buildActiveAndFrozenActors() +void Sc::Scene::gpu_buildActiveAndFrozenActors() { - { - PxU32 numActiveBodies = 0; - BodyCore*const* PX_RESTRICT activeBodies; - if (!(getPublicFlags() & PxSceneFlag::eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS)) - { - numActiveBodies = getNumActiveBodies(); - activeBodies = getActiveBodiesArray(); - } - else - { - numActiveBodies = getActiveDynamicBodiesCount(); - activeBodies = getActiveDynamicBodies(); - } - - mActiveActors.clear(); - mFrozenActors.clear(); - - for (PxU32 i = 0; i < numActiveBodies; i++) - { - PxRigidActor* ra = static_cast(activeBodies[i]->getPxActor()); - PX_ASSERT(ra); - - if (!activeBodies[i]->isFrozen()) - mActiveActors.pushBack(ra); - else - mFrozenActors.pushBack(ra); - } - } - -#if PX_SUPPORT_GPU_PHYSX { PxU32 numActiveSoftBodies = getNumActiveSoftBodies(); SoftBodyCore*const* PX_RESTRICT activeSoftBodies = getActiveSoftBodiesArray(); @@ -6646,7 +3135,7 @@ void Sc::Scene::buildActiveAndFrozenActors() for (PxU32 i = 0; i < numActiveSoftBodies; i++) { PxActor* ra = activeSoftBodies[i]->getPxActor(); - mActiveActors.pushBack(ra); + mActiveSoftBodyActors.pushBack(ra); } } { @@ -6661,304 +3150,320 @@ void Sc::Scene::buildActiveAndFrozenActors() mActiveHairSystemActors.pushBack(ra); } } -#endif } -PxActor** Sc::Scene::getActiveActors(PxU32& nbActorsOut) +void Sc::Scene::gpu_setSimulationEventCallback(PxSimulationEventCallback* /*callback*/) { - nbActorsOut = mActiveActors.size(); - - if(!nbActorsOut) - return NULL; + SoftBodyCore* const* sleepingSoftBodies = mSleepSoftBodies.getEntries(); + for (PxU32 i = 0; i < mSleepSoftBodies.size(); i++) + { + sleepingSoftBodies[i]->getSim()->raiseInternalFlag(BodySim::BF_SLEEP_NOTIFY); + } - return mActiveActors.begin(); -} + //FEMClothCore* const* sleepingFEMCloths = mSleepFEMCloths.getEntries(); + //for (PxU32 i = 0; i < mSleepFEMCloths.size(); i++) + //{ + // sleepingFEMCloths[i]->getSim()->raiseInternalFlag(BodySim::BF_SLEEP_NOTIFY); + //} -void Sc::Scene::setActiveActors(PxActor** actors, PxU32 nbActors) -{ - mActiveActors.forceSize_Unsafe(0); - mActiveActors.resize(nbActors); - PxMemCopy(mActiveActors.begin(), actors, sizeof(PxActor*) * nbActors); + HairSystemCore* const* sleepingHairSystems = mSleepHairSystems.getEntries(); + for (PxU32 i = 0; i < mSleepHairSystems.size(); i++) + { + sleepingHairSystems[i]->getSim()->raiseInternalFlag(BodySim::BF_SLEEP_NOTIFY); + } } -#if PX_SUPPORT_GPU_PHYSX -PxActor** Sc::Scene::getActiveSoftBodyActors(PxU32& nbActorsOut) +PxU32 Sc::Scene::gpu_cleanUpSleepAndWokenBodies() { - nbActorsOut = mActiveSoftBodyActors.size(); + if (!mSleepSoftBodyListValid) + cleanUpSleepSoftBodies(); - if (!nbActorsOut) - return NULL; + if (!mWokeBodyListValid) + cleanUpWokenSoftBodies(); - return mActiveSoftBodyActors.begin(); -} + if (!mSleepHairSystemListValid) + cleanUpSleepHairSystems(); -void Sc::Scene::setActiveSoftBodyActors(PxActor** actors, PxU32 nbActors) -{ - mActiveSoftBodyActors.forceSize_Unsafe(0); - mActiveSoftBodyActors.resize(nbActors); - PxMemCopy(mActiveSoftBodyActors.begin(), actors, sizeof(PxActor*) * nbActors); -} + if (!mWokeHairSystemListValid) // TODO(jcarius) should this be mWokeBodyListValid? + cleanUpWokenHairSystems(); -//PxActor** Sc::Scene::getActiveFEMClothActors(PxU32& nbActorsOut) -//{ -// nbActorsOut = mActiveFEMClothActors.size(); -// -// if (!nbActorsOut) -// return NULL; -// -// return mActiveFEMClothActors.begin(); -//} -// -//void Sc::Scene::setActiveFEMClothActors(PxActor** actors, PxU32 nbActors) -//{ -// mActiveFEMClothActors.forceSize_Unsafe(0); -// mActiveFEMClothActors.resize(nbActors); -// PxMemCopy(mActiveFEMClothActors.begin(), actors, sizeof(PxActor*) * nbActors); -//} -#endif + const PxU32 nbHairSystemSleep = mSleepHairSystems.size(); + const PxU32 nbHairSystemWoken = mWokeHairSystems.size(); + const PxU32 nbSoftBodySleep = mSleepSoftBodies.size(); + const PxU32 nbSoftBodyWoken = mWokeSoftBodies.size(); + return PxMax(PxMax(nbSoftBodyWoken, nbHairSystemWoken), PxMax(nbSoftBodySleep, nbHairSystemSleep)); +} -PxActor** Sc::Scene::getFrozenActors(PxU32& nbActorsOut) +void Sc::Scene::gpu_fireOnSleepCallback(PxActor** actors) { - nbActorsOut = mFrozenActors.size(); - - if(!nbActorsOut) - return NULL; + //ML: need to create and API for the onSleep for softbody + const PxU32 nbSoftBodySleep = mSleepSoftBodies.size(); + if (nbSoftBodySleep) + { + PxU32 destSlot = 0; + SoftBodyCore* const* sleepingSoftBodies = mSleepSoftBodies.getEntries(); + for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) + actors[destSlot++] = body->getPxActor(); + if (mOnSleepingStateChanged) + mOnSleepingStateChanged(*static_cast(body->getPxActor()), true); + } - return mFrozenActors.begin(); -} + if (destSlot && mSimulationEventCallback) + mSimulationEventCallback->onSleep(actors, destSlot); + } -void Sc::Scene::reserveTriggerReportBufferSpace(const PxU32 pairCount, PxTriggerPair*& triggerPairBuffer, TriggerPairExtraData*& triggerPairExtraBuffer) -{ - const PxU32 oldSize = mTriggerBufferAPI.size(); - const PxU32 newSize = oldSize + pairCount; - const PxU32 newCapacity = PxU32(newSize * 1.5f); - mTriggerBufferAPI.reserve(newCapacity); - mTriggerBufferAPI.forceSize_Unsafe(newSize); - triggerPairBuffer = mTriggerBufferAPI.begin() + oldSize; + const PxU32 nbHairSystemSleep = mSleepHairSystems.size(); + if (nbHairSystemSleep) + { + PxU32 destSlot = 0; + HairSystemCore* const* sleepingHairSystems = mSleepHairSystems.getEntries(); + for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) + actors[destSlot++] = body->getPxActor(); + if (mOnSleepingStateChanged) + mOnSleepingStateChanged(*static_cast(body->getPxActor()), true); + } - PX_ASSERT(oldSize == mTriggerBufferExtraData->size()); - mTriggerBufferExtraData->reserve(newCapacity); - mTriggerBufferExtraData->forceSize_Unsafe(newSize); - triggerPairExtraBuffer = mTriggerBufferExtraData->begin() + oldSize; + if (destSlot && mSimulationEventCallback) + mSimulationEventCallback->onSleep(actors, destSlot); + } } -void Sc::Scene::clearSleepWakeBodies(void) +void Sc::Scene::gpu_fireOnWakeCallback(PxActor** actors) { - // PT: TODO: refactor/templatize all that stuff - - // Clear sleep/woken marker flags - BodyCore* const* sleepingBodies = mSleepBodies.getEntries(); - for(PxU32 i=0; i < mSleepBodies.size(); i++) + //ML: need to create an API for woken soft body + const PxU32 nbSoftBodyWoken = mWokeSoftBodies.size(); + if (nbSoftBodyWoken) { - ActorSim* body = sleepingBodies[i]->getSim(); - - PX_ASSERT(!body->readInternalFlag(ActorSim::BF_WAKEUP_NOTIFY)); - body->clearInternalFlag(ActorSim::BF_SLEEP_NOTIFY); + PxU32 destSlot = 0; + SoftBodyCore* const* wokenSoftBodies = mWokeSoftBodies.getEntries(); + for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) + actors[destSlot++] = body->getPxActor(); + if (mOnSleepingStateChanged) + mOnSleepingStateChanged(*static_cast(body->getPxActor()), false); + } - // A body can be in both lists depending on the sequence of events - body->clearInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST); - body->clearInternalFlag(ActorSim::BF_IS_IN_WAKEUP_LIST); + if (destSlot && mSimulationEventCallback) + mSimulationEventCallback->onWake(actors, destSlot); } -#if PX_SUPPORT_GPU_PHYSX - SoftBodyCore* const* sleepingSoftBodies = mSleepSoftBodies.getEntries(); - for (PxU32 i = 0; i < mSleepSoftBodies.size(); i++) + const PxU32 nbHairSystemWoken = mWokeHairSystems.size(); + if (nbHairSystemWoken) { - ActorSim* body = sleepingSoftBodies[i]->getSim(); - - PX_ASSERT(!body->readInternalFlag(ActorSim::BF_WAKEUP_NOTIFY)); - body->clearInternalFlag(ActorSim::BF_SLEEP_NOTIFY); + PxU32 destSlot = 0; + HairSystemCore* const* wokenHairSystems = mWokeHairSystems.getEntries(); + for (PxU32 i = 0; igetActorFlags() & PxActorFlag::eSEND_SLEEP_NOTIFIES) + actors[destSlot++] = body->getPxActor(); + if (mOnSleepingStateChanged) + mOnSleepingStateChanged(*static_cast(body->getPxActor()), false); + } - // A body can be in both lists depending on the sequence of events - body->clearInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST); - body->clearInternalFlag(ActorSim::BF_IS_IN_WAKEUP_LIST); + if (destSlot && mSimulationEventCallback) + mSimulationEventCallback->onWake(actors, destSlot); } +} - HairSystemCore* const* sleepingHairSystems = mSleepHairSystems.getEntries(); - for (PxU32 i = 0; i < mSleepHairSystems.size(); i++) +void Sc::Scene::gpu_updateBounds() +{ + //update soft bodies world bound + Sc::SoftBodyCore* const* softBodies = mSoftBodies.getEntries(); + PxU32 size = mSoftBodies.size(); + if (mUseGpuBp) { - ActorSim* body = sleepingHairSystems[i]->getSim(); - - PX_ASSERT(!body->readInternalFlag(ActorSim::BF_WAKEUP_NOTIFY)); - body->clearInternalFlag(ActorSim::BF_SLEEP_NOTIFY); - - // A body can be in both lists depending on the sequence of events - body->clearInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST); - body->clearInternalFlag(ActorSim::BF_IS_IN_WAKEUP_LIST); + for (PxU32 i = 0; i < size; ++i) + softBodies[i]->getSim()->updateBoundsInAABBMgr(); } -#endif - - BodyCore* const* wokenBodies = mWokeBodies.getEntries(); - for(PxU32 i=0; i < mWokeBodies.size(); i++) + else { - BodySim* body = wokenBodies[i]->getSim(); - - PX_ASSERT(!body->readInternalFlag(BodySim::BF_SLEEP_NOTIFY)); - body->clearInternalFlag(BodySim::BF_WAKEUP_NOTIFY); - - // A body can be in both lists depending on the sequence of events - body->clearInternalFlag(BodySim::BF_IS_IN_SLEEP_LIST); - body->clearInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST); + for (PxU32 i = 0; i < size; ++i) + softBodies[i]->getSim()->updateBounds(); } -#if PX_SUPPORT_GPU_PHYSX - SoftBodyCore* const* wokenSoftBodies = mWokeSoftBodies.getEntries(); - for (PxU32 i = 0; i < mWokeSoftBodies.size(); i++) + // update FEM-cloth world bound + Sc::FEMClothCore* const* femCloths = mFEMCloths.getEntries(); + size = mFEMCloths.size(); + if (mUseGpuBp) + { + for (PxU32 i = 0; i < size; ++i) + femCloths[i]->getSim()->updateBoundsInAABBMgr(); + } + else { - SoftBodySim* body = wokenSoftBodies[i]->getSim(); + for (PxU32 i = 0; i < size; ++i) + femCloths[i]->getSim()->updateBounds(); + } - PX_ASSERT(!body->readInternalFlag(BodySim::BF_SLEEP_NOTIFY)); - body->clearInternalFlag(BodySim::BF_WAKEUP_NOTIFY); + //upate the actor handle of particle system in AABB manager + Sc::ParticleSystemCore* const* particleSystems = mParticleSystems.getEntries(); - // A body can be in both lists depending on the sequence of events - body->clearInternalFlag(BodySim::BF_IS_IN_SLEEP_LIST); - body->clearInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST); + size = mParticleSystems.size(); + if (mUseGpuBp) + { + for (PxU32 i = 0; i < size; ++i) + particleSystems[i]->getSim()->updateBoundsInAABBMgr(); + } + else + { + for (PxU32 i = 0; i < size; ++i) + particleSystems[i]->getSim()->updateBounds(); } - HairSystemCore* const* wokenHairSystems = mWokeHairSystems.getEntries(); - for (PxU32 i = 0; i < mWokeHairSystems.size(); i++) + //update hair system world bound + Sc::HairSystemCore* const* hairSystems = mHairSystems.getEntries(); + PxU32 nHairSystems = mHairSystems.size(); + if (mUseGpuBp) + { + for (PxU32 i = 0; i < nHairSystems; ++i) + hairSystems[i]->getSim()->updateBoundsInAABBMgr(); + } + else { - HairSystemSim* body = wokenHairSystems[i]->getSim(); + for (PxU32 i = 0; i < nHairSystems; ++i) + hairSystems[i]->getSim()->updateBounds(); + } +} - PX_ASSERT(!body->readInternalFlag(BodySim::BF_SLEEP_NOTIFY)); - body->clearInternalFlag(BodySim::BF_WAKEUP_NOTIFY); +void Sc::Scene::addSoftBody(SoftBodyCore& softBody) +{ + SoftBodySim* sim = PX_NEW(SoftBodySim)(softBody, *this); - // A body can be in both lists depending on the sequence of events - body->clearInternalFlag(BodySim::BF_IS_IN_SLEEP_LIST); - body->clearInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST); + if (sim && (sim->getLowLevelSoftBody() == NULL)) + { + PX_DELETE(sim); + return; } -#endif - - mSleepBodies.clear(); - mWokeBodies.clear(); - mWokeBodyListValid = true; - mSleepBodyListValid = true; - // PT: TODO: why aren't these inside PX_SUPPORT_GPU_PHYSX? - mSleepSoftBodies.clear(); - mWokeSoftBodies.clear(); - mWokeSoftBodyListValid = true; - mSleepSoftBodyListValid = true; + mSoftBodies.insert(&softBody); + mStats->gpuMemSizeSoftBodies += softBody.getGpuMemStat(); +} - // PT: TODO: why aren't these inside PX_SUPPORT_GPU_PHYSX? - mSleepHairSystems.clear(); - mWokeHairSystems.clear(); - mWokeHairSystemListValid = true; - mSleepHairSystemListValid = true; +void Sc::Scene::removeSoftBody(SoftBodyCore& softBody) +{ + SoftBodySim* a = softBody.getSim(); + PX_DELETE(a); + mSoftBodies.erase(&softBody); + mStats->gpuMemSizeSoftBodies -= softBody.getGpuMemStat(); } -void Sc::Scene::onBodySleep(BodySim* body) +void Sc::Scene::addFEMCloth(FEMClothCore& femCloth) { - if (!mSimulationEventCallback && !mOnSleepingStateChanged) - return; + FEMClothSim* sim = PX_NEW(FEMClothSim)(femCloth, *this); - if (body->readInternalFlag(ActorSim::BF_WAKEUP_NOTIFY)) + if (sim && (sim->getLowLevelFEMCloth() == NULL)) { - PX_ASSERT(!body->readInternalFlag(ActorSim::BF_SLEEP_NOTIFY)); - - // Body is in the list of woken bodies, hence, mark this list as dirty such that it gets cleaned up before - // being sent to the user - body->clearInternalFlag(ActorSim::BF_WAKEUP_NOTIFY); - mWokeBodyListValid = false; + PX_DELETE(sim); + return; } - body->raiseInternalFlag(ActorSim::BF_SLEEP_NOTIFY); - - // Avoid multiple insertion (the user can do multiple transitions between asleep and awake) - if (!body->readInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST)) - { - PX_ASSERT(!mSleepBodies.contains(&body->getBodyCore())); - mSleepBodies.insert(&body->getBodyCore()); - body->raiseInternalFlag(ActorSim::BF_IS_IN_SLEEP_LIST); - } + mFEMCloths.insert(&femCloth); + mStats->gpuMemSizeFEMCloths += femCloth.getGpuMemStat(); } -void Sc::Scene::onBodyWakeUp(BodySim* body) +void Sc::Scene::removeFEMCloth(FEMClothCore& femCloth) { - if(!mSimulationEventCallback && !mOnSleepingStateChanged) - return; - - if (body->readInternalFlag(BodySim::BF_SLEEP_NOTIFY)) - { - PX_ASSERT(!body->readInternalFlag(BodySim::BF_WAKEUP_NOTIFY)); + FEMClothSim* a = femCloth.getSim(); + PX_DELETE(a); + mFEMCloths.erase(&femCloth); + mStats->gpuMemSizeFEMCloths -= femCloth.getGpuMemStat(); +} - // Body is in the list of sleeping bodies, hence, mark this list as dirty such it gets cleaned up before - // being sent to the user - body->clearInternalFlag(BodySim::BF_SLEEP_NOTIFY); - mSleepBodyListValid = false; - } +void Sc::Scene::addParticleSystem(ParticleSystemCore& particleSystem) +{ + ParticleSystemSim* sim = PX_NEW(ParticleSystemSim)(particleSystem, *this); - body->raiseInternalFlag(BodySim::BF_WAKEUP_NOTIFY); + Dy::ParticleSystem* dyParticleSystem = sim->getLowLevelParticleSystem(); - // Avoid multiple insertion (the user can do multiple transitions between asleep and awake) - if (!body->readInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST)) + if (sim && (dyParticleSystem == NULL)) { - PX_ASSERT(!mWokeBodies.contains(&body->getBodyCore())); - mWokeBodies.insert(&body->getBodyCore()); - body->raiseInternalFlag(BodySim::BF_IS_IN_WAKEUP_LIST); + PX_DELETE(sim); + return; } + + mParticleSystems.insert(&particleSystem); + mStats->gpuMemSizeParticles += particleSystem.getShapeCore().getGpuMemStat(); } -PX_INLINE void Sc::Scene::cleanUpSleepBodies() +void Sc::Scene::removeParticleSystem(ParticleSystemCore& particleSystem) { - BodyCore* const* bodyArray = mSleepBodies.getEntries(); - PxU32 bodyCount = mSleepBodies.size(); + ParticleSystemSim* a = particleSystem.getSim(); + PX_DELETE(a); + mParticleSystems.erase(&particleSystem); + mStats->gpuMemSizeParticles -= particleSystem.getShapeCore().getGpuMemStat(); +} - IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); +void Sc::Scene::addHairSystem(HairSystemCore& hairSystem) +{ + HairSystemSim* sim = PX_NEW(HairSystemSim)(hairSystem, *this); - while (bodyCount--) + if (sim && (sim->getLowLevelHairSystem() == NULL)) { - ActorSim* actor = bodyArray[bodyCount]->getSim(); - BodySim* body = static_cast(actor); + PX_DELETE(sim); + return; + } - if (body->readInternalFlag(static_cast(ActorSim::BF_WAKEUP_NOTIFY))) - { - body->clearInternalFlag(static_cast(ActorSim::BF_IS_IN_WAKEUP_LIST)); - mSleepBodies.erase(bodyArray[bodyCount]); - } - else if (islandSim.getNode(body->getNodeIndex()).isActive()) - { - //This body is still active in the island simulation, so the request to deactivate the actor by the application must have failed. Recover by undoing this - mSleepBodies.erase(bodyArray[bodyCount]); - actor->internalWakeUp(); + mHairSystems.insert(&hairSystem); + mStats->gpuMemSizeHairSystems += hairSystem.getShapeCore().getGpuMemStat(); +} - } - } +void Sc::Scene::removeHairSystem(HairSystemCore& hairSystem) +{ + HairSystemSim* sim = hairSystem.getSim(); + PX_DELETE(sim); + mHairSystems.erase(&hairSystem); + mStats->gpuMemSizeHairSystems -= hairSystem.getShapeCore().getGpuMemStat(); +} - mSleepBodyListValid = true; +Dy::SoftBody* Sc::Scene::createLLSoftBody(Sc::SoftBodySim* sim) +{ + return mLLSoftBodyPool->construct(sim, sim->getCore().getCore()); } -PX_INLINE void Sc::Scene::cleanUpWokenBodies() +void Sc::Scene::destroyLLSoftBody(Dy::SoftBody& softBody) { - cleanUpSleepOrWokenBodies(mWokeBodies, BodySim::BF_SLEEP_NOTIFY, mWokeBodyListValid); + mLLSoftBodyPool->destroy(&softBody); } -PX_INLINE void Sc::Scene::cleanUpSleepOrWokenBodies(PxCoalescedHashSet& bodyList, PxU32 removeFlag, bool& validMarker) +Dy::FEMCloth* Sc::Scene::createLLFEMCloth(Sc::FEMClothSim* sim) { - // With our current logic it can happen that a body is added to the sleep as well as the woken body list in the - // same frame. - // - // Examples: - // - Kinematic is created (added to woken list) but has not target (-> deactivation -> added to sleep list) - // - Dynamic is created (added to woken list) but is forced to sleep by user (-> deactivation -> added to sleep list) - // - // This code traverses the sleep/woken body list and removes bodies which have been initially added to the given - // list but do not belong to it anymore. + return mLLFEMClothPool->construct(sim, sim->getCore().getCore()); +} - BodyCore* const* bodyArray = bodyList.getEntries(); - PxU32 bodyCount = bodyList.size(); - while (bodyCount--) - { - BodySim* body = bodyArray[bodyCount]->getSim(); +void Sc::Scene::destroyLLFEMCloth(Dy::FEMCloth& femCloth) +{ + mLLFEMClothPool->destroy(&femCloth); +} - if (body->readInternalFlag(static_cast(removeFlag))) - bodyList.erase(bodyArray[bodyCount]); - } +Dy::ParticleSystem* Sc::Scene::createLLParticleSystem(Sc::ParticleSystemSim* sim) +{ + return mLLParticleSystemPool->construct(sim->getCore().getShapeCore().getLLCore()); +} + +void Sc::Scene::destroyLLParticleSystem(Dy::ParticleSystem& particleSystem) +{ + return mLLParticleSystemPool->destroy(&particleSystem); +} + +Dy::HairSystem* Sc::Scene::createLLHairSystem(Sc::HairSystemSim* sim) +{ + return mLLHairSystemPool->construct(sim, sim->getCore().getShapeCore().getLLCore()); +} - validMarker = true; +void Sc::Scene::destroyLLHairSystem(Dy::HairSystem& hairSystem) +{ + mLLHairSystemPool->destroy(&hairSystem); } -#if PX_SUPPORT_GPU_PHYSX void Sc::Scene::cleanUpSleepHairSystems() { HairSystemCore* const* hairSystemArray = mSleepHairSystems.getEntries(); @@ -6968,7 +3473,6 @@ void Sc::Scene::cleanUpSleepHairSystems() while (bodyCount--) { - HairSystemSim* hairSystem = hairSystemArray[bodyCount]->getSim(); if (hairSystem->readInternalFlag(static_cast(ActorSim::BF_WAKEUP_NOTIFY))) @@ -7062,868 +3566,714 @@ PX_INLINE void Sc::Scene::cleanUpSleepOrWokenSoftBodies(PxCoalescedHashSetgetNpMemBlockPool().releaseContacts(); - } - } - else if(endOfScene) + if (sim) { - //We now have a double-buffered pool of mem blocks so we must - //release both pools (which actually triggers the memory used this - //frame to be released - mLLContext->getNpMemBlockPool().releaseContacts(); - mLLContext->getNpMemBlockPool().releaseContacts(); - } -} + mSimulationController->addSoftBody(sim->getLowLevelSoftBody(), sim->getNodeIndex()); -PX_INLINE void Sc::Scene::clearBrokenConstraintBuffer() -{ - mBrokenConstraints.clear(); + mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), sim->getPxActor()); + } } -void Sc::Scene::addToLostTouchList(ActorSim& body1, ActorSim& body2) +void Sc::Scene::removeSoftBodySimControl(Sc::SoftBodyCore& core) { - PX_ASSERT(!body1.isStaticRigid()); - PX_ASSERT(!body2.isStaticRigid()); - SimpleBodyPair p = { &body1, &body2, body1.getActorID(), body2.getActorID() }; - mLostTouchPairs.pushBack(p); -} + Sc::SoftBodySim* sim = core.getSim(); -FeatherstoneArticulation* Sc::Scene::createLLArticulation(Sc::ArticulationSim* sim) -{ - return mLLArticulationRCPool->construct(sim); + if (sim) + { + mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID()); + mSimulationController->releaseSoftBody(sim->getLowLevelSoftBody()); + } } -void Sc::Scene::destroyLLArticulation(FeatherstoneArticulation& articulation) +void Sc::Scene::addFEMClothSimControl(Sc::FEMClothCore& core) { - mLLArticulationRCPool->destroy(static_cast(&articulation)); -} - -#if PX_SUPPORT_GPU_PHYSX + Sc::FEMClothSim* sim = core.getSim(); -Dy::SoftBody* Sc::Scene::createLLSoftBody(Sc::SoftBodySim* sim) -{ - return mLLSoftBodyPool->construct(sim, sim->getCore().getCore()); -} + if (sim) + { + mSimulationController->addFEMCloth(sim->getLowLevelFEMCloth(), sim->getNodeIndex()); -void Sc::Scene::destroyLLSoftBody(Dy::SoftBody& softBody) -{ - mLLSoftBodyPool->destroy(&softBody); + mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), sim->getPxActor(), true); + } } -Dy::FEMCloth* Sc::Scene::createLLFEMCloth(Sc::FEMClothSim* sim) +void Sc::Scene::removeFEMClothSimControl(Sc::FEMClothCore& core) { - return mLLFEMClothPool->construct(sim, sim->getCore().getCore()); -} + Sc::FEMClothSim* sim = core.getSim(); -void Sc::Scene::destroyLLFEMCloth(Dy::FEMCloth& femCloth) -{ - mLLFEMClothPool->destroy(&femCloth); + if (sim) + { + mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), true); + mSimulationController->releaseFEMCloth(sim->getLowLevelFEMCloth()); + } } -Dy::ParticleSystem* Sc::Scene::createLLParticleSystem(Sc::ParticleSystemSim* sim) +void Sc::Scene::addParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId) { - return mLLParticleSystemPool->construct(sim->getCore().getShapeCore().getLLCore()); + mSimulationController->addParticleFilter(sim.getLowLevelSoftBody(), core->getSim()->getLowLevelParticleSystem(), + particleId, userBufferId, tetId); } -void Sc::Scene::destroyLLParticleSystem(Dy::ParticleSystem& particleSystem) +void Sc::Scene::removeParticleFilter(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId) { - return mLLParticleSystemPool->destroy(&particleSystem); + mSimulationController->removeParticleFilter(sim.getLowLevelSoftBody(), core->getSim()->getLowLevelParticleSystem(), particleId, userBufferId, tetId); } -Dy::HairSystem* Sc::Scene::createLLHairSystem(Sc::HairSystemSim* sim) +PxU32 Sc::Scene::addParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 particleId, PxU32 userBufferId, PxU32 tetId, const PxVec4& barycentric) { - return mLLHairSystemPool->construct(sim, sim->getCore().getShapeCore().getLLCore()); -} + PxNodeIndex nodeIndex = core->getSim()->getNodeIndex(); -void Sc::Scene::destroyLLHairSystem(Dy::HairSystem& hairSystem) -{ - mLLHairSystemPool->destroy(&hairSystem); -} + PxU32 handle = mSimulationController->addParticleAttachment(sim.getLowLevelSoftBody(), core->getSim()->getLowLevelParticleSystem(), + particleId, userBufferId, tetId, barycentric, sim.isActive()); -#endif //PX_SUPPORT_GPU_PHYSX + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; -PxU32 Sc::Scene::createAggregate(void* userData, PxU32 maxNumShapes, PxAggregateFilterHint filterHint) -{ - const physx::Bp::BoundsIndex index = getElementIDPool().createID(); - mBoundsArray->initEntry(index); - mLLContext->getNphaseImplementationContext()->registerAggregate(index); -#ifdef BP_USE_AGGREGATE_GROUP_TAIL - return mAABBManager->createAggregate(index, Bp::FilterGroup::eINVALID, userData, maxNumShapes, filterHint); -#else - // PT: TODO: ideally a static compound would have a static group - const PxU32 rigidId = getRigidIDTracker().createID(); - const Bp::FilterGroup::Enum bpGroup = Bp::FilterGroup::Enum(rigidId + Bp::FilterGroup::eDYNAMICS_BASE); - return mAABBManager->createAggregate(index, bpGroup, userData, selfCollisions); -#endif + if (interaction.mCount == 0) + { + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eSOFT_BODY_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); + interaction.mIndex = edgeIdx; + } + interaction.mCount++; + return handle; } -void Sc::Scene::deleteAggregate(PxU32 id) +void Sc::Scene::removeParticleAttachment(Sc::ParticleSystemCore* core, SoftBodySim& sim, PxU32 handle) { - Bp::BoundsIndex index; - Bp::FilterGroup::Enum bpGroup; -#ifdef BP_USE_AGGREGATE_GROUP_TAIL - if(mAABBManager->destroyAggregate(index, bpGroup, id)) - { - getElementIDPool().releaseID(index); - } -#else - if(mAABBManager->destroyAggregate(index, bpGroup, id)) - { - getElementIDPool().releaseID(index); + PxNodeIndex nodeIndex = core->getSim()->getNodeIndex(); + + mSimulationController->removeParticleAttachment(sim.getLowLevelSoftBody(), handle); - // PT: this is clumsy.... - const PxU32 rigidId = PxU32(bpGroup) - Bp::FilterGroup::eDYNAMICS_BASE; - getRigidIDTracker().releaseID(rigidId); + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) + { + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); } -#endif } -void Sc::Scene::shiftOrigin(const PxVec3& shift) +void Sc::Scene::addAttachment(const Sc::SoftBodySim& sbSim, const Sc::HairSystemSim& hairSim) { - // adjust low level context - mLLContext->shiftOrigin(shift); - - // adjust bounds array - mBoundsArray->shiftOrigin(shift); - - // adjust broadphase - mAABBManager->shiftOrigin(shift); + const PxPair pair(sbSim.getNodeIndex().index(), hairSim.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - // adjust constraints - ConstraintCore*const * constraints = mConstraints.getEntries(); - for(PxU32 i=0, size = mConstraints.size(); i < size; i++) - constraints[i]->getPxConnector()->onOriginShift(shift); + if (interaction.mCount == 0) + { + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sbSim.getNodeIndex(), hairSim.getNodeIndex(), NULL, IG::Edge::eHAIR_SYSTEM_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eHAIR_SYSTEM_CONTACT); + interaction.mIndex = edgeIdx; + } + interaction.mCount++; } -/////////////////////////////////////////////////////////////////////////////// - -static PX_FORCE_INLINE bool isParticleSystem(const PxActorType::Enum actorType) +void Sc::Scene::removeAttachment(const Sc::SoftBodySim& sbSim, const Sc::HairSystemSim& hairSim) { - return actorType == PxActorType::ePBD_PARTICLESYSTEM || actorType == PxActorType::eFLIP_PARTICLESYSTEM - || actorType == PxActorType::eMPM_PARTICLESYSTEM || actorType == PxActorType::eCUSTOM_PARTICLESYSTEM; -} + const PxPair pair(sbSim.getNodeIndex().index(), hairSim.getNodeIndex().index()); -void Sc::Scene::islandInsertion(PxBaseTask* /*continuation*/) -{ + if(mParticleOrSoftBodyRigidInteractionMap.find(pair)) // find returns pointer to const so we cannot use it directly { - PX_PROFILE_ZONE("Sim.processNewOverlaps.islandInsertion", getContextId()); - - const PxU32 nbShapeIdxCreated = mPreallocatedShapeInteractions.size(); - for (PxU32 a = 0; a < nbShapeIdxCreated; ++a) + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + PX_ASSERT(interaction.mCount > 0); + interaction.mCount--; + if(interaction.mCount == 0) { - size_t address = size_t(mPreallocatedShapeInteractions[a]); - if (address & 1) - { - ShapeInteraction* interaction = reinterpret_cast(address&size_t(~1)); - - PxsContactManager* contactManager = const_cast(interaction->getContactManager()); + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } + } +} - Sc::ActorSim& bs0 = interaction->getShape0().getActor(); - Sc::ActorSim& bs1 = interaction->getShape1().getActor(); +void Sc::Scene::addRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 vertId) +{ + PxNodeIndex nodeIndex; - PxActorType::Enum actorTypeLargest = PxMax(bs0.getActorType(), bs1.getActorType()); + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + } - PxNodeIndex nodeIndexB; - if (!bs1.isStaticRigid()) - nodeIndexB = bs1.getNodeIndex(); + mSimulationController->addRigidFilter(sim.getLowLevelSoftBody(), sim.getNodeIndex(), + nodeIndex, vertId); +} - IG::Edge::EdgeType type = IG::Edge::eCONTACT_MANAGER; - if(actorTypeLargest == PxActorType::eSOFTBODY) - type = IG::Edge::eSOFT_BODY_CONTACT; - else if (actorTypeLargest == PxActorType::eFEMCLOTH) - type = IG::Edge::eFEM_CLOTH_CONTACT; - else if(isParticleSystem(actorTypeLargest)) - type = IG::Edge::ePARTICLE_SYSTEM_CONTACT; - else if (actorTypeLargest == PxActorType::eHAIRSYSTEM) - type = IG::Edge::eHAIR_SYSTEM_CONTACT; +void Sc::Scene::removeRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 vertId) +{ + PxNodeIndex nodeIndex; - IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(contactManager, bs0.getNodeIndex(), nodeIndexB, interaction, type); + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + } - interaction->mEdgeIndex = edgeIdx; + mSimulationController->removeRigidFilter(sim.getLowLevelSoftBody(), nodeIndex, vertId); +} - if (contactManager) - contactManager->getWorkUnit().mEdgeIndex = edgeIdx; +PxU32 Sc::Scene::addRigidAttachment(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 vertId, const PxVec3& actorSpacePose, + PxConeLimitedConstraint* constraint) +{ + PxNodeIndex nodeIndex; + PxsRigidBody* body = NULL; - //If it is a soft body or particle overlap, treat it as a contact for now (we can hook up touch found/lost events later maybe) - if (actorTypeLargest > PxActorType::eARTICULATION_LINK) - mSimpleIslandManager->setEdgeConnected(edgeIdx, type); - } - } + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + body = &core->getSim()->getLowLevelBody(); + } - // - Wakes actors that lost touch if appropriate - //processLostTouchPairs(); + PxU32 handle = mSimulationController->addRigidAttachment(sim.getLowLevelSoftBody(), sim.getNodeIndex(), body, + nodeIndex, vertId, actorSpacePose, constraint, sim.isActive()); - if(mCCDPass == 0) - { - mSimpleIslandManager->firstPassIslandGen(); - } - } -} + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; -void Sc::Scene::registerContactManagers(PxBaseTask* /*continuation*/) -{ + if (interaction.mCount == 0) { - PxvNphaseImplementationContext* nphaseContext = mLLContext->getNphaseImplementationContext(); - nphaseContext->lock(); - PX_PROFILE_ZONE("Sim.processNewOverlaps.registerCms", getContextId()); - //nphaseContext->registerContactManagers(mPreallocatedContactManagers.begin(), mPreallocatedContactManagers.size(), mLLContext->getContactManagerPool().getMaxUsedIndex()); - const PxU32 nbCmsCreated = mPreallocatedContactManagers.size(); - for (PxU32 a = 0; a < nbCmsCreated; ++a) - { - size_t address = size_t(mPreallocatedContactManagers[a]); - if (address & 1) - { - PxsContactManager* cm = reinterpret_cast(address&size_t(~1)); - size_t address2 = size_t(mPreallocatedShapeInteractions[a]); - ShapeInteraction* interaction = reinterpret_cast(address2&size_t(~1)); - nphaseContext->registerContactManager(cm, interaction, 0, 0); - } - } - nphaseContext->unlock(); + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eSOFT_BODY_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); + interaction.mIndex = edgeIdx; } + interaction.mCount++; + return handle; } -void Sc::Scene::registerInteractions(PxBaseTask* /*continuation*/) +void Sc::Scene::removeRigidAttachment(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 handle) { + PxNodeIndex nodeIndex; + + if (core) { - PX_PROFILE_ZONE("Sim.processNewOverlaps.registerInteractions", getContextId()); - const PxU32 nbShapeIdxCreated = mPreallocatedShapeInteractions.size(); - for (PxU32 a = 0; a < nbShapeIdxCreated; ++a) - { - size_t address = size_t(mPreallocatedShapeInteractions[a]); - if (address & 1) - { - ShapeInteraction* interaction = reinterpret_cast(address&size_t(~1)); - - ActorSim& actorSim0 = interaction->getActorSim0(); - ActorSim& actorSim1 = interaction->getActorSim1(); - actorSim0.registerInteractionInActor(interaction); - actorSim1.registerInteractionInActor(interaction); - - /*Sc::BodySim* bs0 = actorSim0.isDynamicRigid() ? static_cast(&actorSim0) : NULL; - Sc::BodySim* bs1 = actorSim1.isDynamicRigid() ? static_cast(&actorSim1) : NULL;*/ + nodeIndex = core->getSim()->getNodeIndex(); + } - if (actorSim0.isDynamicRigid()) - { - Sc::BodySim* bs0 = static_cast(&actorSim0); - bs0->registerCountedInteraction(); - } + mSimulationController->removeRigidAttachment(sim.getLowLevelSoftBody(), handle); - if (actorSim1.isDynamicRigid()) - { - Sc::BodySim* bs1 = static_cast(&actorSim1); - bs1->registerCountedInteraction(); - } - } - } + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) + { + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } +} - const PxU32 nbMarkersCreated = mPreallocatedInteractionMarkers.size(); - for (PxU32 a = 0; a < nbMarkersCreated; ++a) - { - size_t address = size_t(mPreallocatedInteractionMarkers[a]); - if (address & 1) - { - ElementInteractionMarker* interaction = reinterpret_cast(address&size_t(~1)); - interaction->registerInActors(NULL); - } - } +void Sc::Scene::addTetRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 tetIdx) +{ + PxNodeIndex nodeIndex; + + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); } + + mSimulationController->addTetRigidFilter(sim.getLowLevelSoftBody(), nodeIndex, tetIdx); } -void Sc::Scene::registerSceneInteractions(PxBaseTask* /*continuation*/) +void Sc::Scene::removeTetRigidFilter(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 tetIdx) { - PX_PROFILE_ZONE("Sim.processNewOverlaps.registerInteractionsScene", getContextId()); - const PxU32 nbShapeIdxCreated = mPreallocatedShapeInteractions.size(); - for (PxU32 a = 0; a < nbShapeIdxCreated; ++a) - { - size_t address = size_t(mPreallocatedShapeInteractions[a]); - if (address & 1) - { - ShapeInteraction* interaction = reinterpret_cast(address&size_t(~1)); - registerInteraction(interaction, interaction->getContactManager() != NULL); - mNPhaseCore->registerInteraction(interaction); - - const PxsContactManager* cm = interaction->getContactManager(); - if(cm) - mLLContext->setActiveContactManager(cm, cm->getCCD()); - } - } + PxNodeIndex nodeIndex; - const PxU32 nbInteractionMarkers = mPreallocatedInteractionMarkers.size(); - for (PxU32 a = 0; a < nbInteractionMarkers; ++a) + if (core) { - size_t address = size_t(mPreallocatedInteractionMarkers[a]); - if (address & 1) - { - ElementInteractionMarker* interaction = reinterpret_cast(address&size_t(~1)); - registerInteraction(interaction, false); - mNPhaseCore->registerInteraction(interaction); - } + nodeIndex = core->getSim()->getNodeIndex(); } + mSimulationController->removeTetRigidFilter(sim.getLowLevelSoftBody(), nodeIndex, tetIdx); } -class OverlapFilterTask : public Cm::Task +PxU32 Sc::Scene::addTetRigidAttachment(Sc::BodyCore* core, Sc::SoftBodySim& sim, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, + PxConeLimitedConstraint* constraint) { -public: - static const PxU32 MaxPairs = 512; - Sc::NPhaseCore* mNPhaseCore; - const Bp::AABBOverlap* mPairs; - - PxU32 mNbToProcess; - - PxU32 mKeepMap[MaxPairs/32]; - PxU32 mCallbackMap[MaxPairs/32]; + PxNodeIndex nodeIndex; + PxsRigidBody* body = NULL; - PxFilterInfo* mFinfo; + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + body = &core->getSim()->getLowLevelBody(); + } - PxU32 mNbToKeep; - PxU32 mNbToSuppress; - PxU32 mNbToCallback; + PxU32 handle = mSimulationController->addTetRigidAttachment(sim.getLowLevelSoftBody(), body, nodeIndex, + tetIdx, barycentric, actorSpacePose, constraint, sim.isActive()); - OverlapFilterTask* mNext; + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - OverlapFilterTask(PxU64 contextID, Sc::NPhaseCore* nPhaseCore, PxFilterInfo* fInfo, const Bp::AABBOverlap* pairs, const PxU32 nbToProcess) : - Cm::Task (contextID), - mNPhaseCore (nPhaseCore), - mPairs (pairs), - mNbToProcess (nbToProcess), - mFinfo (fInfo), - mNbToKeep (0), - mNbToSuppress (0), - mNbToCallback (0), - mNext (NULL) + if (interaction.mCount == 0) { - PxMemZero(mKeepMap, sizeof(mKeepMap)); - PxMemZero(mCallbackMap, sizeof(mCallbackMap)); + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eSOFT_BODY_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); + interaction.mIndex = edgeIdx; } + interaction.mCount++; + return handle; +} - virtual void runInternal() - { - mNPhaseCore->runOverlapFilters( mNbToProcess, mPairs, mFinfo, mNbToKeep, mNbToSuppress, mNbToCallback, mKeepMap, mCallbackMap); - } +void Sc::Scene::addSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1) +{ + Sc::SoftBodySim& bSim = *core.getSim(); - virtual const char* getName() const { return "OverlapFilterTask"; } -}; + mSimulationController->addSoftBodyFilter(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIdx0, tetIdx1); +} -class OnOverlapCreatedTask : public Cm::Task +void Sc::Scene::removeSoftBodyFilter(SoftBodyCore& core, PxU32 tetIdx0, SoftBodySim& sim, PxU32 tetIdx1) { -public: - Sc::NPhaseCore* mNPhaseCore; - const Bp::AABBOverlap* mPairs; - const PxFilterInfo* mFinfo; - PxsContactManager** mContactManagers; - Sc::ShapeInteraction** mShapeInteractions; - Sc::ElementInteractionMarker** mInteractionMarkers; - PxU32 mNbToProcess; - - OnOverlapCreatedTask(PxU64 contextID, Sc::NPhaseCore* nPhaseCore, const Bp::AABBOverlap* pairs, const PxFilterInfo* fInfo, PxsContactManager** contactManagers, Sc::ShapeInteraction** shapeInteractions, Sc::ElementInteractionMarker** interactionMarkers, - PxU32 nbToProcess) : - Cm::Task (contextID), - mNPhaseCore (nPhaseCore), - mPairs (pairs), - mFinfo (fInfo), - mContactManagers (contactManagers), - mShapeInteractions (shapeInteractions), - mInteractionMarkers (interactionMarkers), - mNbToProcess (nbToProcess) - { - } - - virtual void runInternal() - { - PxsContactManager** currentCm = mContactManagers; - Sc::ShapeInteraction** currentSI = mShapeInteractions; - Sc::ElementInteractionMarker** currentEI = mInteractionMarkers; - - for(PxU32 i=0; i(pair.mUserData1); - Sc::ShapeSimBase* s1 = reinterpret_cast(pair.mUserData0); + Sc::SoftBodySim& bSim = *core.getSim(); + mSimulationController->removeSoftBodyFilter(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIdx0, tetIdx1); +} - Sc::ElementSimInteraction* interaction = mNPhaseCore->createRbElementInteraction(mFinfo[i], *s0, *s1, *currentCm, *currentSI, *currentEI, 0); - if(interaction) - { - if(interaction->getType() == Sc::InteractionType::eOVERLAP) - { - *currentSI = reinterpret_cast(size_t(*currentSI) | 1); - currentSI++; +void Sc::Scene::addSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize) +{ + Sc::SoftBodySim& bSim = *core.getSim(); - if(static_cast(interaction)->getContactManager()) - { - *currentCm = reinterpret_cast(size_t(*currentCm) | 1); - currentCm++; - } - } - else if(interaction->getType() == Sc::InteractionType::eMARKER) - { - *currentEI = reinterpret_cast(size_t(*currentEI) | 1); - currentEI++; - } - } - } - } + mSimulationController->addSoftBodyFilters(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIndices0, tetIndices1, tetIndicesSize); +} - virtual const char* getName() const { return "OnOverlapCreatedTask"; } -}; +void Sc::Scene::removeSoftBodyFilters(SoftBodyCore& core, SoftBodySim& sim, PxU32* tetIndices0, PxU32* tetIndices1, PxU32 tetIndicesSize) +{ + Sc::SoftBodySim& bSim = *core.getSim(); + mSimulationController->removeSoftBodyFilters(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIndices0, tetIndices1, tetIndicesSize); +} -void Sc::Scene::finishBroadPhase(PxBaseTask* continuation) +PxU32 Sc::Scene::addSoftBodyAttachment(SoftBodyCore& core, PxU32 tetIdx0, const PxVec4& tetBarycentric0, Sc::SoftBodySim& sim, PxU32 tetIdx1, const PxVec4& tetBarycentric1, + PxConeLimitedConstraint* constraint, PxReal constraintOffset) { - PX_UNUSED(continuation); - PX_PROFILE_ZONE("Sc::Scene::finishBroadPhase", getContextId()); + Sc::SoftBodySim& bSim = *core.getSim(); + + PxU32 handle = mSimulationController->addSoftBodyAttachment(bSim.getLowLevelSoftBody(), sim.getLowLevelSoftBody(), tetIdx0, tetIdx1, + tetBarycentric0, tetBarycentric1, constraint, constraintOffset, sim.isActive() || bSim.isActive()); - Bp::AABBManagerBase* aabbMgr = mAABBManager; + PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + if (interaction.mCount == 0) { - PX_PROFILE_ZONE("Sim.processNewOverlaps", getContextId()); + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), bSim.getNodeIndex(), NULL, IG::Edge::eSOFT_BODY_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eSOFT_BODY_CONTACT); + interaction.mIndex = edgeIdx; + } + interaction.mCount++; - { - //KS - these functions call "registerInActors", while OverlapFilterTask reads the list of interactions - //in an actor. This could lead to a race condition and a crash if they occur at the same time, so we - //serialize these operations - PX_PROFILE_ZONE("Sim.processNewOverlaps.createOverlapsNoShapeInteractions", getContextId()); - { - PxU32 createdOverlapCount; - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getCreatedOverlaps(Bp::ElementType::eTRIGGER, createdOverlapCount); + return handle; +} - mLLContext->getSimStats().mNbNewPairs += createdOverlapCount; - mNPhaseCore->onTriggerOverlapCreated(p, createdOverlapCount); - } - } +void Sc::Scene::removeSoftBodyAttachment(SoftBodyCore& core, Sc::SoftBodySim& sim, PxU32 handle) +{ + Sc::SoftBodySim& bSim = *core.getSim(); + mSimulationController->removeSoftBodyAttachment(bSim.getLowLevelSoftBody(), handle); - { - PxU32 createdOverlapCount; - const Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getCreatedOverlaps(Bp::ElementType::eSHAPE, createdOverlapCount); - { - //We allocate at least 1 element in this array to ensure that the onOverlapCreated functions don't go bang! - mPreallocatedContactManagers.reserve(1); - mPreallocatedShapeInteractions.reserve(1); - mPreallocatedInteractionMarkers.reserve(1); - - mPreallocatedContactManagers.forceSize_Unsafe(1); - mPreallocatedShapeInteractions.forceSize_Unsafe(1); - mPreallocatedInteractionMarkers.forceSize_Unsafe(1); - } + PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) + { + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } +} - mLLContext->getSimStats().mNbNewPairs += createdOverlapCount; +void Sc::Scene::addClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx) +{ + Sc::FEMClothSim& bSim = *core.getSim(); - mPreallocateContactManagers.setContinuation(continuation); - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + mSimulationController->addClothFilter(sim.getLowLevelSoftBody(), bSim.getLowLevelFEMCloth(), triIdx,tetIdx); +} - mFilterInfo.forceSize_Unsafe(0); - mFilterInfo.reserve(createdOverlapCount); - mFilterInfo.forceSize_Unsafe(createdOverlapCount); +void Sc::Scene::removeClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, Sc::SoftBodySim& sim, PxU32 tetIdx) +{ + Sc::FEMClothSim& bSim = *core.getSim(); + mSimulationController->removeClothFilter(sim.getLowLevelSoftBody(), bSim.getLowLevelFEMCloth(), triIdx, tetIdx); +} - const PxU32 nbPairsPerTask = OverlapFilterTask::MaxPairs; - mOverlapFilterTaskHead = NULL; - OverlapFilterTask* previousTask = NULL; - for(PxU32 a=0; asetContinuation(&mPreallocateContactManagers); - task->removeReference(); + PxU32 handle = mSimulationController->addClothAttachment(sim.getLowLevelSoftBody(), bSim.getLowLevelFEMCloth(), triIdx, triBarycentric, + tetIdx, tetBarycentric, constraint, constraintOffset, sim.isActive()); - if(previousTask) - previousTask->mNext = task; - else - mOverlapFilterTaskHead = task; + PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - previousTask = task; - } - } + if (interaction.mCount == 0) + { + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), bSim.getNodeIndex(), NULL, IG::Edge::eFEM_CLOTH_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); + interaction.mIndex = edgeIdx; + } + interaction.mCount++; - mPreallocateContactManagers.removeReference(); - } + return handle; } -void Sc::Scene::preallocateContactManagers(PxBaseTask* continuation) +void Sc::Scene::removeClothAttachment(Sc::FEMClothCore& core, Sc::SoftBodySim& sim, PxU32 handle) { - //Iterate over all filter tasks and work out how many pairs we need... - - PxU32 createdOverlapCount = 0; - - PxU32 totalCreatedPairs = 0; - PxU32 totalSuppressPairs = 0; - - PxU32 overlapCount; - Bp::AABBOverlap* PX_RESTRICT p = mAABBManager->getCreatedOverlaps(Bp::ElementType::eSHAPE, overlapCount); - PxFilterInfo* fInfo = mFilterInfo.begin(); + PX_UNUSED(core); + Sc::FEMClothSim& bSim = *core.getSim(); + mSimulationController->removeClothAttachment(sim.getLowLevelSoftBody(), handle); - OverlapFilterTask* task = mOverlapFilterTaskHead; - while(task) + PxPair pair(sim.getNodeIndex().index(), bSim.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) { - if(task->mNbToCallback) - { - //Iterate and process callbacks. Refilter then increment the results, setting the appropriate settings - const FilteringContext context(*this, mNPhaseCore->mFilterPairManager); - - for(PxU32 w = 0; w < (OverlapFilterTask::MaxPairs / 32); ++w) - { - for(PxU32 b = task->mCallbackMap[w]; b; b &= b - 1) - { - const PxU32 index = (w << 5) + PxLowestSetBit(b); - const Bp::AABBOverlap& pair = task->mPairs[index]; - Sc::ShapeSim* s0 = reinterpret_cast(pair.mUserData0); - Sc::ShapeSim* s1 = reinterpret_cast(pair.mUserData1); + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } +} - bool isNonRigid = s0->getActor().isNonRigid() || s1->getActor().isNonRigid(); - +void Sc::Scene::addRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 vertId) +{ + PxNodeIndex nodeIndex; - const PxFilterInfo finfo = filterRbCollisionPairSecondStage(context, *s0, *s1, s0->getActor(), s1->getActor(), INVALID_FILTER_PAIR_INDEX, true, isNonRigid); + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + } - task->mFinfo[index] = finfo; + mSimulationController->addRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, vertId); +} - if(!(finfo.filterFlags & PxFilterFlag::eKILL)) - { - if((finfo.filterFlags & PxFilterFlag::eSUPPRESS) == false) - task->mNbToKeep++; - else - task->mNbToSuppress++; - task->mKeepMap[index / 32] |= (1 << (index & 31)); - } - } - } - } +void Sc::Scene::removeRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 vertId) +{ + PxNodeIndex nodeIndex; - totalCreatedPairs += task->mNbToKeep; - totalSuppressPairs += task->mNbToSuppress; - task = task->mNext; + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); } - { - //We allocate at least 1 element in this array to ensure that the onOverlapCreated functions don't go bang! - mPreallocatedContactManagers.forceSize_Unsafe(0); - mPreallocatedShapeInteractions.forceSize_Unsafe(0); - mPreallocatedInteractionMarkers.forceSize_Unsafe(0); + mSimulationController->removeRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, vertId); +} - mPreallocatedContactManagers.reserve(totalCreatedPairs+1); - mPreallocatedShapeInteractions.reserve(totalCreatedPairs+1); - mPreallocatedInteractionMarkers.reserve(totalSuppressPairs+1); +PxU32 Sc::Scene::addRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint) +{ + PxNodeIndex nodeIndex; + PxsRigidBody* body = NULL; - mPreallocatedContactManagers.forceSize_Unsafe(totalCreatedPairs); - mPreallocatedShapeInteractions.forceSize_Unsafe(totalCreatedPairs); - mPreallocatedInteractionMarkers.forceSize_Unsafe(totalSuppressPairs); + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + body = &core->getSim()->getLowLevelBody(); } - const PxU32 nbPairsPerTask = 256; - PxsContactManager** cms = mPreallocatedContactManagers.begin(); - Sc::ShapeInteraction** shapeInter = mPreallocatedShapeInteractions.begin(); - Sc::ElementInteractionMarker** markerIter = mPreallocatedInteractionMarkers.begin(); + PxU32 handle = mSimulationController->addRigidAttachment(sim.getLowLevelFEMCloth(), sim.getNodeIndex(), body, nodeIndex, + vertId, actorSpacePose, constraint, sim.isActive()); - Cm::FlushPool& flushPool = mLLContext->getTaskPool(); + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - struct Local + if (interaction.mCount == 0) { - static void processBatch(const PxU32 createdCurrIdx, PxU32& createdStartIdx, const PxU32 suppressedCurrIdx, PxU32& suppressedStartIdx, const PxU32 batchSize, - PxsContext* const context, NPhaseCore* const core, OnOverlapCreatedTask* const createTask, PxBaseTask* const continuation_, - PxsContactManager** const cms_, Sc::ShapeInteraction** const shapeInter_, Sc::ElementInteractionMarker** const markerIter_) - { - const PxU32 nbToCreate = createdCurrIdx - createdStartIdx; - const PxU32 nbToSuppress = suppressedCurrIdx - suppressedStartIdx; - - { - context->getContactManagerPool().preallocate(nbToCreate, cms_ + createdStartIdx); - } - - { - for (PxU32 i = 0; i < nbToCreate; ++i) - shapeInter_[createdStartIdx + i] = core->mShapeInteractionPool.allocate(); - } - { - for (PxU32 i = 0; i < nbToSuppress; ++i) - markerIter_[suppressedStartIdx + i] = core->mInteractionMarkerPool.allocate(); - } - - createdStartIdx = createdCurrIdx; - suppressedStartIdx = suppressedCurrIdx; + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eFEM_CLOTH_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); + interaction.mIndex = edgeIdx; + } + interaction.mCount++; + return handle; +} - createTask->mNbToProcess = batchSize; - createTask->setContinuation(continuation_); - createTask->removeReference(); - } - }; +void Sc::Scene::removeRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 handle) +{ + PxNodeIndex nodeIndex; - // PT: TODO: why do we create the task immediately? Why not create it only when a batch is full? - OnOverlapCreatedTask* createTask = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(OnOverlapCreatedTask)), OnOverlapCreatedTask)(getContextId(), mNPhaseCore, p, fInfo, cms, shapeInter, markerIter, 0); + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + } - PxU32 batchSize = 0; - PxU32 suppressedStartIdx = 0; - PxU32 createdStartIdx = 0; - PxU32 suppressedCurrIdx = 0; - PxU32 createdCurrIdx = 0; - PxU32 currentReadIdx = 0; + mSimulationController->removeRigidAttachment(sim.getLowLevelFEMCloth(), handle); - task = mOverlapFilterTaskHead; - while(task) + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) { - if(task->mNbToKeep || task->mNbToSuppress) - { - for(PxU32 w = 0; w < (OverlapFilterTask::MaxPairs/32); ++w) - { - for(PxU32 b = task->mKeepMap[w]; b; b &= b-1) - { - const PxU32 index = (w<<5) + PxLowestSetBit(b); + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } +} - if(createdOverlapCount < (index + currentReadIdx)) - { - p[createdOverlapCount] = task->mPairs[index]; - fInfo[createdOverlapCount] = task->mFinfo[index]; - } - createdOverlapCount++; - batchSize++; - } - } +void Sc::Scene::addTriRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 triIdx) +{ + PxNodeIndex nodeIndex; - suppressedCurrIdx += task->mNbToSuppress; - createdCurrIdx += task->mNbToKeep; + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + } - if(batchSize >= nbPairsPerTask) - { - Local::processBatch(createdCurrIdx, createdStartIdx, suppressedCurrIdx, suppressedStartIdx, batchSize, mLLContext, mNPhaseCore, createTask, continuation, cms, shapeInter, markerIter); + mSimulationController->addTriRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, triIdx); +} - createTask = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(OnOverlapCreatedTask)), OnOverlapCreatedTask)(getContextId(), mNPhaseCore, p + createdOverlapCount, - fInfo + createdOverlapCount, cms + createdStartIdx, shapeInter + createdStartIdx, markerIter + suppressedStartIdx, 0); +void Sc::Scene::removeTriRigidFilter(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 triIdx) +{ + PxNodeIndex nodeIndex; - batchSize = 0; - } - } - currentReadIdx += OverlapFilterTask::MaxPairs; - task = task->mNext; + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); } - if(batchSize) - Local::processBatch(createdCurrIdx, createdStartIdx, suppressedCurrIdx, suppressedStartIdx, batchSize, mLLContext, mNPhaseCore, createTask, continuation, cms, shapeInter, markerIter); + mSimulationController->removeTriRigidFilter(sim.getLowLevelFEMCloth(), nodeIndex, triIdx); } -void Sc::Scene::finishBroadPhaseStage2(const PxU32 ccdPass) +PxU32 Sc::Scene::addTriRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 triIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint) { - PX_PROFILE_ZONE("Sc::Scene::finishBroadPhase2", getContextId()); + PxNodeIndex nodeIndex; + PxsRigidBody* body = NULL; + + if (core) + { + nodeIndex = core->getSim()->getNodeIndex(); + body = &core->getSim()->getLowLevelBody(); + } + + PxU32 handle = mSimulationController->addTriRigidAttachment(sim.getLowLevelFEMCloth(), body, nodeIndex, + triIdx, barycentric, actorSpacePose, constraint, sim.isActive()); - Bp::AABBManagerBase* aabbMgr = mAABBManager; + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - for(PxU32 i=0; igetDestroyedOverlaps(Bp::ElementType::Enum(i), destroyedOverlapCount); - mLLContext->getSimStats().mNbLostPairs += destroyedOverlapCount; + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eFEM_CLOTH_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); + interaction.mIndex = edgeIdx; } + interaction.mCount++; + return handle; +} + +void Sc::Scene::removeTriRigidAttachment(Sc::BodyCore* core, Sc::FEMClothSim& sim, PxU32 handle) +{ + PxNodeIndex nodeIndex; - //KS - we need to defer processing lost overlaps until later! - if (ccdPass) + if (core) { - PX_PROFILE_ZONE("Sim.processLostOverlaps", getContextId()); - PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + nodeIndex = core->getSim()->getNodeIndex(); + } - PxU32 destroyedOverlapCount; + mSimulationController->removeTriRigidAttachment(sim.getLowLevelFEMCloth(), handle); - { - Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eSHAPE, destroyedOverlapCount); + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) + { + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } +} - while(destroyedOverlapCount--) - { - ElementSim* volume0 = reinterpret_cast(p->mUserData0); - ElementSim* volume1 = reinterpret_cast(p->mUserData1); +void Sc::Scene::addClothFilter(FEMClothCore& core0, PxU32 triIdx0, Sc::FEMClothSim& sim1, PxU32 triIdx1) +{ + Sc::FEMClothSim& sim0 = *core0.getSim(); - //KS - this is a bit ugly. We split the "onOverlapRemoved" for shape interactions to parallelize it and that means - //that we have to call each of the individual stages of the remove here. + mSimulationController->addClothFilter(sim0.getLowLevelFEMCloth(), sim1.getLowLevelFEMCloth(), triIdx0, triIdx1); +} - //First, we have to get the interaction pointer... - Sc::ElementSimInteraction* interaction = mNPhaseCore->onOverlapRemovedStage1(volume0, volume1); - p->mPairUserData = interaction; - if(interaction) - { - if(interaction->getType() == Sc::InteractionType::eOVERLAP || interaction->getType() == Sc::InteractionType::eMARKER) - { - //If it's a standard "overlap" interaction, we have to send a lost touch report, unregister it, and destroy its manager and island gen data. - if(interaction->getType() == Sc::InteractionType::eOVERLAP) - { - Sc::ShapeInteraction* si = static_cast(interaction); - mNPhaseCore->lostTouchReports(si, PxU32(PairReleaseFlag::eWAKE_ON_LOST_TOUCH), NULL, 0, outputs); - - //We must check to see if we have a contact manager here. There is an edge case where actors could be put to - //sleep after discrete simulation, prior to CCD, causing their contactManager() to be destroyed. If their bounds - //also ceased overlapping, then this code will try to destroy the manager again. - if(si->getContactManager()) - si->destroyManager(); - si->clearIslandGenData(); - } - - unregisterInteraction(interaction); - mNPhaseCore->unregisterInteraction(interaction); - } +void Sc::Scene::removeClothFilter(FEMClothCore& core, PxU32 triIdx0, FEMClothSim& sim1, PxU32 triIdx1) +{ + Sc::FEMClothSim& sim0 = *core.getSim(); + mSimulationController->removeClothFilter(sim0.getLowLevelFEMCloth(), sim1.getLowLevelFEMCloth(), triIdx0, triIdx1); +} - //Then call "onOverlapRemoved" to actually free the interaction - mNPhaseCore->onOverlapRemoved(volume0, volume1, ccdPass, interaction, outputs); - } - p++; - } - } +PxU32 Sc::Scene::addTriClothAttachment(FEMClothCore& core, PxU32 triIdx0, const PxVec4& barycentric0, Sc::FEMClothSim& sim1, PxU32 triIdx1, const PxVec4& barycentric1) +{ + Sc::FEMClothSim& sim0 = *core.getSim(); - { - Bp::AABBOverlap* PX_RESTRICT p = aabbMgr->getDestroyedOverlaps(Bp::ElementType::eTRIGGER, destroyedOverlapCount); + PxU32 handle = mSimulationController->addTriClothAttachment(sim0.getLowLevelFEMCloth(), sim1.getLowLevelFEMCloth(), triIdx0, triIdx1, + barycentric0, barycentric1, sim1.isActive() || sim0.isActive()); - while(destroyedOverlapCount--) - { - ElementSim* volume0 = reinterpret_cast(p->mUserData0); - ElementSim* volume1 = reinterpret_cast(p->mUserData1); + //return handle; - p->mPairUserData = NULL; + PxPair pair(sim0.getNodeIndex().index(), sim1.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - //KS - this is a bit ugly. - mNPhaseCore->onOverlapRemoved(volume0, volume1, ccdPass, NULL, outputs); - p++; - } - } + if (interaction.mCount == 0) + { + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim0.getNodeIndex(), sim1.getNodeIndex(), NULL, IG::Edge::eFEM_CLOTH_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eFEM_CLOTH_CONTACT); + interaction.mIndex = edgeIdx; } + interaction.mCount++; + return handle; +} - // - Wakes actors that lost touch if appropriate - processLostTouchPairs(); +void Sc::Scene::removeTriClothAttachment(FEMClothCore& core, FEMClothSim& sim1, PxU32 handle) +{ + Sc::FEMClothSim& sim0 = *core.getSim(); + mSimulationController->removeTriClothAttachment(sim0.getLowLevelFEMCloth(), handle); - if (ccdPass) - aabbMgr->freeBuffers(); + PxPair pair(sim0.getNodeIndex().index(), sim1.getNodeIndex().index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) + { + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } } -void Sc::Scene::activateEdgesInternal(const IG::EdgeIndex* activatingEdges, const PxU32 nbActivatingEdges) +void Sc::Scene::addParticleSystemSimControl(Sc::ParticleSystemCore& core) { - const IG::IslandSim& speculativeSim = mSimpleIslandManager->getSpeculativeIslandSim(); - for (PxU32 i = 0; i < nbActivatingEdges; ++i) + Sc::ParticleSystemSim* sim = core.getSim(); + + if (sim) { - Sc::Interaction* interaction = mSimpleIslandManager->getInteraction(activatingEdges[i]); + mSimulationController->addParticleSystem(sim->getLowLevelParticleSystem(), sim->getNodeIndex(), core.getSolverType()); + + mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getCore().getShapeCore().getCore(), sim->getLowLevelParticleSystem()->getElementId(), sim->getPxActor()); + } +} - if (interaction && !interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) - { - if (speculativeSim.getEdge(activatingEdges[i]).isActive()) - { - const bool proceed = activateInteraction(interaction, NULL); +void Sc::Scene::removeParticleSystemSimControl(Sc::ParticleSystemCore& core) +{ + Sc::ParticleSystemSim* sim = core.getSim(); - if (proceed && (interaction->getType() < InteractionType::eTRACKED_IN_SCENE_COUNT)) - notifyInteractionActivated(interaction); - } - } + if (sim) + { + mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getCore().getShapeCore().getCore(), sim->getShapeSim().getElementID()); + mSimulationController->releaseParticleSystem(sim->getLowLevelParticleSystem(), core.getSolverType()); } } -void Sc::Scene::secondPassNarrowPhase(PxBaseTask* /*continuation*/) + +void Sc::Scene::addRigidAttachment(Sc::BodyCore* core, Sc::ParticleSystemSim& sim) { + PxNodeIndex nodeIndex; + + if (core) { - PX_PROFILE_ZONE("Sim.postIslandGen", getContextId()); - mSimpleIslandManager->additionalSpeculativeActivation(); - // wake interactions - { - PX_PROFILE_ZONE("ScScene.wakeInteractions", getContextId()); - const IG::IslandSim& speculativeSim = mSimpleIslandManager->getSpeculativeIslandSim(); + nodeIndex = core->getSim()->getNodeIndex(); + } + + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - //KS - only wake contact managers based on speculative state to trigger contact gen. Waking actors based on accurate state - //should activate and joints. - { - //Wake speculatively based on rigid contacts, soft contacts and particle contacts - activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eCONTACT_MANAGER), speculativeSim.getNbActivatedEdges(IG::Edge::eCONTACT_MANAGER)); - activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eSOFT_BODY_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::eSOFT_BODY_CONTACT)); - activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eFEM_CLOTH_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::eFEM_CLOTH_CONTACT)); - activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::ePARTICLE_SYSTEM_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::ePARTICLE_SYSTEM_CONTACT)); - activateEdgesInternal(speculativeSim.getActivatedEdges(IG::Edge::eHAIR_SYSTEM_CONTACT), speculativeSim.getNbActivatedEdges(IG::Edge::eHAIR_SYSTEM_CONTACT)); - } - } + if (interaction.mCount == 0) + { + IG::EdgeIndex edgeIdx = mSimpleIslandManager->addContactManager(NULL, sim.getNodeIndex(), nodeIndex, NULL, IG::Edge::ePARTICLE_SYSTEM_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::ePARTICLE_SYSTEM_CONTACT); + interaction.mIndex = edgeIdx; } - mLLContext->secondPassUpdateContactManager(mDt, &mPostNarrowPhase); // Starts update of contact managers + interaction.mCount++; } -//~BROADPHASE - -void Sc::activateInteractions(Sc::ActorSim& actorSim) +void Sc::Scene::removeRigidAttachment(Sc::BodyCore* core, Sc::ParticleSystemSim& sim) { - using namespace Sc; + PxNodeIndex nodeIndex; + if (core) + nodeIndex = core->getSim()->getNodeIndex(); - const PxU32 nbInteractions = actorSim.getActorInteractionCount(); - if(!nbInteractions) - return; + PxPair pair(sim.getNodeIndex().index(), nodeIndex.index()); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + interaction.mCount--; + if (interaction.mCount == 0) + { + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); + } +} - Interaction** interactions = actorSim.getActorInteractions(); - Scene& scene = actorSim.getScene(); +void Sc::Scene::addHairSystemSimControl(Sc::HairSystemCore& core) +{ + Sc::HairSystemSim* sim = core.getSim(); - for(PxU32 i=0; iaddHairSystem(sim->getLowLevelHairSystem(), sim->getNodeIndex()); + mLLContext->getNphaseImplementationContext()->registerShape(sim->getNodeIndex(), sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID(), sim->getPxActor()); + } +} - if(!interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) - { - const InteractionType::Enum type = interaction->getType(); - const bool isNotIGControlled = type != InteractionType::eOVERLAP && type != InteractionType::eMARKER; +void Sc::Scene::removeHairSystemSimControl(Sc::HairSystemCore& core) +{ + Sc::HairSystemSim* sim = core.getSim(); - if((isNotIGControlled)) - { - const bool proceed = activateInteraction(interaction, NULL); - if(proceed && (type < InteractionType::eTRACKED_IN_SCENE_COUNT)) - scene.notifyInteractionActivated(interaction); - } - } + if (sim) + { + mLLContext->getNphaseImplementationContext()->unregisterShape(sim->getShapeSim().getCore().getCore(), sim->getShapeSim().getElementID()); + mSimulationController->releaseHairSystem(sim->getLowLevelHairSystem()); } } -void Sc::deactivateInteractions(Sc::ActorSim& actorSim) +void Sc::Scene::addAttachment(const Sc::BodySim& bodySim, const Sc::HairSystemSim& hairSim) { - using namespace Sc; - - const PxU32 nbInteractions = actorSim.getActorInteractionCount(); - if(!nbInteractions) - return; + const PxNodeIndex nodeIndex = bodySim.getNodeIndex(); + const PxPair pair(hairSim.getNodeIndex().index(), nodeIndex.index()); - Interaction** interactions = actorSim.getActorInteractions(); - Scene& scene = actorSim.getScene(); + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; - for(PxU32 i=0; iaddContactManager(NULL, hairSim.getNodeIndex(), nodeIndex, NULL, IG::Edge::eHAIR_SYSTEM_CONTACT); + mSimpleIslandManager->setEdgeConnected(edgeIdx, IG::Edge::eHAIR_SYSTEM_CONTACT); + interaction.mIndex = edgeIdx; + } + interaction.mCount++; +} - if(interaction->readInteractionFlag(InteractionFlag::eIS_ACTIVE)) +void Sc::Scene::removeAttachment(const Sc::BodySim& bodySim, const Sc::HairSystemSim& hairSim) +{ + const PxNodeIndex nodeIndex = bodySim.getNodeIndex(); + const PxPair pair(hairSim.getNodeIndex().index(), nodeIndex.index()); + + if(mParticleOrSoftBodyRigidInteractionMap.find(pair)) // find returns pointer to const so we cannot use it directly + { + ParticleOrSoftBodyRigidInteraction& interaction = mParticleOrSoftBodyRigidInteractionMap[pair]; + PX_ASSERT(interaction.mCount > 0); + interaction.mCount--; + if(interaction.mCount == 0) { - const InteractionType::Enum type = interaction->getType(); - const bool isNotIGControlled = type != InteractionType::eOVERLAP && type != InteractionType::eMARKER; - if(isNotIGControlled) - { - const bool proceed = deactivateInteraction(interaction, type); - if(proceed && (type < InteractionType::eTRACKED_IN_SCENE_COUNT)) - scene.notifyInteractionDeactivated(interaction); - } + mSimpleIslandManager->removeConnection(interaction.mIndex); + mParticleOrSoftBodyRigidInteractionMap.erase(pair); } } } -Sc::ConstraintCore* Sc::Scene::findConstraintCore(const Sc::ActorSim* sim0, const Sc::ActorSim* sim1) +PxActor** Sc::Scene::getActiveSoftBodyActors(PxU32& nbActorsOut) { - const PxNodeIndex ind0 = sim0->getNodeIndex(); - const PxNodeIndex ind1 = sim1->getNodeIndex(); + nbActorsOut = mActiveSoftBodyActors.size(); - if(ind1 < ind0) - PxSwap(sim0, sim1); + if (!nbActorsOut) + return NULL; - const PxHashMap, Sc::ConstraintCore*>::Entry* entry = mConstraintMap.find(PxPair(sim0, sim1)); - return entry ? entry->second : NULL; + return mActiveSoftBodyActors.begin(); } -void Sc::Scene::updateBodySim(Sc::BodySim& bodySim) +void Sc::Scene::setActiveSoftBodyActors(PxActor** actors, PxU32 nbActors) { - Dy::FeatherstoneArticulation* arti = NULL; - Sc::ArticulationSim* artiSim = bodySim.getArticulation(); - if (artiSim) - arti = artiSim->getLowLevelArticulation(); - mSimulationController->updateDynamic(arti, bodySim.getNodeIndex()); + mActiveSoftBodyActors.forceSize_Unsafe(0); + mActiveSoftBodyActors.resize(nbActors); + PxMemCopy(mActiveSoftBodyActors.begin(), actors, sizeof(PxActor*) * nbActors); } + +//PxActor** Sc::Scene::getActiveFEMClothActors(PxU32& nbActorsOut) +//{ +// nbActorsOut = mActiveFEMClothActors.size(); +// +// if (!nbActorsOut) +// return NULL; +// +// return mActiveFEMClothActors.begin(); +//} +// +//void Sc::Scene::setActiveFEMClothActors(PxActor** actors, PxU32 nbActors) +//{ +// mActiveFEMClothActors.forceSize_Unsafe(0); +// mActiveFEMClothActors.resize(nbActors); +// PxMemCopy(mActiveFEMClothActors.begin(), actors, sizeof(PxActor*) * nbActors); +//} + +#endif //PX_SUPPORT_GPU_PHYSX + diff --git a/physx/source/simulationcontroller/src/ScShapeCore.cpp b/physx/source/simulationcontroller/src/ScShapeCore.cpp index ede428e41..dce6fa92b 100644 --- a/physx/source/simulationcontroller/src/ScShapeCore.cpp +++ b/physx/source/simulationcontroller/src/ScShapeCore.cpp @@ -165,7 +165,7 @@ static PxHeightFieldGeometryLL extendForLL(const PxHeightFieldGeometry& hlGeom) ShapeCore::ShapeCore(const PxGeometry& geometry, PxShapeFlags shapeFlags, const PxU16* materialIndices, PxU16 materialCount, bool isExclusive, PxShapeCoreFlag::Enum softOrClothFlags) : - mSimAndIsExclusive (NULL) + mExclusiveSim(NULL) { mCore.mShapeCoreFlags |= PxShapeCoreFlag::eOWNS_MATERIAL_IDX_MEMORY; if(isExclusive) @@ -184,8 +184,6 @@ ShapeCore::ShapeCore(const PxGeometry& geometry, PxShapeFlags shapeFlags, const mCore.mMinTorsionalPatchRadius = 0.0f; mCore.mShapeFlags = shapeFlags; - mSimAndIsExclusive = reinterpret_cast(size_t(isExclusive ? 1 : 0)); - setMaterialIndices(materialIndices, materialCount); } @@ -193,7 +191,7 @@ ShapeCore::ShapeCore(const PxGeometry& geometry, PxShapeFlags shapeFlags, const ShapeCore::ShapeCore(const PxEMPTY) : mSimulationFilterData (PxEmpty), mCore (PxEmpty), - mSimAndIsExclusive (NULL) + mExclusiveSim (NULL) { mCore.mShapeCoreFlags.clear(PxShapeCoreFlag::eOWNS_MATERIAL_IDX_MEMORY); } @@ -308,11 +306,10 @@ void ShapeCore::setContactOffset(const PxReal offset) { mCore.mContactOffset = offset; - ShapeSim* sim = getSim(); - - if (sim) + ShapeSim* exclusiveSim = getExclusiveSim(); + if (exclusiveSim) { - sim->getScene().updateContactDistance(sim->getElementID(), offset); + exclusiveSim->getScene().updateContactDistance(exclusiveSim->getElementID(), offset); } } @@ -403,4 +400,9 @@ void ShapeCore::resolveReferences(PxDeserializationContext& context) } } +PxU32 ShapeCore::getInternalShapeIndex(PxsSimulationController& simulationController) const +{ + return simulationController.getInternalShapeIndex(getCore()); +} + //~PX_SERIALIZATION diff --git a/physx/source/simulationcontroller/src/ScShapeInteraction.cpp b/physx/source/simulationcontroller/src/ScShapeInteraction.cpp index 350d19664..9a9013841 100644 --- a/physx/source/simulationcontroller/src/ScShapeInteraction.cpp +++ b/physx/source/simulationcontroller/src/ScShapeInteraction.cpp @@ -33,12 +33,6 @@ using namespace physx; -static PX_FORCE_INLINE bool isParticleSystem(const PxActorType::Enum actorType) -{ - return actorType == PxActorType::ePBD_PARTICLESYSTEM || actorType == PxActorType::eFLIP_PARTICLESYSTEM - || actorType == PxActorType::eMPM_PARTICLESYSTEM || actorType == PxActorType::eCUSTOM_PARTICLESYSTEM; -} - Sc::ShapeInteraction::ShapeInteraction(ShapeSimBase& s1, ShapeSimBase& s2, PxPairFlags pairFlags, PxsContactManager* contactManager) : ElementSimInteraction (s1, s2, InteractionType::eOVERLAP, InteractionFlag::eRB_ELEMENT|InteractionFlag::eFILTERABLE), mActorPair (NULL), @@ -99,9 +93,10 @@ Sc::ShapeInteraction::ShapeInteraction(ShapeSimBase& s1, ShapeSimBase& s2, PxPai IG::SimpleIslandManager* simpleIslandManager = scene.getSimpleIslandManager(); - PxActorType::Enum actorTypeLargest = PxMax(bs0.getActorType(), bs1.getActorType()); + const PxActorType::Enum actorTypeLargest = PxMax(bs0.getActorType(), bs1.getActorType()); IG::Edge::EdgeType type = IG::Edge::eCONTACT_MANAGER; +#if PX_SUPPORT_GPU_PHYSX if (actorTypeLargest == PxActorType::eSOFTBODY) type = IG::Edge::eSOFT_BODY_CONTACT; if (actorTypeLargest == PxActorType::eFEMCLOTH) @@ -110,12 +105,14 @@ Sc::ShapeInteraction::ShapeInteraction(ShapeSimBase& s1, ShapeSimBase& s2, PxPai type = IG::Edge::ePARTICLE_SYSTEM_CONTACT; else if (actorTypeLargest == PxActorType::eHAIRSYSTEM) type = IG::Edge::eHAIR_SYSTEM_CONTACT; - +#endif mEdgeIndex = simpleIslandManager->addContactManager(NULL, indexA, indexB, this, type); - const bool active = registerInActors(contactManager); // this will call onActivate_() on the interaction - scene.getNPhaseCore()->registerInteraction(this); - scene.registerInteraction(this, active); + { + const bool active = onActivate(contactManager); + registerInActors(); + scene.registerInteraction(this, active); + } //If it is a soft body or particle overlap, treat it as a contact for now (we can hook up touch found/lost events later maybe) if (actorTypeLargest > PxActorType::eARTICULATION_LINK) @@ -123,7 +120,7 @@ Sc::ShapeInteraction::ShapeInteraction(ShapeSimBase& s1, ShapeSimBase& s2, PxPai } else { - onActivate_(contactManager); + onActivate(contactManager); } } @@ -147,7 +144,6 @@ Sc::ShapeInteraction::~ShapeInteraction() mEdgeIndex = IG_INVALID_EDGE; scene.unregisterInteraction(this); - scene.getNPhaseCore()->unregisterInteraction(this); } // This will remove the interaction from the actors list, which will prevent @@ -168,77 +164,6 @@ void Sc::ShapeInteraction::clearIslandGenData() } } -void Sc::ShapeInteraction::visualize(PxRenderOutput& out, PxsContactManagerOutputIterator& outputs, - float scale, float param_contactForce, float param_contactNormal, float param_contactError, float param_contactPoint) -{ - if(mManager) // sleeping pairs have no contact points -> do not visualize - { - Sc::ActorSim* actorSim0 = &getShape0().getActor(); - Sc::ActorSim* actorSim1 = &getShape1().getActor(); - if(!actorSim0->isNonRigid() && !actorSim1->isNonRigid()) - { - PxU32 offset; - PxU32 nextOffset = 0; - do - { - const void* contactPatches; - const void* contactPoints; - PxU32 contactDataSize; - PxU32 contactPointCount; - PxU32 contactPatchCount; - const PxReal* impulses; - - offset = nextOffset; - nextOffset = getContactPointData(contactPatches, contactPoints, contactDataSize, contactPointCount, contactPatchCount, impulses, offset, outputs); - - const PxU32* faceIndices = reinterpret_cast(impulses + contactPointCount); - PxContactStreamIterator iter(reinterpret_cast(contactPatches), reinterpret_cast(contactPoints), faceIndices, contactPatchCount, contactPointCount); - - PxU32 i = 0; - while(iter.hasNextPatch()) - { - iter.nextPatch(); - while(iter.hasNextContact()) - { - iter.nextContact(); - - if((param_contactForce != 0.0f) && impulses) - { - out << PxU32(PxDebugColor::eARGB_RED); - out.outputSegment(iter.getContactPoint(), iter.getContactPoint() + iter.getContactNormal() * (scale * param_contactForce * impulses[i])); - } - else if(param_contactNormal != 0.0f) - { - out << PxU32(PxDebugColor::eARGB_BLUE); - out.outputSegment(iter.getContactPoint(), iter.getContactPoint() + iter.getContactNormal() * (scale * param_contactNormal)); - } - else if(param_contactError != 0.0f) - { - out << PxU32(PxDebugColor::eARGB_YELLOW); - out.outputSegment(iter.getContactPoint(), iter.getContactPoint() + iter.getContactNormal() * PxAbs(scale * param_contactError * PxMin(0.f, iter.getSeparation()))); - } - - if(param_contactPoint != 0.0f) - { - const PxReal s = scale * 0.1f; - const PxVec3& point = iter.getContactPoint(); - - //if (0) //temp debug to see identical contacts - // point.x += scale * 0.01f * (contactPointCount - i + 1); - - out << PxU32(PxDebugColor::eARGB_RED); - out.outputSegment(point + PxVec3(-s, 0, 0), point + PxVec3(s, 0, 0)); - out.outputSegment(point + PxVec3(0, -s, 0), point + PxVec3(0, s, 0)); - out.outputSegment(point + PxVec3(0, 0, -s), point + PxVec3(0, 0, s)); - } - i++; - } - } - } while (nextOffset != offset); - } - } -} - PX_FORCE_INLINE void Sc::ShapeInteraction::processReportPairOnActivate() { PX_ASSERT(isReportPair()); @@ -320,7 +245,7 @@ void Sc::ShapeInteraction::processUserNotificationSync() } void Sc::ShapeInteraction::processUserNotificationAsync(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, - const PxU32 ccdPass, const bool useCurrentTransform, PxsContactManagerOutputIterator& outputs, ContactReportAllocationManager* alloc) + PxU32 ccdPass, bool useCurrentTransform, PxsContactManagerOutputIterator& outputs, ContactReportAllocationManager* alloc) { contactEvent = (!ccdPass) ? contactEvent : (contactEvent | PxPairFlag::eNOTIFY_TOUCH_CCD); @@ -589,7 +514,7 @@ void Sc::ShapeInteraction::processUserNotificationAsync(PxU32 contactEvent, PxU1 } } -void Sc::ShapeInteraction::processUserNotification(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, const PxU32 ccdPass, const bool useCurrentTransform, PxsContactManagerOutputIterator& outputs) +void Sc::ShapeInteraction::processUserNotification(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, PxU32 ccdPass, bool useCurrentTransform, PxsContactManagerOutputIterator& outputs) { processUserNotificationSync(); processUserNotificationAsync(contactEvent, infoFlags, touchLost, ccdPass, useCurrentTransform, outputs); @@ -676,7 +601,7 @@ PxU32 Sc::ShapeInteraction::getContactPointData(const void*& contactPatches, con } // Note that LL will not send end touch events for managers that are destroyed while having contact -void Sc::ShapeInteraction::managerNewTouch(const PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs) +void Sc::ShapeInteraction::managerNewTouch(PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs) { if(readFlag(HAS_TOUCH)) return; // Do not count the touch twice (for instance when recreating a manager with touch) @@ -699,9 +624,7 @@ void Sc::ShapeInteraction::managerNewTouch(const PxU32 ccdPass, bool adjustCount { PxU16 infoFlag = 0; if(mActorPair->getTouchCount() == 1) // this code assumes that the actor pair touch count does get incremented beforehand - { infoFlag = PxContactPairFlag::eACTOR_PAIR_HAS_FIRST_TOUCH; - } processUserNotification(PxPairFlag::eNOTIFY_TOUCH_FOUND, infoFlag, false, ccdPass, true, outputs); } @@ -719,8 +642,7 @@ void Sc::ShapeInteraction::managerNewTouch(const PxU32 ccdPass, bool adjustCount } } - -bool Sc::ShapeInteraction::managerLostTouch(const PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs) +bool Sc::ShapeInteraction::managerLostTouch(PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs) { if(!readFlag(HAS_TOUCH)) return false; @@ -905,7 +827,7 @@ void Sc::ShapeInteraction::updateState(const PxU8 externalDirtyFlags) if (!islandSim.getNode(bodySim0.getNodeIndex()).isActiveOrActivating() && (bodySim1.isStaticRigid() || !islandSim.getNode(bodySim1.getNodeIndex()).isActiveOrActivating())) { - onDeactivate_(); + onDeactivate(); scene.notifyInteractionDeactivated(this); } else @@ -935,7 +857,7 @@ void Sc::ShapeInteraction::updateState(const PxU8 externalDirtyFlags) } } -bool Sc::ShapeInteraction::onActivate_(void* contactManager) +bool Sc::ShapeInteraction::onActivate(void* contactManager) { if(isReportPair()) { @@ -953,7 +875,7 @@ bool Sc::ShapeInteraction::onActivate_(void* contactManager) return false; } -bool Sc::ShapeInteraction::onDeactivate_() +bool Sc::ShapeInteraction::onDeactivate() { PX_ASSERT(!getShape0().getActor().isStaticRigid() || !getShape1().getActor().isStaticRigid()); @@ -1094,8 +1016,8 @@ void Sc::ShapeInteraction::createManager(void* contactManager) mNpUnit.mTorsionalPatchRadius = PxMax(shapeSim0.getTorsionalPatchRadius(),shapeSim1.getTorsionalPatchRadius()); mNpUnit.mMinTorsionalPatchRadius = PxMax(shapeSim0.getMinTorsionalPatchRadius(), shapeSim1.getMinTorsionalPatchRadius()); - PxReal slop0 = manager->mRigidBody0 ? manager->mRigidBody0->getCore().offsetSlop : 0.f; - PxReal slop1 = manager->mRigidBody1 ? manager->mRigidBody1->getCore().offsetSlop : 0.f; + const PxReal slop0 = manager->mRigidBody0 ? manager->mRigidBody0->getCore().offsetSlop : 0.0f; + const PxReal slop1 = manager->mRigidBody1 ? manager->mRigidBody1->getCore().offsetSlop : 0.0f; mNpUnit.mOffsetSlop = PxMax(slop0, slop1); PxU16 wuflags = 0; @@ -1112,12 +1034,13 @@ void Sc::ShapeInteraction::createManager(void* contactManager) if(type1 == PxActorType::eRIGID_DYNAMIC) wuflags |= PxcNpWorkUnitFlag::eDYNAMIC_BODY1; +#if PX_SUPPORT_GPU_PHYSX if (type0 == PxActorType::eSOFTBODY) wuflags |= PxcNpWorkUnitFlag::eSOFT_BODY; if (type1 == PxActorType::eSOFTBODY) wuflags |= PxcNpWorkUnitFlag::eSOFT_BODY; - +#endif if(!disableResponse && !contactChangeable) wuflags |= PxcNpWorkUnitFlag::eOUTPUT_CONSTRAINTS; diff --git a/physx/source/simulationcontroller/src/ScShapeInteraction.h b/physx/source/simulationcontroller/src/ScShapeInteraction.h index f64382965..495cde0df 100644 --- a/physx/source/simulationcontroller/src/ScShapeInteraction.h +++ b/physx/source/simulationcontroller/src/ScShapeInteraction.h @@ -42,6 +42,12 @@ namespace physx { +static PX_FORCE_INLINE bool isParticleSystem(const PxActorType::Enum actorType) +{ + return actorType == PxActorType::ePBD_PARTICLESYSTEM || actorType == PxActorType::eFLIP_PARTICLESYSTEM + || actorType == PxActorType::eMPM_PARTICLESYSTEM; +} + class PxsContactManagerOutputIterator; namespace Sc { @@ -89,12 +95,10 @@ namespace Sc ~ShapeInteraction(); // Submits to contact stream - void processUserNotification(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, const PxU32 ccdPass, const bool useCurrentTransform, + void processUserNotification(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, PxU32 ccdPass, bool useCurrentTransform, PxsContactManagerOutputIterator& outputs); // ccdPass is 0 for discrete collision and then 1,2,... for the CCD passes - void processUserNotificationSync(); - - void processUserNotificationAsync(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, const PxU32 ccdPass, const bool useCurrentTransform, + void processUserNotificationAsync(PxU32 contactEvent, PxU16 infoFlags, bool touchLost, PxU32 ccdPass, bool useCurrentTransform, PxsContactManagerOutputIterator& outputs, ContactReportAllocationManager* alloc = NULL); // ccdPass is 0 for discrete collision and then 1,2,... for the CCD passes void visualize( PxRenderOutput&, PxsContactManagerOutputIterator&, @@ -103,15 +107,15 @@ namespace Sc PxU32 getContactPointData(const void*& contactPatches, const void*& contactPoints, PxU32& contactDataSize, PxU32& contactPointCount, PxU32& patchCount, const PxReal*& impulses, PxU32 startOffset, PxsContactManagerOutputIterator& outputs); - bool managerLostTouch(const PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs); - void managerNewTouch(const PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs); + bool managerLostTouch(PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs); + void managerNewTouch(PxU32 ccdPass, bool adjustCounters, PxsContactManagerOutputIterator& outputs); PX_FORCE_INLINE void adjustCountersOnLostTouch(); PX_FORCE_INLINE void adjustCountersOnNewTouch(); - PX_FORCE_INLINE void sendCCDRetouch(const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs); + PX_FORCE_INLINE void sendCCDRetouch(PxU32 ccdPass, PxsContactManagerOutputIterator& outputs); void setContactReportPostSolverVelocity(ContactStreamManager& cs); - PX_FORCE_INLINE void sendLostTouchReport(bool shapeVolumeRemoved, const PxU32 ccdPass, PxsContactManagerOutputIterator& ouptuts); + PX_FORCE_INLINE void sendLostTouchReport(bool shapeVolumeRemoved, PxU32 ccdPass, PxsContactManagerOutputIterator& ouptuts); void resetManagerCachedState() const; PX_FORCE_INLINE ActorPair* getActorPair() const { return mActorPair; } @@ -133,8 +137,8 @@ namespace Sc PX_FORCE_INLINE PxIntBool hasKnownTouchState() const; - bool onActivate_(void* data); - bool onDeactivate_(); + bool onActivate(void* data); + bool onDeactivate(); void updateState(const PxU8 externalDirtyFlags); @@ -188,7 +192,7 @@ namespace Sc // PT: TODO: is there a reason for force-inlining all that stuff? -PX_FORCE_INLINE void Sc::ShapeInteraction::sendLostTouchReport(bool shapeVolumeRemoved, const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs) +PX_FORCE_INLINE void Sc::ShapeInteraction::sendLostTouchReport(bool shapeVolumeRemoved, PxU32 ccdPass, PxsContactManagerOutputIterator& outputs) { PX_ASSERT(hasTouch()); PX_ASSERT(isReportPair()); @@ -201,10 +205,8 @@ PX_FORCE_INLINE void Sc::ShapeInteraction::sendLostTouchReport(bool shapeVolumeR return; PxU16 infoFlag = 0; - if (mActorPair->getTouchCount() == 1) // this code assumes that the actor pair touch count does get decremented afterwards - { + if(mActorPair->getTouchCount() == 1) // this code assumes that the actor pair touch count does get decremented afterwards infoFlag |= PxContactPairFlag::eACTOR_PAIR_LOST_TOUCH; - } //Lost touch is processed after solver, so we should use the previous transform to update the pose for objects if user request eCONTACT_EVENT_POSE const bool useCurrentTransform = false; @@ -308,7 +310,11 @@ PX_FORCE_INLINE bool Sc::ShapeInteraction::activeManagerAllowed() const ActorSim& bodySim1 = shape1.getActor(); // the first shape always belongs to a dynamic body or soft body +#if PX_SUPPORT_GPU_PHYSX PX_ASSERT(bodySim0.isDynamicRigid() || bodySim0.isSoftBody() || bodySim0.isFEMCloth() || bodySim0.isParticleSystem() || bodySim0.isHairSystem()); +#else + PX_ASSERT(bodySim0.isDynamicRigid()); +#endif const IG::IslandSim& islandSim = getScene().getSimpleIslandManager()->getSpeculativeIslandSim(); @@ -318,7 +324,7 @@ PX_FORCE_INLINE bool Sc::ShapeInteraction::activeManagerAllowed() const (!bodySim1.isStaticRigid() && islandSim.getNode(bodySim1.getNodeIndex()).isActive())); } -PX_FORCE_INLINE void Sc::ShapeInteraction::sendCCDRetouch(const PxU32 ccdPass, PxsContactManagerOutputIterator& outputs) +PX_FORCE_INLINE void Sc::ShapeInteraction::sendCCDRetouch(PxU32 ccdPass, PxsContactManagerOutputIterator& outputs) { const PxU32 pairFlags = getPairFlags(); if (pairFlags & PxPairFlag::eNOTIFY_TOUCH_CCD) diff --git a/physx/source/simulationcontroller/src/ScShapeSim.cpp b/physx/source/simulationcontroller/src/ScShapeSim.cpp index 088f38218..8c55d9206 100644 --- a/physx/source/simulationcontroller/src/ScShapeSim.cpp +++ b/physx/source/simulationcontroller/src/ScShapeSim.cpp @@ -26,47 +26,22 @@ // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#include "ScBodySim.h" -#include "ScStaticSim.h" -#include "ScScene.h" -#include "ScElementSimInteraction.h" -#include "ScShapeInteraction.h" -#include "ScTriggerInteraction.h" -#include "ScSimStats.h" -#include "ScObjectIDTracker.h" -#include "GuHeightFieldUtil.h" -#include "GuTriangleMesh.h" -#include "GuConvexMeshData.h" -#include "GuHeightField.h" -#include "PxsContext.h" -#include "PxsTransformCache.h" -#include "CmTransformUtils.h" -#include "GuBounds.h" -#include "PxsRigidBody.h" -#include "ScSqBoundsManager.h" -#include "PxsSimulationController.h" -#include "common/PxProfileZone.h" -#include "ScArticulationSim.h" +#include "ScShapeSim.h" using namespace physx; -using namespace Gu; using namespace Sc; void resetElementID(Scene& scene, ShapeSimBase& shapeSim); -ShapeSim::ShapeSim(RigidSim& owner, ShapeCore& core) : - ShapeSimBase(owner, &core) +ShapeSim::ShapeSim(RigidSim& owner, ShapeCore& core) : ShapeSimBase(owner, &core) { - // sizeof(ShapeSim) = 40 bytes - initSubsystemsDependingOnElementID(); - - core.setSim(this); + core.setExclusiveSim(this); } ShapeSim::~ShapeSim() { - const_cast(&getCore())->clearSim(); + Sc::ShapeCore::getCore(*mLLShape.mShapeCore).setExclusiveSim(NULL); Scene& scScene = getScene(); resetElementID(scScene, *this); } diff --git a/physx/source/simulationcontroller/src/ScShapeSim.h b/physx/source/simulationcontroller/src/ScShapeSim.h index 87809a613..fb3bae6b0 100644 --- a/physx/source/simulationcontroller/src/ScShapeSim.h +++ b/physx/source/simulationcontroller/src/ScShapeSim.h @@ -29,48 +29,28 @@ #ifndef SC_SHAPE_SIM_H #define SC_SHAPE_SIM_H -#include "ScElementSim.h" -#include "ScShapeCore.h" -#include "ScRigidSim.h" -#include "PxsShapeSim.h" #include "ScShapeSimBase.h" namespace physx { - class PxsTransformCache; /** Simulation object corresponding to a shape core object. This object is created when a ShapeCore object is added to the simulation, and destroyed when it is removed */ -struct PxsRigidCore; - namespace Sc { class RigidSim; class ShapeCore; - class BodySim; class ShapeSim : public ShapeSimBase { - ShapeSim &operator=(const ShapeSim &); - public: - - // passing in a pointer for the shape to output its bounds allows us not to have to compute them twice. - // A neater way to do this would be to ask the AABB Manager for the bounds after the shape has been - // constructed, but there is currently no spec for what the AABBMgr is allowed to do with the bounds, - // hence better not to assume anything. - - ShapeSim(RigidSim&, ShapeCore& core); - ~ShapeSim(); - private: + PX_NOCOPY(ShapeSim) + public: + ShapeSim(RigidSim&, ShapeCore& core); + ~ShapeSim(); }; -#if !PX_P64_FAMILY -// PX_COMPILE_TIME_ASSERT(32==sizeof(Sc::ShapeSim)); // after removing bounds from shapes -// PX_COMPILE_TIME_ASSERT((sizeof(Sc::ShapeSim) % 16) == 0); // aligned mem bounds are better for prefetching -#endif - } // namespace Sc } diff --git a/physx/source/simulationcontroller/src/ScShapeSimBase.cpp b/physx/source/simulationcontroller/src/ScShapeSimBase.cpp index c50342282..ce7b762e9 100644 --- a/physx/source/simulationcontroller/src/ScShapeSimBase.cpp +++ b/physx/source/simulationcontroller/src/ScShapeSimBase.cpp @@ -63,10 +63,22 @@ PX_INLINE Bp::FilterGroup::Enum getBPGroup(const ShapeSimBase& shapeSim) return Bp::getFilterGroup(rbSim.getActorType() == PxActorType::eRIGID_STATIC, rbSim.getActorID(), isKinematic); } +static void setElementInteractionsDirty(Sc::ElementSim& elementSim, InteractionDirtyFlag::Enum flag, PxU8 interactionFlag) +{ + ElementSim::ElementInteractionIterator iter = elementSim.getElemInteractions(); + ElementSimInteraction* interaction = iter.getNext(); + while(interaction) + { + if(interaction->readInteractionFlag(interactionFlag)) + interaction->setDirty(flag); + + interaction = iter.getNext(); + } +} void ShapeSimBase::onFilterDataChange() { - setElementInteractionsDirty(InteractionDirtyFlag::eFILTER_STATE, InteractionFlag::eFILTERABLE); + setElementInteractionsDirty(*this, InteractionDirtyFlag::eFILTER_STATE, InteractionFlag::eFILTERABLE); } void ShapeSimBase::onResetFiltering() @@ -77,12 +89,12 @@ void ShapeSimBase::onResetFiltering() void ShapeSimBase::onMaterialChange() { - setElementInteractionsDirty(InteractionDirtyFlag::eMATERIAL, InteractionFlag::eRB_ELEMENT); + setElementInteractionsDirty(*this, InteractionDirtyFlag::eMATERIAL, InteractionFlag::eRB_ELEMENT); } void ShapeSimBase::onRestOffsetChange() { - setElementInteractionsDirty(InteractionDirtyFlag::eREST_OFFSET, InteractionFlag::eRB_ELEMENT); + setElementInteractionsDirty(*this, InteractionDirtyFlag::eREST_OFFSET, InteractionFlag::eRB_ELEMENT); } void ShapeSimBase::onContactOffsetChange() @@ -345,8 +357,8 @@ void ShapeSimBase::updateBPGroup() scene.getAABBManager()->setBPGroup(getElementID(), getBPGroup(*this)); reinsertBroadPhase(); - // internalRemoveFromBroadPhase(); - // internalAddToBroadPhase(); +// internalRemoveFromBroadPhase(); +// internalAddToBroadPhase(); } } diff --git a/physx/source/simulationcontroller/src/ScShapeSimBase.h b/physx/source/simulationcontroller/src/ScShapeSimBase.h index 564e4593e..cabade534 100644 --- a/physx/source/simulationcontroller/src/ScShapeSimBase.h +++ b/physx/source/simulationcontroller/src/ScShapeSimBase.h @@ -36,8 +36,8 @@ namespace physx { namespace Sc { - PX_FORCE_INLINE PxU32 isBroadPhase(PxShapeFlags flags) { return PxU32(flags) & PxU32(PxShapeFlag::eTRIGGER_SHAPE | PxShapeFlag::eSIMULATION_SHAPE); } + class ShapeCore; // PT: TODO: ShapeSimBase is bonkers: @@ -52,14 +52,8 @@ namespace physx class ShapeSimBase : public ElementSim { - ShapeSimBase &operator=(const ShapeSimBase &); + PX_NOCOPY(ShapeSimBase) public: - - // passing in a pointer for the shape to output its bounds allows us not to have to compute them twice. - // A neater way to do this would be to ask the AABB Manager for the bounds after the shape has been - // constructed, but there is currently no spec for what the AABBMgr is allowed to do with the bounds, - // hence better not to assume anything. - ShapeSimBase(ActorSim& owner, const ShapeCore* core) : ElementSim (owner), mSqBoundsId (PX_INVALID_U32), @@ -136,7 +130,7 @@ namespace physx PX_FORCE_INLINE void ShapeSimBase::setCore(const ShapeCore* core) { - mLLShape.mShapeCore = const_cast(&core->getCore()); + mLLShape.mShapeCore = core ? const_cast(&core->getCore()) : NULL; } PX_FORCE_INLINE const ShapeCore& ShapeSimBase::getCore() const { diff --git a/physx/source/simulationcontroller/src/ScSimulationController.cpp b/physx/source/simulationcontroller/src/ScSimulationController.cpp index 4a6219bd9..def585c03 100644 --- a/physx/source/simulationcontroller/src/ScSimulationController.cpp +++ b/physx/source/simulationcontroller/src/ScSimulationController.cpp @@ -44,21 +44,20 @@ void Sc::SimulationController::updateScBodyAndShapeSim(PxsTransformCache& /*cach mCallback->updateScBodyAndShapeSim(continuation); } +namespace +{ class UpdateArticulationAfterIntegrationTask : public Cm::Task { - IG::IslandSim& mIslandSim; - + IG::IslandSim& mIslandSim; const PxNodeIndex* const PX_RESTRICT mNodeIndices; - const PxU32 mNbArticulations; - const PxReal mDt; + const PxU32 mNbArticulations; + const PxReal mDt; PX_NOCOPY(UpdateArticulationAfterIntegrationTask) public: static const PxU32 NbArticulationsPerTask = 64; - - UpdateArticulationAfterIntegrationTask(PxU64 contextId, PxU32 nbArticulations, PxReal dt, - const PxNodeIndex* nodeIndices, IG::IslandSim& islandSim) : + UpdateArticulationAfterIntegrationTask(PxU64 contextId, PxU32 nbArticulations, PxReal dt, const PxNodeIndex* nodeIndices, IG::IslandSim& islandSim) : Cm::Task(contextId), mIslandSim(islandSim), mNodeIndices(nodeIndices), @@ -81,7 +80,7 @@ class UpdateArticulationAfterIntegrationTask : public Cm::Task virtual const char* getName() const { return "UpdateArticulationAfterIntegrationTask"; } }; - +} //KS - TODO - parallelize this bit!!!!! void Sc::SimulationController::updateArticulationAfterIntegration( @@ -90,7 +89,7 @@ void Sc::SimulationController::updateArticulationAfterIntegration( PxArray& ccdBodies, PxBaseTask* continuation, IG::IslandSim& islandSim, - const float dt + float dt ) { const PxU32 nbActiveArticulations = islandSim.getNbActiveNodes(IG::Node::eARTICULATION_TYPE); @@ -104,8 +103,8 @@ void Sc::SimulationController::updateArticulationAfterIntegration( UpdateArticulationAfterIntegrationTask* task = PX_PLACEMENT_NEW(flushPool.allocate(sizeof(UpdateArticulationAfterIntegrationTask)), UpdateArticulationAfterIntegrationTask)(islandSim.getContextId(), PxMin(UpdateArticulationAfterIntegrationTask::NbArticulationsPerTask, PxU32(nbActiveArticulations - i)), dt, activeArticulations + i, islandSim); - task->setContinuation(continuation); - task->removeReference(); + + startTask(task, continuation); } llContext->getLock().lock(); diff --git a/physx/source/simulationcontroller/src/ScSimulationController.h b/physx/source/simulationcontroller/src/ScSimulationController.h index 167c1da50..1da788a9c 100644 --- a/physx/source/simulationcontroller/src/ScSimulationController.h +++ b/physx/source/simulationcontroller/src/ScSimulationController.h @@ -33,251 +33,19 @@ namespace physx { - -class PxsHeapMemoryAllocator; - -namespace Dy -{ - class FeatherstoneArticulation; - struct ArticulationJointCore; - class ParticleSystem; - class FEMCloth; - class HairSystem; -} - namespace Sc { - class SimulationController : public PxsSimulationController { PX_NOCOPY(SimulationController) public: - SimulationController(PxsSimulationControllerCallback* callback) : PxsSimulationController(callback) - { - } - - virtual ~SimulationController() {} - virtual void addJoint(const PxU32 /*edgeIndex*/, Dy::Constraint* /*constraint*/, IG::IslandSim& /*islandSim*/, PxArray& /*jointIndices*/, - PxPinnedArray& /*managerIter*/, PxU32 /*uniqueId*/){} - virtual void removeJoint(const PxU32 /*edgeIndex*/, Dy::Constraint* /*constraint*/, PxArray& /*jointIndices*/, IG::IslandSim& /*islandSim*/){} - virtual void addShape(PxsShapeSim* /*shapeSim*/, const PxU32 /*index*/){} - virtual void reinsertShape(PxsShapeSim* /*shapeSim*/, const PxU32 /*index*/) {} - virtual void removeShape(const PxU32 /*index*/){} - virtual void addDynamic(PxsRigidBody* /*rigidBody*/, const PxNodeIndex& /*nodeIndex*/){} - virtual void addDynamics(PxsRigidBody** /*rigidBody*/, const PxU32* /*nodeIndex*/, PxU32 /*nbBodies*/) {} - virtual void addArticulation(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void releaseArticulation(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void releaseDeferredArticulationIds() {} - -#if PX_SUPPORT_GPU_PHYSX - virtual void addSoftBody(Dy::SoftBody*, const PxNodeIndex&) {} - virtual void releaseSoftBody(Dy::SoftBody*) {} - virtual void releaseDeferredSoftBodyIds() {} - virtual void activateSoftbody(Dy::SoftBody*) {} - virtual void deactivateSoftbody(Dy::SoftBody*) {} - virtual void activateSoftbodySelfCollision(Dy::SoftBody*) {} - virtual void deactivateSoftbodySelfCollision(Dy::SoftBody*) {} - virtual void setSoftBodyWakeCounter(Dy::SoftBody*) {} - - - virtual void addParticleFilter(Dy::SoftBody*, Dy::ParticleSystem* , - PxU32, PxU32, PxU32){} - virtual void removeParticleFilter(Dy::SoftBody*, - const Dy::ParticleSystem*, PxU32, PxU32, PxU32){} - - virtual PxU32 addParticleAttachment(Dy::SoftBody*, const Dy::ParticleSystem*, - PxU32, PxU32, PxU32, const PxVec4&, const bool) { return 0xFFFFFFFF; } - virtual void removeParticleAttachment(Dy::SoftBody*, PxU32){} - - virtual void addRigidFilter(Dy::SoftBody*, const PxNodeIndex&, const PxNodeIndex&, PxU32) {} - virtual void removeRigidFilter(Dy::SoftBody*, const PxNodeIndex&, PxU32){} - - - virtual PxU32 addRigidAttachment(Dy::SoftBody*, const PxNodeIndex&, - PxsRigidBody*, const PxNodeIndex&, PxU32, const PxVec3&, PxConeLimitedConstraint*, const bool) {return 0xFFFFFFFF;} - virtual void removeRigidAttachment(Dy::SoftBody*, PxU32) {} - - virtual void addTetRigidFilter(Dy::SoftBody*, - const PxNodeIndex&, PxU32) {} - virtual void removeTetRigidFilter(Dy::SoftBody* , - const PxNodeIndex&, PxU32) {} - - virtual PxU32 addTetRigidAttachment(Dy::SoftBody*, PxsRigidBody*, const PxNodeIndex&, - PxU32, const PxVec4& , const PxVec3&, PxConeLimitedConstraint*, const bool) { return 0xFFFFFFFF;} - - virtual void addSoftBodyFilter(Dy::SoftBody*, Dy::SoftBody*, PxU32, - PxU32) {} - virtual void removeSoftBodyFilter(Dy::SoftBody*, Dy::SoftBody*, PxU32, - PxU32) {} - virtual void addSoftBodyFilters(Dy::SoftBody*, Dy::SoftBody*, PxU32*, PxU32*, - PxU32) {} - virtual void removeSoftBodyFilters(Dy::SoftBody*, Dy::SoftBody*, PxU32*, PxU32*, - PxU32) {} - - virtual PxU32 addSoftBodyAttachment(Dy::SoftBody* , Dy::SoftBody* , PxU32, PxU32, - const PxVec4&, const PxVec4&, PxConeLimitedConstraint*, const bool){ return 0xFFFFFFFF;} - virtual void removeSoftBodyAttachment(Dy::SoftBody*, PxU32) {} - - virtual void addClothFilter(Dy::SoftBody*, Dy::FEMCloth*, PxU32, - PxU32) {} - virtual void removeClothFilter(Dy::SoftBody*, Dy::FEMCloth*, PxU32, - PxU32) {} - - virtual PxU32 addClothAttachment(Dy::SoftBody*, Dy::FEMCloth*, PxU32, - const PxVec4&, PxU32, const PxVec4&, PxConeLimitedConstraint* , const bool) { return 0xFFFFFFFF;} - virtual void removeClothAttachment(Dy::SoftBody*, PxU32) {} - - - virtual void addFEMCloth(Dy::FEMCloth* , const PxNodeIndex&) {} - virtual void releaseFEMCloth(Dy::FEMCloth*) {} - virtual void releaseDeferredFEMClothIds() {} - virtual void activateCloth(Dy::FEMCloth*) {} - virtual void deactivateCloth(Dy::FEMCloth*) {} - virtual void setClothWakeCounter(Dy::FEMCloth*) {} - - - virtual void addRigidFilter(Dy::FEMCloth*, - const PxNodeIndex&, PxU32){} - - virtual void removeRigidFilter(Dy::FEMCloth*, - const PxNodeIndex&, PxU32){} - - virtual PxU32 addRigidAttachment(Dy::FEMCloth* , const PxNodeIndex& , - PxsRigidBody* , const PxNodeIndex& , PxU32, const PxVec3& , PxConeLimitedConstraint*, const bool){ return 0xFFFFFFFF; } - - virtual void removeRigidAttachment(Dy::FEMCloth*, PxU32 ){} - - - virtual void addTriRigidFilter(Dy::FEMCloth*, - const PxNodeIndex&, PxU32) {} - - virtual void removeTriRigidFilter(Dy::FEMCloth*, - const PxNodeIndex&, PxU32) {} + SimulationController(PxsSimulationControllerCallback* callback) : PxsSimulationController(callback, PxIntFalse) {} + virtual ~SimulationController() {} - virtual PxU32 addTriRigidAttachment(Dy::FEMCloth*, PxsRigidBody*, const PxNodeIndex& , - PxU32 , const PxVec4& , const PxVec3&, PxConeLimitedConstraint*, const bool){ return 0xFFFFFFFF;} - - virtual void removeTriRigidAttachment(Dy::FEMCloth*, PxU32){} - - virtual void addClothFilter(Dy::FEMCloth*, Dy::FEMCloth*, PxU32, PxU32) {} - virtual void removeClothFilter(Dy::FEMCloth*, Dy::FEMCloth*, PxU32, PxU32){} - - virtual PxU32 addTriClothAttachment(Dy::FEMCloth*, Dy::FEMCloth*, PxU32, PxU32, - const PxVec4&, const PxVec4&, const bool){ return 0xFFFFFFFF;} - - virtual void removeTriClothAttachment(Dy::FEMCloth*, PxU32) {} - - virtual void addParticleSystem(Dy::ParticleSystem*, const PxNodeIndex&, PxParticleSolverType::Enum) {} - virtual void releaseParticleSystem(Dy::ParticleSystem*, PxParticleSolverType::Enum) {} - virtual void releaseDeferredParticleSystemIds() {} - - virtual void addHairSystem(Dy::HairSystem *, const PxNodeIndex&) {} - virtual void releaseHairSystem(Dy::HairSystem*) {} - virtual void releaseDeferredHairSystemIds() {} - virtual void activateHairSystem(Dy::HairSystem*) {} - virtual void deactivateHairSystem(Dy::HairSystem*) {} - virtual void setHairSystemWakeCounter(Dy::HairSystem*) {} - virtual void copyHairSystemData(void** , void* , void* , PxHairSystemData::Enum , const PxU32 , const PxU32 , void* ) {} - virtual void applyHairSystemData(void** , void* , void* , PxHairSystemData::Enum , const PxU32 , const PxU32 , void* ) {} -#endif - - virtual void flush() {} - virtual void updateDynamic(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void updateJoint(const PxU32 /*edgeIndex*/, Dy::Constraint* /*constraint*/){} - virtual void updateBodies(PxsRigidBody** /*rigidBodies*/, PxU32* /*nodeIndices*/, const PxU32 /*nbBodies*/) {} - virtual void updateBody(PxsRigidBody* /*rigidBody*/, const PxU32 /*nodeIndex*/) {} - virtual void updateBodies(PxBaseTask* /*continuation*/){} - virtual void updateShapes(PxBaseTask* /*continuation*/) {} - virtual void preIntegrateAndUpdateBound(PxBaseTask* /*continuation*/, const PxVec3 /*gravity*/, const PxReal /*dt*/){} - virtual void updateParticleSystemsAndSoftBodies(){} - virtual void sortContacts(){} - virtual void update(PxBitMapPinned& /*changedHandleMap*/){} - virtual void mergeChangedAABBMgHandle(const PxU32 /*maxAABBMgHandles*/, const bool /*suppressedReadback*/) {} - virtual void gpuDmabackData(PxsTransformCache& /*cache*/, Bp::BoundsArray& /*boundArray*/, PxBitMapPinned& /*changedAABBMgrHandles*/, bool /*suppress*/){} - virtual void updateScBodyAndShapeSim(PxsTransformCache& /*cache*/, Bp::BoundsArray& /*boundArray*/, PxBaseTask* /*continuation*/); - virtual void updateArticulation(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void updateArticulationJoint(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void updateArticulationTendon(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void updateArticulationExtAccel(Dy::FeatherstoneArticulation* /*articulation*/, const PxNodeIndex& /*nodeIndex*/) {} - virtual void updateArticulationAfterIntegration(PxsContext* /*llContext*/, Bp::AABBManagerBase* /*aabbManager*/, - PxArray& /*ccdBodies*/, PxBaseTask* /*continuation*/, IG::IslandSim& /*islandSim*/, const float /*dt*/); - virtual PxU32* getActiveBodies() { return NULL; } - virtual PxU32* getDeactiveBodies() { return NULL; } - virtual void** getRigidBodies() { return NULL; } - virtual PxU32 getNbBodies() { return 0; } - virtual PxU32 getNbFrozenShapes() { return 0; } - virtual PxU32 getNbUnfrozenShapes() { return 0; } - - virtual PxU32* getUnfrozenShapes() { return NULL; } - virtual PxU32* getFrozenShapes() { return NULL; } - virtual PxsShapeSim** getShapeSims() { return NULL; } - virtual PxU32 getNbShapes() { return 0; } - - virtual void clear() { } - virtual void setBounds(Bp::BoundsArray* /*boundArray*/){} - virtual void reserve(const PxU32 /*nbBodies*/) {} - - - virtual PxU32 getArticulationRemapIndex(const PxU32 /*nodeIndex*/) { return PX_INVALID_U32;} - - //virtual void setParticleSystemManager(PxgParticleSystemCore* /* psCore*/) {} - - virtual void copyArticulationData(void* /*jointData*/, void* /*index*/, PxArticulationGpuDataType::Enum /*flag*/, const PxU32 /*nbUpdatedArticulations*/, void* /*copyEvent*/) {} - virtual void applyArticulationData(void* /*data*/, void* /*index*/, PxArticulationGpuDataType::Enum /*flag*/, const PxU32 /*nbUpdatedArticulations*/, void* /*waitEvent*/, void* /*signalEvent*/) {} - - virtual void copySoftBodyData(void** /*data*/, void* /*dataSizes*/, void* /*softBodyIndices*/, PxSoftBodyDataFlag::Enum /*flag*/, const PxU32 /*nbCopySoftBodies*/, const PxU32 /*maxSize*/, void* /*copyEvent*/) {} - virtual void applySoftBodyData(void** /*data*/, void* /*dataSizes*/, void* /*softBodyIndices*/, PxSoftBodyDataFlag::Enum /*flag*/, const PxU32 /*nbUpdatedSoftBodies*/, const PxU32 /*maxSize*/, void* /*applyEvent*/) {} - - virtual void copyContactData(Dy::Context* /*dyContext*/, void* /*data*/, const PxU32 /*maxContactPairs*/, void* /*numContactPairs*/, void* /*copyEvent*/) {} - virtual void copyBodyData(PxGpuBodyData* /*data*/, PxGpuActorPair* /*index*/, const PxU32 /*nbCopyActors*/, void* /*copyEvent*/){} - - virtual void applyActorData(void* /*data*/, PxGpuActorPair* /*index*/, PxActorCacheFlag::Enum /*flag*/, const PxU32 /*nbUpdatedActors*/, void* /*waitEvent*/, void* /*signalEvent*/) {} - - virtual void* getMPMDataPointer(const Dy::ParticleSystem& /*psLL*/, PxMPMParticleDataFlag::Enum /*flags*/) { return NULL; } - virtual void* getSparseGridDataPointer(const Dy::ParticleSystem& /*psLL*/, PxSparseGridDataFlag::Enum /*flags*/, PxParticleSolverType::Enum /*type*/) { return NULL; } - - virtual void allocatePBDMaterialsBuffer(PxPhysXGpu* /*physxGpu*/, Dy::ParticleSystemCore& /*core*/, PxU64* /*gpuMemStat*/) {} - virtual void allocateFLIPMaterialsBuffer(PxPhysXGpu* /*physxGpu*/, Dy::ParticleSystemCore& /*core*/, PxU64* /*gpuMemStat*/) {} - virtual void allocateMPMMaterialsBuffer(PxPhysXGpu* /*physxGpu*/, Dy::ParticleSystemCore& /*core*/, PxU64* /*gpuMemStat*/) {} - - virtual void syncParticleData() {} - - virtual void updateBoundsAndShapes(Bp::AABBManagerBase& /*aabbManager*/, const bool/* useGpuBp*/, const bool /*useDirectApi*/){} - - virtual void computeDenseJacobians(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, void* /*computeEvent*/){} - virtual void computeGeneralizedMassMatrices(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, void* /*computeEvent*/){} - virtual void computeGeneralizedGravityForces(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, const PxVec3& /*gravity*/, void* /*computeEvent*/){} - virtual void computeCoriolisAndCentrifugalForces(const PxIndexDataPair* /*indices*/, PxU32 /*nbIndices*/, void* /*computeEvent*/) {} - virtual void applyParticleBufferData(const PxU32* /*indices*/, const PxGpuParticleBufferIndexPair* /*indexPairs*/, const PxParticleBufferFlags* /*flags*/, PxU32 /*nbUpdatedBuffers*/, void* /*waitEvent*/, void* /*signalEvent*/) {} - - virtual void flushInsertions() {} - -#if PX_SUPPORT_GPU_PHYSX - virtual PxU32 getNbDeactivatedFEMCloth() const { return 0; } - virtual PxU32 getNbActivatedFEMCloth() const { return 0; } - - virtual Dy::FEMCloth** getDeactivatedFEMCloths() const { return NULL; } - virtual Dy::FEMCloth** getActivatedFEMCloths() const { return NULL; } - - virtual bool hasFEMCloth() const { return false; } - - virtual PxU32 getNbDeactivatedSoftbodies() const { return 0; } - virtual PxU32 getNbActivatedSoftbodies() const { return 0; } - - virtual const PxReal* getSoftBodyWakeCounters() const { return NULL; } - - virtual Dy::SoftBody** getDeactivatedSoftbodies() const { return NULL; } - virtual Dy::SoftBody** getActivatedSoftbodies() const { return NULL; } - - virtual bool hasSoftBodies() const { return false; } - - virtual PxU32 getNbDeactivatedHairSystems() const { return 0; } - virtual PxU32 getNbActivatedHairSystems() const { return 0; } - virtual Dy::HairSystem** getDeactivatedHairSystems() const { return NULL; } - virtual Dy::HairSystem** getActivatedHairSystems() const { return NULL; } - virtual bool hasHairSystems() const { return false; } -#endif + virtual void updateScBodyAndShapeSim(PxsTransformCache& cache, Bp::BoundsArray& boundArray, PxBaseTask* continuation) PX_OVERRIDE; + virtual void updateArticulationAfterIntegration(PxsContext* llContext, Bp::AABBManagerBase* aabbManager, + PxArray& ccdBodies, PxBaseTask* continuation, IG::IslandSim& islandSim, float dt) PX_OVERRIDE; }; } diff --git a/physx/source/simulationcontroller/src/ScSleep.cpp b/physx/source/simulationcontroller/src/ScSleep.cpp new file mode 100644 index 000000000..ccff992f9 --- /dev/null +++ b/physx/source/simulationcontroller/src/ScSleep.cpp @@ -0,0 +1,315 @@ +// 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. + +#include "ScScene.h" +#include "ScArticulationSim.h" +#include "ScBodySim.h" +#include "common/PxProfileZone.h" + +#include "ScActorSim.h" +#include "ScArticulationSim.h" + +#if PX_SUPPORT_GPU_PHYSX + #include "ScSoftBodySim.h" + #include "ScFEMClothSim.h" + #include "ScParticleSystemSim.h" + #include "ScHairSystemSim.h" +#endif + +using namespace physx; +using namespace physx::Cm; +using namespace physx::Dy; +using namespace Sc; + +// PT: "setActive()" moved from ActorSim to BodySim because GPU classes silently re-implement this in a very different way (see below), +// i.e. it defeats the purpose of the virtual activate()/deactivate() functions. +void Sc::BodySim::setActive(bool active, bool asPartOfCreation) +{ + PX_ASSERT(!active || isDynamicRigid()); // Currently there should be no need to activate an actor that does not take part in island generation + + if(asPartOfCreation || isActive() != active) + { + PX_ASSERT(!asPartOfCreation || (getActorInteractionCount() == 0)); // On creation or destruction there should be no interactions + + if(active) + { + if(!asPartOfCreation) + getScene().addToActiveList(*this); // Inactive => Active + + activate(); + + PX_ASSERT(asPartOfCreation || isActive()); + } + else + { + if(!asPartOfCreation) + getScene().removeFromActiveList(*this); // Active => Inactive + + deactivate(); + + PX_ASSERT(asPartOfCreation || (!isActive())); + } + } +} + +void Sc::ArticulationSim::setActive(bool b, bool asPartOfCreation) +{ + const PxReal wakeCounter = mCore.getWakeCounter(); + const PxU32 nbBodies = mBodies.size(); + for(PxU32 i=0;igetBodyCore().setWakeCounterFromSim(wakeCounter); + mBodies[i]->setActive(b, asPartOfCreation); + } +} + +// PT: moving all the sleeping-related implementations to the same file clearly exposes the inconsistencies between them +#if PX_SUPPORT_GPU_PHYSX +void Sc::ParticleSystemSim::setActive(bool /*active*/, bool /*asPartOfCreation*/) +{ +} + +void Sc::FEMClothSim::activate() +{ + mScene.getSimulationController()->activateCloth(mLLFEMCloth); + + activateInteractions(*this); +} + +void Sc::FEMClothSim::deactivate() +{ + mScene.getSimulationController()->deactivateCloth(mLLFEMCloth); + + deactivateInteractions(*this); +} + +void Sc::FEMClothSim::setActive(bool active, bool /*asPartOfCreation*/) +{ + if(active) + activate(); + else + deactivate(); +} + +void Sc::SoftBodySim::setActive(bool active, bool /*asPartOfCreation*/) +{ + if(active) + getScene().getSimulationController()->activateSoftbody(mLLSoftBody); + else + getScene().getSimulationController()->deactivateSoftbody(mLLSoftBody); +} + +void Sc::HairSystemSim::setActive(bool active, bool /*asPartOfCreation*/) +{ + if(active) + getScene().getSimulationController()->activateHairSystem(mLLHairSystem); + else + getScene().getSimulationController()->deactivateHairSystem(mLLHairSystem); +} +#endif + +namespace +{ +struct GetRigidSim { static PX_FORCE_INLINE BodySim* getSim(const IG::Node& node) { return reinterpret_cast(reinterpret_cast(node.mRigidBody) - BodySim::getRigidBodyOffset()); } }; +struct GetArticSim { static PX_FORCE_INLINE ArticulationSim* getSim(const IG::Node& node) { return reinterpret_cast(node.mLLArticulation->getUserData()); } }; +#if PX_SUPPORT_GPU_PHYSX +struct GetSoftBodySim { static PX_FORCE_INLINE SoftBodySim* getSim(const IG::Node& node) { return node.mLLSoftBody->getSoftBodySim(); } }; +struct GetFEMClothSim { static PX_FORCE_INLINE FEMClothSim* getSim(const IG::Node& node) { return node.mLLFEMCloth->getFEMClothSim(); } }; +struct GetHairSystemSim { static PX_FORCE_INLINE HairSystemSim* getSim(const IG::Node& node) { return node.mLLHairSystem->getHairSystemSim(); } }; +#endif +} + +template +static void setActive(PxU32& nbModified, const IG::IslandSim& islandSim, IG::Node::NodeType type) +{ + PxU32 nbToProcess = active ? islandSim.getNbNodesToActivate(type) : islandSim.getNbNodesToDeactivate(type); + const PxNodeIndex* indices = active ? islandSim.getNodesToActivate(type) : islandSim.getNodesToDeactivate(type); + + while(nbToProcess--) + { + const IG::Node& node = islandSim.getNode(*indices++); + PX_ASSERT(node.mType == type); + if(node.isActive()==active) + { + SimT* sim = SimAccessT::getSim(node); + if(sim) + { + sim->setActive(active); + nbModified++; + } + } + } +} + +#ifdef BATCHED +namespace +{ +struct SetActiveRigidSim +{ + template + static void setActive(Scene& /*scene*/, PxU32 nbObjects, BodySim** objects) + { + if(1) + { + while(nbObjects--) + { + (*objects)->setActive(active); + objects++; + } + } + else + { + if(active) + { +// scene.addToActiveList(*this); +// activate(); +// PX_ASSERT(isActive()); + } + else + { +// scene.removeFromActiveList(*this); +// deactivate(); +// PX_ASSERT(!isActive()); + } + } + } +}; +} + +template +static void setActiveBatched(Scene& scene, PxU32& nbModified, const IG::IslandSim& islandSim, IG::Node::NodeType type) +{ + PxU32 nbToProcess = active ? islandSim.getNbNodesToActivate(type) : islandSim.getNbNodesToDeactivate(type); + const PxNodeIndex* indices = active ? islandSim.getNodesToActivate(type) : islandSim.getNodesToDeactivate(type); + + PX_ALLOCA(batch, SimT*, nbToProcess); + + PxU32 nb = 0; + while(nbToProcess--) + { + const IG::Node& node = islandSim.getNode(*indices++); + PX_ASSERT(node.mType == type); + if(node.isActive()==active) + { + SimT* sim = SimAccessT::getSim(node); + if(sim && sim->isActive()!=active) + batch.mPointer[nb++] = sim; + } + } + + SetActiveBatchedT::setActive(scene, nb, batch.mPointer); + + nbModified = nb; +} + +/* +Batched version would be just: +a) addToActiveList(batched objects) +b) activate(batched objects) + +void Sc::ActorSim::setActive(bool active) +{ + PX_ASSERT(!active || isDynamicRigid()); // Currently there should be no need to activate an actor that does not take part in island generation + + if(isActive() != active) + { + if(active) + { + // Inactive => Active + getScene().addToActiveList(*this); + + activate(); + + PX_ASSERT(isActive()); + } + else + { + // Active => Inactive + getScene().removeFromActiveList(*this); + + deactivate(); + + PX_ASSERT(!isActive()); + } + } +} +*/ +#endif + +void Sc::Scene::putObjectsToSleep() +{ + PX_PROFILE_ZONE("Sc::Scene::putObjectsToSleep", mContextId); + + //Set to sleep all bodies that were in awake islands that have just been put to sleep. + + const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); + + PxU32 nbBodiesDeactivated = 0; + //setActiveBatched(*this, nbBodiesDeactivated, islandSim, IG::Node::eRIGID_BODY_TYPE); + setActive(nbBodiesDeactivated, islandSim, IG::Node::eRIGID_BODY_TYPE); + setActive(nbBodiesDeactivated, islandSim, IG::Node::eARTICULATION_TYPE); + +#if PX_SUPPORT_GPU_PHYSX + setActive(nbBodiesDeactivated, islandSim, IG::Node::eSOFTBODY_TYPE); + setActive(nbBodiesDeactivated, islandSim, IG::Node::eFEMCLOTH_TYPE); + setActive(nbBodiesDeactivated, islandSim, IG::Node::eHAIRSYSTEM_TYPE); +#endif + + if(nbBodiesDeactivated) + mDynamicsContext->setStateDirty(true); +} + +void Sc::Scene::wakeObjectsUp() +{ + PX_PROFILE_ZONE("Sc::Scene::wakeObjectsUp", mContextId); + + //Wake up all bodies that were in sleeping islands that have just been hit by a moving object. + + const IG::IslandSim& islandSim = mSimpleIslandManager->getAccurateIslandSim(); + + PxU32 nbBodiesWoken = 0; + setActive(nbBodiesWoken, islandSim, IG::Node::eRIGID_BODY_TYPE); + setActive(nbBodiesWoken, islandSim, IG::Node::eARTICULATION_TYPE); + +#if PX_SUPPORT_GPU_PHYSX + setActive(nbBodiesWoken, islandSim, IG::Node::eSOFTBODY_TYPE); + setActive(nbBodiesWoken, islandSim, IG::Node::eFEMCLOTH_TYPE); + setActive(nbBodiesWoken, islandSim, IG::Node::eHAIRSYSTEM_TYPE); +#endif + + if(nbBodiesWoken) + mDynamicsContext->setStateDirty(true); +} + diff --git a/physx/source/simulationcontroller/src/ScSoftBodyCore.cpp b/physx/source/simulationcontroller/src/ScSoftBodyCore.cpp index 9b4eefe4c..77f0f0172 100644 --- a/physx/source/simulationcontroller/src/ScSoftBodyCore.cpp +++ b/physx/source/simulationcontroller/src/ScSoftBodyCore.cpp @@ -62,48 +62,16 @@ Sc::SoftBodyCore::SoftBodyCore() : mCore.mFlags = PxSoftBodyFlags(0); mCore.mPositionInvMass = NULL; - mCore.mPositionInvMassCPU = NULL; + mCore.mRestPosition = NULL; mCore.mSimPositionInvMass = NULL; - mCore.mSimPositionInvMassCPU = NULL; - mCore.mSimVelocityInvMass = NULL; - mCore.mSimVelocityInvMassCPU = NULL; + mCore.mSimVelocity = NULL; mCore.mKinematicTarget = NULL; - mCore.mKinematicTargetCPU = NULL; } -Sc::SoftBodyCore::~SoftBodyCore() -{ - if (mCore.mPositionInvMass) - mCore.mPositionInvMass->release(); - - if (mCore.mPositionInvMassCPU) - mCore.mPositionInvMassCPU->release(); - - if(mCore.mRestPositionInvMassCPU) - mCore.mRestPositionInvMassCPU->release(); - - if (mCore.mSimPositionInvMass) - mCore.mSimPositionInvMass->release(); - - if (mCore.mSimPositionInvMassCPU) - mCore.mSimPositionInvMassCPU->release(); - - if (mCore.mSimVelocityInvMass) - mCore.mSimVelocityInvMass->release(); - - if (mCore.mSimVelocityInvMassCPU) - mCore.mSimVelocityInvMassCPU->release(); - - if (mCore.mKinematicTarget) - mCore.mKinematicTarget->release(); - - if (mCore.mKinematicTargetCPU) - mCore.mKinematicTargetCPU->release(); -} - +Sc::SoftBodyCore::~SoftBodyCore() { } void Sc::SoftBodyCore::setMaterial(const PxU16 handle) @@ -136,7 +104,7 @@ void Sc::SoftBodyCore::setFlags(PxSoftBodyFlags flags) } mCore.mFlags = flags; - + mCore.dirty = true; } @@ -428,12 +396,12 @@ void Sc::SoftBodyCore::removeSoftBodyFilters(Sc::SoftBodyCore& core, PxU32* tetI PxU32 Sc::SoftBodyCore::addSoftBodyAttachment(Sc::SoftBodyCore& core, PxU32 tetIdx0, const PxVec4& triBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1, - PxConeLimitedConstraint* constraint) + PxConeLimitedConstraint* constraint, PxReal constraintOffset) { Sc::SoftBodySim* sim = getSim(); PxU32 handle = 0xFFFFFFFF; if (sim) - handle = sim->getScene().addSoftBodyAttachment(core, tetIdx0, triBarycentric0, *sim, tetIdx1, tetBarycentric1, constraint); + handle = sim->getScene().addSoftBodyAttachment(core, tetIdx0, triBarycentric0, *sim, tetIdx1, tetBarycentric1, constraint, constraintOffset); return handle; } @@ -463,13 +431,13 @@ void Sc::SoftBodyCore::removeClothFilter(Sc::FEMClothCore& core, PxU32 triIdx, P sim->getScene().removeClothFilter(core, triIdx, *sim, tetIdx); } -PxU32 Sc::SoftBodyCore::addClothAttachment(Sc::FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, - const PxVec4& tetBarycentric, PxConeLimitedConstraint* constraint) +PxU32 Sc::SoftBodyCore::addClothAttachment(Sc::FEMClothCore& core, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, + PxConeLimitedConstraint* constraint, PxReal constraintOffset) { Sc::SoftBodySim* sim = getSim(); PxU32 handle = 0xFFFFFFFF; if (sim) - handle = sim->getScene().addClothAttachment(core, triIdx, triBarycentric, *sim, tetIdx, tetBarycentric, constraint); + handle = sim->getScene().addClothAttachment(core, triIdx, triBarycentric, *sim, tetIdx, tetBarycentric, constraint, constraintOffset); return handle; } @@ -484,9 +452,9 @@ void Sc::SoftBodyCore::removeClothAttachment(Sc::FEMClothCore& core, PxU32 handl } -PxU32 Sc::SoftBodyCore::getGpuSoftBodyIndex() +PxU32 Sc::SoftBodyCore::getGpuSoftBodyIndex() const { - Sc::SoftBodySim* sim = getSim(); + const Sc::SoftBodySim* sim = getSim(); return sim ? sim->getGpuSoftBodyIndex() : 0xffffffff; } @@ -515,6 +483,23 @@ void Sc::SoftBodyCore::onShapeChange(ShapeCore& shape, ShapeChangeNotifyFlags no s.onRestOffsetChange(); } +void Sc::SoftBodyCore::setKinematicTargets(const PxVec4* positions, PxSoftBodyFlags flags) +{ + mCore.mKinematicTarget = positions; + + if (positions != NULL) + { + mCore.mFlags |= PxSoftBodyFlags(flags & PxSoftBodyFlags(PxSoftBodyFlag::eKINEMATIC | PxSoftBodyFlag::ePARTIALLY_KINEMATIC)); + } + else + { + mCore.mFlags.clear(PxSoftBodyFlag::eKINEMATIC); + mCore.mFlags.clear(PxSoftBodyFlag::ePARTIALLY_KINEMATIC); + } + + mCore.dirty = true; +} + #endif //PX_SUPPORT_GPU_PHYSX diff --git a/physx/source/simulationcontroller/src/ScSoftBodyShapeSim.h b/physx/source/simulationcontroller/src/ScSoftBodyShapeSim.h index 81f9c776d..f83a6ae8d 100644 --- a/physx/source/simulationcontroller/src/ScSoftBodyShapeSim.h +++ b/physx/source/simulationcontroller/src/ScSoftBodyShapeSim.h @@ -27,12 +27,13 @@ #ifndef SC_SOFTBODY_SHAPE_SIM_H #define SC_SOFTBODY_SHAPE_SIM_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "PxPhysXConfig.h" #include "ScElementSim.h" #include "ScShapeSimBase.h" - namespace physx { namespace Sc @@ -70,7 +71,6 @@ namespace physx //PX_FORCE_INLINE SoftBodySim& getBodySim() const { return static_cast(getActor()); } SoftBodySim& getBodySim() const; - void updateBounds(); void updateBoundsInAABBMgr(); PxBounds3 getBounds() const; @@ -80,7 +80,7 @@ namespace physx }; } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScSoftBodySim.cpp b/physx/source/simulationcontroller/src/ScSoftBodySim.cpp index b3a6de8d1..f0755ada6 100644 --- a/physx/source/simulationcontroller/src/ScSoftBodySim.cpp +++ b/physx/source/simulationcontroller/src/ScSoftBodySim.cpp @@ -24,7 +24,6 @@ // // Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. - #include "foundation/PxPreprocessor.h" #if PX_SUPPORT_GPU_PHYSX @@ -37,13 +36,10 @@ using namespace physx; using namespace physx::Dy; - Sc::SoftBodySim::SoftBodySim(SoftBodyCore& core, Scene& scene) : ActorSim(scene, core), - mShapeSim(*this), - mNumCountedInteractions(0) + mShapeSim(*this) { - mLLSoftBody = scene.createLLSoftBody(this); mNodeIndex = scene.getSimpleIslandManager()->addSoftBody(mLLSoftBody, false); @@ -86,16 +82,6 @@ bool Sc::SoftBodySim::isSleeping() const return sim.getActiveNodeIndex(mNodeIndex) == PX_INVALID_NODE; } - -void Sc::SoftBodySim::setActive(const bool b, const PxU32 infoFlag) -{ - PX_UNUSED(infoFlag); - if (b) - getScene().getSimulationController()->activateSoftbody(mLLSoftBody); - else - getScene().getSimulationController()->deactivateSoftbody(mLLSoftBody); -} - void Sc::SoftBodySim::onSetWakeCounter() { getScene().getSimulationController()->setSoftBodyWakeCounter(mLLSoftBody); @@ -141,7 +127,6 @@ void Sc::SoftBodySim::enableSelfCollision() } } - void Sc::SoftBodySim::disableSelfCollision() { if (isActive()) @@ -150,7 +135,7 @@ void Sc::SoftBodySim::disableSelfCollision() } } -void Sc::SoftBodySim::activate() +/*void Sc::SoftBodySim::activate() { // Activate body //{ @@ -206,9 +191,9 @@ void Sc::SoftBodySim::deactivate() // } // destroySqBounds(); //} -} +}*/ -PxU32 Sc::SoftBodySim::getGpuSoftBodyIndex() +PxU32 Sc::SoftBodySim::getGpuSoftBodyIndex() const { return mLLSoftBody->getGpuSoftBodyIndex(); } diff --git a/physx/source/simulationcontroller/src/ScSoftBodySim.h b/physx/source/simulationcontroller/src/ScSoftBodySim.h index 330385270..e94418626 100644 --- a/physx/source/simulationcontroller/src/ScSoftBodySim.h +++ b/physx/source/simulationcontroller/src/ScSoftBodySim.h @@ -27,6 +27,8 @@ #ifndef SC_SOFTBODY_SIM_H #define SC_SOFTBODY_SIM_H +#include "foundation/PxPreprocessor.h" +#if PX_SUPPORT_GPU_PHYSX #include "foundation/PxUserAllocated.h" #include "DySoftBody.h" #include "ScSoftBodyCore.h" @@ -40,10 +42,10 @@ namespace physx class SoftBodySim : public ActorSim { + PX_NOCOPY(SoftBodySim) public: - SoftBodySim(SoftBodyCore& core, Scene& scene); - - ~SoftBodySim(); + SoftBodySim(SoftBodyCore& core, Scene& scene); + ~SoftBodySim(); PX_INLINE Dy::SoftBody* getLowLevelSoftBody() const { return mLLSoftBody; } PX_INLINE SoftBodyCore& getCore() const { return static_cast(mCore); } @@ -57,7 +59,7 @@ namespace physx bool isSleeping() const; bool isActive() const { return !isSleeping(); } - void setActive(const bool b, const PxU32 infoFlag = 0); + void setActive(bool active, bool asPartOfCreation=false); void enableSelfCollision(); void disableSelfCollision(); @@ -67,35 +69,28 @@ namespace physx void attachShapeCore(ShapeCore* core); void attachSimulationMesh(PxTetrahedronMesh* simulationMesh, PxSoftBodyAuxData* simulationState); PxTetrahedronMesh* getSimulationMesh(); - PxSoftBodyAuxData* getSoftBodyAuxData(); + PxSoftBodyAuxData* getSoftBodyAuxData(); PxTetrahedronMesh* getCollisionMesh(); - virtual void registerCountedInteraction() { mNumCountedInteractions++; } - virtual void unregisterCountedInteraction() { mNumCountedInteractions--; } - virtual PxU32 getNumCountedInteractions() const { return mNumCountedInteractions; } - - virtual void activate(); - virtual void deactivate(); - - PxU32 getGpuSoftBodyIndex(); + PxU32 getGpuSoftBodyIndex() const; SoftBodyShapeSim& getShapeSim() { return mShapeSim; } private: - SoftBodySim& operator=(const SoftBodySim&); - Dy::SoftBody* mLLSoftBody; SoftBodyShapeSim mShapeSim; - PxU32 mNumCountedInteractions; PxU32 mIslandNodeIndex; +// PT: as far as I can tell these are never actually called +// void activate(); +// void deactivate(); }; } // namespace Sc - } +#endif #endif diff --git a/physx/source/simulationcontroller/src/ScTriggerInteraction.cpp b/physx/source/simulationcontroller/src/ScTriggerInteraction.cpp index e178efd18..be04dbc7c 100644 --- a/physx/source/simulationcontroller/src/ScTriggerInteraction.cpp +++ b/physx/source/simulationcontroller/src/ScTriggerInteraction.cpp @@ -47,10 +47,11 @@ TriggerInteraction::TriggerInteraction( ShapeSimBase& tShape, ShapeSimBase& oSha PX_COMPILE_TIME_ASSERT(PxPairFlag::eNOTIFY_TOUCH_LOST < 0xffff); PX_COMPILE_TIME_ASSERT(LAST < 0xffff); - bool active = registerInActors(); - Scene& scene = getScene(); - scene.registerInteraction(this, active); - scene.getNPhaseCore()->registerInteraction(this); + { + const bool active = onActivate(NULL); + registerInActors(); + getScene().registerInteraction(this, active); + } PX_ASSERT(getTriggerShape().getFlags() & PxShapeFlag::eTRIGGER_SHAPE); mTriggerCache.state = Gu::TRIGGER_DISJOINT; @@ -58,9 +59,7 @@ TriggerInteraction::TriggerInteraction( ShapeSimBase& tShape, ShapeSimBase& oSha TriggerInteraction::~TriggerInteraction() { - Scene& scene = getScene(); - scene.unregisterInteraction(this); - scene.getNPhaseCore()->unregisterInteraction(this); + getScene().unregisterInteraction(this); unregisterFromActors(); } @@ -100,7 +99,7 @@ static bool isOneActorActive(TriggerInteraction* trigger) // - If the scenario above does not apply, then a trigger pair can only be deactivated, if both actors are sleeping. // - If an overlapping actor is activated/deactivated, the trigger interaction gets notified // -bool TriggerInteraction::onActivate_(void*) +bool TriggerInteraction::onActivate(void*) { // IMPORTANT: this method can get called concurrently from multiple threads -> make sure shared resources // are protected (note: there are none at the moment but it might change) @@ -122,7 +121,7 @@ bool TriggerInteraction::onActivate_(void*) } } -bool TriggerInteraction::onDeactivate_() +bool TriggerInteraction::onDeactivate() { if(!readFlag(PROCESS_THIS_FRAME)) { diff --git a/physx/source/simulationcontroller/src/ScTriggerInteraction.h b/physx/source/simulationcontroller/src/ScTriggerInteraction.h index 5fde8fb24..d235b7c8f 100644 --- a/physx/source/simulationcontroller/src/ScTriggerInteraction.h +++ b/physx/source/simulationcontroller/src/ScTriggerInteraction.h @@ -72,8 +72,8 @@ namespace Sc PX_FORCE_INLINE void forceProcessingThisFrame(Sc::Scene& scene); - bool onActivate_(void*); - bool onDeactivate_(); + bool onActivate(void*); + bool onDeactivate(); protected: Gu::TriggerCache mTriggerCache; diff --git a/physx/source/simulationcontroller/src/ScVisualize.cpp b/physx/source/simulationcontroller/src/ScVisualize.cpp new file mode 100644 index 000000000..5b39d38c9 --- /dev/null +++ b/physx/source/simulationcontroller/src/ScVisualize.cpp @@ -0,0 +1,206 @@ +// 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. + +#include "ScScene.h" +#include "ScNPhaseCore.h" +#include "ScShapeInteraction.h" +#include "ScConstraintSim.h" +#include "ScConstraintCore.h" +#include "CmVisualization.h" + +using namespace physx; +using namespace Sc; + +// PT: Sc-level visualization code has been moved to this dedicated file (like we did in NpDebugViz.cpp) + +static void visualize(const ConstraintSim& sim, Cm::ConstraintImmediateVisualizer& viz, PxU32 flags, const PxTransform& idt) +{ + ConstraintCore& core = sim.getCore(); + if(!(core.getFlags() & PxConstraintFlag::eVISUALIZATION)) + return; + + const Dy::Constraint& llc = sim.getLowLevelConstraint(); + + PxsRigidBody* b0 = llc.body0; + PxsRigidBody* b1 = llc.body1; + + const PxTransform& t0 = b0 ? b0->getPose() : idt; + const PxTransform& t1 = b1 ? b1->getPose() : idt; + + core.getVisualize()(viz, llc.constantBlock, t0, t1, flags); +} + +void Sc::ShapeInteraction::visualize(PxRenderOutput& out, PxsContactManagerOutputIterator& outputs, + float scale, float param_contactForce, float param_contactNormal, float param_contactError, float param_contactPoint) +{ + if(mManager) // sleeping pairs have no contact points -> do not visualize + { + Sc::ActorSim* actorSim0 = &getShape0().getActor(); + Sc::ActorSim* actorSim1 = &getShape1().getActor(); + if(!actorSim0->isNonRigid() && !actorSim1->isNonRigid()) + { + PxU32 offset; + PxU32 nextOffset = 0; + do + { + const void* contactPatches; + const void* contactPoints; + PxU32 contactDataSize; + PxU32 contactPointCount; + PxU32 contactPatchCount; + const PxReal* impulses; + + offset = nextOffset; + nextOffset = getContactPointData(contactPatches, contactPoints, contactDataSize, contactPointCount, contactPatchCount, impulses, offset, outputs); + + const PxU32* faceIndices = reinterpret_cast(impulses + contactPointCount); + PxContactStreamIterator iter(reinterpret_cast(contactPatches), reinterpret_cast(contactPoints), faceIndices, contactPatchCount, contactPointCount); + + PxU32 i = 0; + while(iter.hasNextPatch()) + { + iter.nextPatch(); + while(iter.hasNextContact()) + { + iter.nextContact(); + + if((param_contactForce != 0.0f) && impulses) + { + out << PxU32(PxDebugColor::eARGB_RED); + out.outputSegment(iter.getContactPoint(), iter.getContactPoint() + iter.getContactNormal() * (scale * param_contactForce * impulses[i])); + } + else if(param_contactNormal != 0.0f) + { + out << PxU32(PxDebugColor::eARGB_BLUE); + out.outputSegment(iter.getContactPoint(), iter.getContactPoint() + iter.getContactNormal() * (scale * param_contactNormal)); + } + else if(param_contactError != 0.0f) + { + out << PxU32(PxDebugColor::eARGB_YELLOW); + out.outputSegment(iter.getContactPoint(), iter.getContactPoint() + iter.getContactNormal() * PxAbs(scale * param_contactError * PxMin(0.f, iter.getSeparation()))); + } + + if(param_contactPoint != 0.0f) + { + const PxReal s = scale * 0.1f; + const PxVec3& point = iter.getContactPoint(); + + //if (0) //temp debug to see identical contacts + // point.x += scale * 0.01f * (contactPointCount - i + 1); + + out << PxU32(PxDebugColor::eARGB_RED); + out.outputSegment(point + PxVec3(-s, 0, 0), point + PxVec3(s, 0, 0)); + out.outputSegment(point + PxVec3(0, -s, 0), point + PxVec3(0, s, 0)); + out.outputSegment(point + PxVec3(0, 0, -s), point + PxVec3(0, 0, s)); + } + i++; + } + } + } while (nextOffset != offset); + } + } +} + +// Render objects before simulation starts +void Sc::Scene::visualizeStartStep() +{ + PX_PROFILE_ZONE("Sim.visualizeStartStep", mContextId); + + // Update from visualization parameters + if(mVisualizationParameterChanged) + { + mVisualizationParameterChanged = false; + + // Update SIPs if visualization is enabled + if( getVisualizationParameter(PxVisualizationParameter::eCONTACT_POINT) || getVisualizationParameter(PxVisualizationParameter::eCONTACT_NORMAL) || + getVisualizationParameter(PxVisualizationParameter::eCONTACT_ERROR) || getVisualizationParameter(PxVisualizationParameter::eCONTACT_FORCE)) + mInternalFlags |= SceneInternalFlag::eSCENE_SIP_STATES_DIRTY_VISUALIZATION; + } + +#if PX_ENABLE_DEBUG_VISUALIZATION + const PxReal scale = getVisualizationScale(); + if(scale==0.0f) + { + // make sure visualization inside simulate was skipped + PX_ASSERT(getRenderBuffer().empty()); + return; // early out if visualization scale is 0 + } + + PxRenderOutput out(getRenderBuffer()); + + if(getVisualizationParameter(PxVisualizationParameter::eCOLLISION_COMPOUNDS)) + mAABBManager->visualize(out); + + // Visualize joints + { + const float frameScale = scale * getVisualizationParameter(PxVisualizationParameter::eJOINT_LOCAL_FRAMES); + const float limitScale = scale * getVisualizationParameter(PxVisualizationParameter::eJOINT_LIMITS); + if(frameScale!=0.0f || limitScale!=0.0f) + { + Cm::ConstraintImmediateVisualizer viz(frameScale, limitScale, out); + + PxU32 flags = 0; + if(frameScale!=0.0f) + flags |= PxConstraintVisualizationFlag::eLOCAL_FRAMES; + if(limitScale!=0.0f) + flags |= PxConstraintVisualizationFlag::eLIMITS; + + const PxTransform idt(PxIdentity); + + Sc::ConstraintCore*const * constraints = mConstraints.getEntries(); + for(PxU32 i=0, size = mConstraints.size();igetSim(); + if(sim) + visualize(*sim, viz, flags, idt); + } + } + } + + { + // PT: put common reads here to avoid doing them for each interaction + const PxReal param_contactForce = getVisualizationParameter(PxVisualizationParameter::eCONTACT_FORCE); + const PxReal param_contactNormal = getVisualizationParameter(PxVisualizationParameter::eCONTACT_NORMAL); + const PxReal param_contactError = getVisualizationParameter(PxVisualizationParameter::eCONTACT_ERROR); + const PxReal param_contactPoint = getVisualizationParameter(PxVisualizationParameter::eCONTACT_POINT); + + if(param_contactForce!=0.0f || param_contactNormal!=0.0f || param_contactError!=0.0f || param_contactPoint!=0.0f) + { + PxsContactManagerOutputIterator outputs = mLLContext->getNphaseImplementationContext()->getContactManagerOutputs(); + + ElementSimInteraction** interactions = getActiveInteractions(InteractionType::eOVERLAP); + PxU32 nbActiveInteractions = getNbActiveInteractions(InteractionType::eOVERLAP); + while(nbActiveInteractions--) + static_cast(*interactions++)->visualize( out, outputs, + scale, param_contactForce, param_contactNormal, param_contactError, param_contactPoint); + } + } +#else + PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION +#endif +} diff --git a/physx/version.txt b/physx/version.txt index 1e74033d6..b2ac507d1 100644 --- a/physx/version.txt +++ b/physx/version.txt @@ -1 +1 @@ -5.1.3.32494398 \ No newline at end of file +5.2.1.33015808 \ No newline at end of file