Comments (5)
Thank you for the report! We'll have a look. Internal tracking: PX-4672
from physx.
Thanks for the report! I'm trying to reproduce this but my first attempts are failing, but I'm on windows right now. Will try linux later. Could you maybe give me a hint about the order of magnitude of the number of shapes? Did you have additional actors in the scene, and if so, what kind? Are you using GPU dynamics?
from physx.
Hi @adenzler-nvidia,
I could finally trigger the crash 100% of the time with the following code. I believe that it might be related to the behaviour noticed by @Elercia in #226.
The code creates three kinematic actors, to which a great number of boxes and spheres are exclusively attached to. Actors 2 and 3 are completely overlapping, and actor 1 is partly overlapping with the others. The number of shapes attached to each object is set to 2*N^3. When N = 14, the crash is triggered when calling PX_RELEASE(), at which point 26940 + 0 + 26940 contact pairs were detected. When N = 13, 18456 + 57244 + 18456 contact pairs are detected but the crash is not triggered.
Note that the contact pairs between the actors that are entirely overlapping are not being detected when N = 14 but are detected when N = 13.
I hope this helps.
#include <iostream>
#include <vector>
#include "PxPhysicsAPI.h"
#include "eigen3/Eigen/Eigen"
using namespace physx;
using namespace std;
using namespace Eigen;
static PxDefaultAllocator gAllocator;
static PxDefaultErrorCallback gErrorCallback;
static PxFoundation* gFoundation = NULL;
static PxPhysics* gPhysics;
static PxDefaultCpuDispatcher* gDispatcher;
static PxScene* gScene;
static PxMaterial* gMaterial;
static PxFilterFlags contactReportFilterShader( PxFilterObjectAttributes attributes0, PxFilterData filterData0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
{
PX_UNUSED(attributes0);
PX_UNUSED(attributes1);
PX_UNUSED(filterData0);
PX_UNUSED(filterData1);
PX_UNUSED(constantBlockSize);
PX_UNUSED(constantBlock);
pairFlags = PxPairFlag::eDETECT_DISCRETE_CONTACT
| PxPairFlag::eNOTIFY_TOUCH_FOUND
| PxPairFlag::eNOTIFY_CONTACT_POINTS;
return PxFilterFlag::eDEFAULT;
}
class ContactReportCallback: public PxSimulationEventCallback
{
void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { PX_UNUSED(constraints); PX_UNUSED(count); }
void onWake(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
void onSleep(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
void onTrigger(PxTriggerPair* pairs, PxU32 count) { PX_UNUSED(pairs); PX_UNUSED(count); }
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
{
PX_UNUSED((pairHeader));
cout << "Contact detected: " << nbPairs << " pairs" << endl;
}
};
ContactReportCallback gContactReportCallback;
int main()
{
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale());
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
sceneDesc.gravity = PxVec3(0.0f, 0.0f, -9.81f);
gDispatcher = PxDefaultCpuDispatcherCreate(2);
sceneDesc.cpuDispatcher = gDispatcher;
sceneDesc.kineKineFilteringMode = PxPairFilteringMode::eKEEP;
sceneDesc.filterShader = contactReportFilterShader;
sceneDesc.simulationEventCallback = &gContactReportCallback;
gScene = gPhysics->createScene(sceneDesc);
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.1f);
//Spheres positions - create a grid of NxNxN spheres
vector<Vector3f> sphere_positions;
//NOTE: The crash is triggered when N >= 14 only.
// With N=13, there are 18456 + 57244 + 18456 contact pairs detected.
// With N=14, there are 26940 + 0 + 26940 contact pairs detected.
int N = 14;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
for(int k = 0; k < N; k++){
sphere_positions.push_back(Vector3f(i*0.1, j*0.1, k*0.1));
}
}
}
/// OBJECT 1
PxArray<PxShape*> shapes;
for(int i = 0; i < sphere_positions.size(); i++)
{
//Create a sphere
PxSphereGeometry sphereGeometry = PxSphereGeometry(0.01);
PxShape* sphere = gPhysics->createShape(sphereGeometry, *gMaterial, true);
//Create a box
PxBoxGeometry boxGeometry = PxBoxGeometry(0.05, 0.05, 0.05);
PxShape* box = gPhysics->createShape(boxGeometry, *gMaterial, true);
//Set the position
Vector3f pos = sphere_positions[i];
sphere->setLocalPose(PxTransform(PxVec3(pos[0], pos[1], pos[2])));
sphere->setRestOffset(0);
sphere->setContactOffset(1e-6);
box->setLocalPose(PxTransform(PxVec3(pos[0], pos[1], pos[2])));
box->setRestOffset(0);
box->setContactOffset(1e-6);
shapes.pushBack(sphere);
shapes.pushBack(box);
}
//Pose of the actor/object in the world frame column by column [col0 | col1 | col2 | col3]
Matrix4f pose;
pose << 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
PxTransform pxPose = PxTransform(PxMat44(
PxVec3(pose(0,0), pose(1,0), pose(2,0)),
PxVec3(pose(0,1), pose(1,1), pose(2,1)),
PxVec3(pose(0,2), pose(1,2), pose(2,2)),
PxVec3(pose(0,3), pose(1,3), pose(2,3))));
//Create a kinematic actor and attach all spheres to it
PxRigidDynamic* actor = gPhysics->createRigidDynamic(pxPose);
actor->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
//Attach all shapes in the object to the actor
for(int i = 0; i < shapes.size(); i++){
if(shapes[i] != nullptr){
actor->attachShape(*shapes[i]);
//We release the shape after it has been attached such that when the actor
// is released, the shape is also released.
shapes[i]->release();
}
}
actor->setMass(1);
actor->setCMassLocalPose(PxTransform(PxVec3(0,0,0)));
gScene->addActor(*actor);
actor->setGlobalPose(pxPose);
actor->setKinematicTarget(pxPose);
//Run simulation
float dt = 1/1000.0;
gScene->simulate(dt/2);
gScene->fetchResults(true);
gScene->simulate(dt/2);
gScene->fetchResults(true);
/// OBJECT 2 with overlapping spheres
PxArray<PxShape*> shapes2;
for(int i = 0; i < sphere_positions.size(); i++)
{
//Create a sphere
PxSphereGeometry sphereGeometry = PxSphereGeometry(0.01);
PxShape* sphere = gPhysics->createShape(sphereGeometry, *gMaterial, true);
//Create a box
PxBoxGeometry boxGeometry = PxBoxGeometry(0.05, 0.05, 0.05);
PxShape* box = gPhysics->createShape(boxGeometry, *gMaterial, true);
//Set the position
Vector3f pos = sphere_positions[i];
sphere->setLocalPose(PxTransform(PxVec3(pos[0], pos[1], pos[2])));
sphere->setRestOffset(0);
sphere->setContactOffset(1e-6);
box->setLocalPose(PxTransform(PxVec3(pos[0], pos[1], pos[2])));
box->setRestOffset(0);
box->setContactOffset(1e-6);
shapes2.pushBack(sphere);
shapes2.pushBack(box);
}
pose << 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0.9,
0, 0, 0, 1;
pxPose = PxTransform(PxMat44(
PxVec3(pose(0,0), pose(1,0), pose(2,0)),
PxVec3(pose(0,1), pose(1,1), pose(2,1)),
PxVec3(pose(0,2), pose(1,2), pose(2,2)),
PxVec3(pose(0,3), pose(1,3), pose(2,3))));
//Create a kinematic actor and attach all spheres to it
PxRigidDynamic* actor2 = gPhysics->createRigidDynamic(pxPose);
actor2->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
//Attach all shapes in the object to the actor
for(int i = 0; i < shapes2.size(); i++){
if(shapes2[i] != nullptr){
actor2->attachShape(*shapes2[i]);
//We release the shape after it has been attached such that when the actor
// is released, the shape is also released.
shapes2[i]->release();
}
}
actor2->setMass(1);
actor2->setCMassLocalPose(PxTransform(PxVec3(0,0,0)));
gScene->addActor(*actor2);
actor2->setGlobalPose(pxPose);
actor2->setKinematicTarget(pxPose);
//Run simulation
gScene->simulate(dt/2);
gScene->fetchResults(true);
gScene->simulate(dt/2);
gScene->fetchResults(true);
/// OBJECT 3 with overlapping spheres
PxArray<PxShape*> shapes3;
for(int i = 0; i < sphere_positions.size(); i++)
{
//Create a sphere
PxSphereGeometry sphereGeometry = PxSphereGeometry(0.01);
PxShape* sphere = gPhysics->createShape(sphereGeometry, *gMaterial, true);
//Create a box
PxBoxGeometry boxGeometry = PxBoxGeometry(0.05, 0.05, 0.05);
PxShape* box = gPhysics->createShape(boxGeometry, *gMaterial, true);
//Set the position
Vector3f pos = sphere_positions[i];
sphere->setLocalPose(PxTransform(PxVec3(pos[0], pos[1], pos[2])));
sphere->setRestOffset(0);
sphere->setContactOffset(1e-6);
box->setLocalPose(PxTransform(PxVec3(pos[0], pos[1], pos[2])));
box->setRestOffset(0);
box->setContactOffset(1e-6);
shapes3.pushBack(sphere);
shapes3.pushBack(box);
}
//Create a kinematic actor and attach all spheres to it
PxRigidDynamic* actor3 = gPhysics->createRigidDynamic(pxPose);
actor3->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
//Attach all shapes in the object to the actor
for(int i = 0; i < shapes3.size(); i++){
if(shapes3[i] != nullptr){
actor3->attachShape(*shapes3[i]);
//We release the shape after it has been attached such that when the actor
// is released, the shape is also released.
shapes3[i]->release();
}
}
actor3->setMass(1);
actor3->setCMassLocalPose(PxTransform(PxVec3(0,0,0)));
gScene->addActor(*actor3);
actor3->setGlobalPose(pxPose);
actor3->setKinematicTarget(pxPose);
//Run simulation
gScene->simulate(dt/2);
gScene->fetchResults(true);
gScene->simulate(dt/2);
gScene->fetchResults(true);
//PhysX crash when releasing the scene
if(N >= 14){
cout << "We are going to crash now." << endl;
}
PX_RELEASE(gScene);
PX_RELEASE(gDispatcher);
PX_RELEASE(gPhysics);
}
from physx.
Thank you very much for the detailed repro snippet - I can reproduce the crash on my machine now. Interestingly, if you run this in debug config you'll hit an assert much earlier in ScNphaseCore::resizeContactReportPairData because the paircount overflows a 16bit variable. I'll have a closer look and get back to you with a potential fix/workaround.
from physx.
Hi @PhilNad - thanks again for the repro snippet. A fix for this crash will be in the next release.
For a workaround, I suggest using more actors with each one having fewer shapes attached, such that the total number of colliding shapes per actor pair does not exceed 65536 shape pairs.
from physx.
Related Issues (20)
- crush in PxContactStreamIterator getFaceIndex0 when GPU enabled and contact with custom geometry or mesh HOT 2
- PxRigidBodyExt::setMassAndUpdateInertia of kinematic rigid actor with triangle mesh causes: Assertion failed: mG.isFinite() HOT 2
- setting driveForceLimit does not work HOT 2
- SDF cause CUDA error , even black screen (driver crash)
- SDF cause CUDA error , even black screen (driver crash?) HOT 4
- Increasing Damping ingnores ForceLimit of PxD6 Joint HOT 9
- PxCustomGeometryExt::BaseConvexCallbacks::raycast doesn't report back which fields are valid HOT 2
- Trigger emulation and character controller HOT 3
- Crash inside SAP Broad phase when there is too much collision pairs HOT 2
- issue with getting a center of mass
- Unable to compile with Clang - __m128 is not a structure or union HOT 3
- TGS solver does not support PxPairFlag::eNOTIFY_THRESHOLD_FORCE_... flags HOT 2
- Blast build for Visual Studio 2022
- I can not link physx 5.3.0 library from vcpkg into my project HOT 3
- Static contact forces are not correct on inclined plane HOT 5
- linux - cannot build libraries (error: 'src' is an unsafe pointer used for buffer access [-Werror,-Wunsafe-buffer-usage]) HOT 9
- Bad task scheduling due to lack of priority HOT 2
- How to read data from Flow HOT 4
- Wrong includes within physx/include/extensions/PxCustomGeometryExt.h HOT 1
- D6 Joint doesn't report drive force HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from physx.