NVIDIAGameWorks / PhysX

NVIDIA PhysX SDK
Other
3.19k stars 807 forks source link

Dynamic heightfield collision doesn't wake up dynamic shapes #167

Open ZhivaevDmitry opened 5 years ago

ZhivaevDmitry commented 5 years ago

I am working on dynamic heighfield collision for ARSandbox system using PhysX 3.4 (UE 4.21)

I throw the spheres on the heightfield and observe that after falling asleep, a force from the heightfield does not awaken them. At the same time, when they are in an awakened state, all physics works correctly.

Is this the correct behavior, or am I doing something wrong?

Pierre-Terdiman commented 5 years ago

You might want to try a PxScene::resetFiltering() call on the heightfield actor, to make this work.

ZhivaevDmitry commented 5 years ago

You might want to try a PxScene::resetFiltering() call on the heightfield actor, to make this work.

Thanks, it worked!

But in PhysX documentation: "This is an expensive operation, don't use it if you don't have to."

Unfortunately I have 30 fps heighfield stream, and this solution does not suit me.

Pierre-Terdiman commented 5 years ago

What is your framerate before & after doing this call? It's relatively "expensive" but not so much that you should avoid it at all cost. Sometimes this is the right tool for the job, and we do use it ourselves in "SnippetDeformableMesh".

I can imagine alternative ways to do this but they're all more complicated for users.

One simple way to reduce the cost of "resetFiltering" is to use smaller heightfield tiles (instead of, say, a single giant heightfield). That way the number of internal "interactions" (there's one between the heightfield and each of the dynamic spheres resting on it) is reduced, and so is the cost of "resetFiltering".

One way to avoid "resetFiltering" would be to compute the bounding box around the part of the heightfield that you modify (assuming you modify a small portion of the heightfield, not all of it. Otherwise just retrieve the whole heightfield bounds with PxActor::getWorldBounds). Then do an AABB overlap query to retrieve all dynamic objects touching that part of the heightfield. Then call wakeUp() on each of them.

I'd need to create a repro and go through the code to see if there are easier ways.

Pierre-Terdiman commented 5 years ago

Another suggestion that might work would be to set the terrain as a kinematic and set its kinematic target to be the current pose. That might wake up the spheres properly. (I need to create a repro to confirm all this).

ZhivaevDmitry commented 5 years ago

What is your framerate before & after doing this call? It's relatively "expensive" but not so much that you should avoid it at all cost. Sometimes this is the right tool for the job, and we do use it ourselves in "SnippetDeformableMesh".

I can imagine alternative ways to do this but they're all more complicated for users.

One simple way to reduce the cost of "resetFiltering" is to use smaller heightfield tiles (instead of, say, a single giant heightfield). That way the number of internal "interactions" (there's one between the heightfield and each of the dynamic spheres resting on it) is reduced, and so is the cost of "resetFiltering".

One way to avoid "resetFiltering" would be to compute the bounding box around the part of the heightfield that you modify (assuming you modify a small portion of the heightfield, not all of it. Otherwise just retrieve the whole heightfield bounds with PxActor::getWorldBounds). Then do an AABB overlap query to retrieve all dynamic objects touching that part of the heightfield. Then call wakeUp() on each of them.

I'd need to create a repro and go through the code to see if there are easier ways.

modifySamples turned out to be fairly thread safe, so the FPS is the same. The problem is in the processing time: the user feels a delay, now I managed to achieve processing in 2 milliseconds, with resolution 110 x 66, on RK-3288 Android platform. It turned out very cool, because the texture streaming takes about the same amount of time, and it turned out such a synchronization of collision and visualization.

I observe a 50% increase in processing time with PxScene::resetFiltering(), moreover, it is not thread safe, so I have to call it in the main thread.

Unfortunately usually 4-6 kids simultaneously play in our sandbox, which completely negates optimization in the form of segmentation heightfield.

The idea with PxActor :: getWorldBounds is quite interesting, but it seems to me that everything should be much simpler.