Open asdasdasdasdasdf opened 3 years ago
Can you share a PVD capture? What are the contact distance parameters that you are using? PhysX uses persistent manifolds so it will generate a set of contacts, then attempt to recycle/incrementally update those contacts. If you increase contact distance, it can increase the set of contacts in the manifold, which could avoid these cases where contacts are missed.
Also, related to (2), you don't need to implement contact modification to achieve this. PxRigidBody::setMaxDepenetrationVelocity should give you what you need - it allows you to define the maximum velocity that can be used to correct penetrations. It is defaulted to MAX_F32, but you can reduce this to something smaller such as 2-3m/s and you will no longer have such violent de-penetrations. However, you should ensure you do not set this too small because this can damage stable stacking.
Thanks for the quick response.
Unfortunately I'm running over remote desktop at the moment so I can't generate a PVD capture. I can hopefully get one later in the week.
I'm using default contact distance (I never call setContactOffset). I have PxTolerancesScale::length set to 1 so the contact distance would be (according to the docs) 0.02m. Interestingly I just measured and the collision is finally resolved at what appears to be a penetration of 0.02m. Not sure if that's a coincidence or not. My understanding was that the effective contact distance was the sum of values for the two shapes so would actually be 0.04m. I was skeptical about the contact distance helping since there are 10 or so ticks where the penetration is increasing roughly linearly so I don't think it's a question of failing to notice an impending contact. I'll try increasing though and see what impact it has. Is there some maximum number of contact points which make up the manifold which I should be increasing?
EDIT: I'll keep setMaxDepenetrationVelocity in mind as well
There is a maximum number, but not one that you can change without modifying the PCM code.
I'll take a look at your PVD capture when you have it and perhaps can advise better at that point.
Indeed it looks like increasing the contact offset from 0.02 to 0.04 has solved the problem but I'm quite confused as to why. With the default value of 0.02 the bodies interpenetrate by 0.02m (again might be coincidence) before fully depenetrating. I thought that the contact should be added to the manifold when they're separated by 0.02m rather than penetrated by 0.02m. If this were the case then I could see that 0.04 might give a more stable reaction as it would give a more complete picture of the impending contact but shouldn't some contact be enough?
Either way, thanks for your help so far.
I've Uploaded Missed Collision.pdx2 to the FTP. The body in question is part of the one articulation in the scene. Compare frame 1896 where no collision is detected despite there being obvious penetration to frame 1897 where the collision is detected and 1898 where it is resolved.
The contact distance 0.04m didn't end up working for me because
setMaxDepenetrationVelocity solution seems to work though it makes the reaction a bit more spongy (not in a way that's super noticeable) but I'd still like to understand the problem and how to avoid the root cause.
thanks
I think this one is almost certainly related to a recycling tolerance. The motion of the bucket is very slow so it's not CCD-related. The recycling tolerances are based on the size of the convex and they are probably just coming in a bit too large.
I suspect that we need to add in a lower-bound limit based on contact offset to make sure that we aren't going to miss contacts when simulating really large shapes.
If you want a quick fix workaround, take a look in
bool Gu::pcmContactConvexMesh(GU_CONTACT_METHOD_ARGS)
at this variable:
const FloatV minMargin = CalculatePCMConvexMargin(hullData, vScale, toleranceScale, GU_PCM_MESH_MANIFOLD_EPSILON);
and scale down that tolerance limit. It should improve this issue. we'll try to revisit this on my side and add in an additional heuristic based on contact offsets that should be more robust to this. I can't give you an ETA on when we'll be able to do that at the moment.
An alternative to adjusting the recycling thresholds is to increase the contact offset, which ensures we generate contacts while they are separated and makes sure the recycling doesn't cause us to miss contacts.
cool thanks. I'll give that a go when I get a chance.
When you say really large shapes are you talking about the dynamic body or the static terrain? I am surprised if you're referring to the bucket since it's only maybe 4x the length scale.
I am referring to the bucket. I suspect the issue is the very slow moving, large shape exacerbating the issues. I've not seen this kind of artefact with large objects before, but it does seem likely that it's related to us having an empty manifold and then only triggering contact gen once the relative transforms of the shapes have moved beyond a certain amount.
Ah that makes sense. One thing though, according to the docs I have to set eENABLE_PCM in order to be using PCMs and I'm not setting that flag. Does that affect your theory or proposed solution?
With PhysX 4, PCM is on by default. The legacy collision approach has also been augmented to add in some contact caching, although it uses a different approach to generate, track and update contacts.
Oh that is not obvious in the documentation. Thanks for clarifying.
Is there a way to disable the caching entirely or per body? I'd be interested to see the impact on performance in my case where there are relatively few bodies.
Not without changing the code on your end. It's certainly something that could be added, but the hope is that this should be completely transparent to the user. It's super easy to make it do collision all the time if you want to edit that function.
change this
if(multiManifold.invalidate(curTransform, minMargin))
to
if(multiManifold.invalidate(curTransform, minMargin) || 1)
and it will go into contact gen regardless of the results of the manifold invalidation logic.
alright thanks a lot for all your help!
I have a dynamic rigid body (articulation link) interacting with static triangle mesh geometry (a tunnel if that's important). The region of the static geometry where they interact is more or less flat (normal to gravity axis). I'm rotating the dynamic body with a joint and when it collides with the ground, as I continue to push I expect it to lift. If this sounds like #452 it's because it's a new issue in the same setup.
What I observe is that low-penetration collisions which are clearly present in my diagnostic rendering of the two geometries are not detected by PhysX. Once the collision is eventually detected there is a lot of penetration and a violent depenetration occurs. Stepping through frame by frame I can see that on the frame where the collision is resolved the dynamic body is sitting exactly on the static surface but on subsequent ticks its momentum carries it further up.
How should I mitigate this? I'm using PhysX 4.1.2. To the best of my knowledge I'm using default cooking settings and collision detection settings on the scene. To be clear, I'm not super concerned about minor collisions not being detected right away. The effect I primarily want to avoid is the violent depenetrations which occur as the collisions get worse before they are detected.
Is convex-trimesh collision detection expected to be "correct" or does it have limitations of approximation?
I've found quite a lot of settings I could experiment with that sound peripherally related but I'm not sure which to focus on.
So far I have two ideas:
planeTolerance = 0.03
I end up with simpler geometry which doesn't seem to exhibit the problem. The concern I have with this solution is that I still don't understand the underlying cause so I'm not sure to what extent I should rely on this fix.Basically I'm looking for advice on what capabilities I should expect from PhysX in this area so I can tell whether I'm doing something wrong or PhysX and, either way, what I should do about it.
Thanks