Hey, i've started integrating PhysX into my graphical engine recently(purpose is basic collision with level, which is represented by static primitives and some debris, like cans, barrels and bottles reacting at bullets and impact with a player). Currently done is representing the scene with static primitives and using convex hulls for dynamic actors. And at this stage i've noticed PhysX acting not exactly like one would expect. I'll try to describe it as verbose as possible, and i would like to hear some logical explanation and advice.

My initial setup was:

Timestep 1/30.0f, called in a separate from rendering thread, which runs at 30 FPS.

simulate() and fetchResults() Are called exactly, as in example from official documentation.

i also set setCMassLocalPose to model's relative center(because some models may be not centered correctly).

First of all, i would expect to just set object's mass in kilograms, or at least relative to other objects, with default gravity of -9.8 and timestep of 30. Neither worked. Objects with mass of hundreds or thousands kilograms end up falling through the floor or bouncing crazily. And smaller objects with lower mass were too floaty.

At first, all big\medium-sized objects were freaking out. And by looking at PVD's grid in comparison with my scene, i figured i need to rescale my scene. My level is up to 3000 by 3000 units size. Medium-sized object is 20-30 units, and small object is around 2-4 units of size. So in process passing physical objects to PhysX, i now rescale them and their positions by some factor(now it's 0.05f). And it made things better.

But there are significant problems remaining. First thing i don't get is why scene get's slo-mo, if i decrease time step size. PhysX Tips page says "Few substeps: moon gravity effects", so it's vice-versa.
Actors with bigger mass still act inadequately.
Different scaling factor affects simulation speed. So setting scale to a smaler value, makes everything move more rapidly and with less inertia\bounce. With smaller scene scale, smaller objects act like they have enormous friction or low bounce\angular velocity.

And that leads to the main problem i can't solve yet is that with scene, rescaled by 0.05f smaller objects(like soda can or a pack of cigarettes) act really floaty. They don't react well on collision, they rotate too slowly and don't bounce. I have a scene with a character model, some barrels, a big box and soda can, represented with convex hulls. And environment, represented with boxes, spheres and capsules. I fly around and shoot spheres at them, and look how they react. Medium-sized objects have a mass of 20-30, and small objects have a mass of 5(yeah, i did mention relative mass inconsistency. if i put more appropriate relative weight to smaller objects, they act even floatier and don't react much on a sphere with 100000 density and while falling, they act more like poo).

I just don't want to fiddle with magic numbers. I would like to find some explanation and make it more predictable and consistent.

P.S. PhysX version is 3.2.4 and platform is Windows.
P.S.S. I hope this is an appropriate forum for such questions.

Well, first I'd try leaving all the weird scaling factors untouched and decide exactly the measures of my world. Start with 1 unit = 1m and begin experimenting with some convex hulls no larger than 5 units (unscaled). Too large objects can be deceiving as they may seem to fall in slo-mo. After these "standard sized" actors are behaving correctly, you can start putting more arbitrary actors in. And if physx provides any scaling factors I strongly suggest ignoring them as they can initially cause problems exactly like these.

if i pass my scene, without re-scaling it to lower size with all the default parameters, it's super slow-mo. and objects with the mass of dozens already start to freak out(penetrating through static actors, bouncing weirdly or falling through completely). smaller objects(up to 5 units) are also slow-mo. that's why i figured problem is my scene's size, but it just doesn't sound right.

That PxMeshScale is probably what you should attempt to get rid of, for now. Scale should be 1.0, and the actor size determined entirely by the convex hull dimensions (at the point where you "cook" it). How big is the convex hull anyway, I mean the approximate distance between two furthest points forming it?

At least in earlier versions of physx 3.x, that PxMeshScale didn't fix oversized convex hulls. Did you already try unit spheres (for example), to see if they make any difference in speed? And how's your initialization code?

That PxMeshScale is probably what you should attempt to get rid of, for now. Scale should be 1.0, and the actor size determined entirely by the convex hull dimensions (at the point where you "cook" it). How big is the convex hull anyway, I mean the approximate distance between two furthest points forming it?

to clarify, my convex hulls are based on the model. but this model can be used by different entities, with different scaling. that's it. so i rescale initial convex hull by that entitiy's scale using PxMeshScale, before passing it to the scene, so it fits perfectly. and they look fine in PVD. so data is 100% ok, but i may set some parameters wrong. documentation is not clear on call order and physical parameters of objects and doesn't say much about scale\mass.

At least in earlier versions of physx 3.x, that PxMeshScale didn't fix oversized convex hulls. Did you already try unit spheres (for example), to see if they make any difference in speed? And how's your initialization code?

just tried PxSphereGeometry(1.0f) instead of convex geometry, they're in slow-mo as well, but they don't fall through static stuff(i guess, cause sphere collision is really basic and predictable).

Hm ok, so that's not the problem then. I recall that scale thing being a source of some problems earlier, but don't know about that anymore. I'm using 3.3 beta 2 myself now.

Initialization seems ok. Check filter shaders and possibly compare your code to those (awful) examples in case you're missing something. Are you calling PxRigidBodyExt::setMassAndUpdateInertia for dynamic actors after creating all the shapes? That's also pretty important. You shouldn't need that setMass() at all.

i replaced it with PxRigidBodyExt::setMassAndUpdateInertia after createShape(), using the same masses(~25 for medium object and 1-5 for small objects). and now, if i set scene scale factor to 1.0f, objects don't fall through stuff, but everything is still in slow-mo. so maybe i've missed some other parameter?

here's how i initialize convex hull actors(beware of temporary\experimental grabage-code):

If you're sure that slowness isn't just an illusion caused by big objects (after all, even a unit sphere can seem to accelerate pretty slow from distance in empty world) it's most likely a bug in timestepping or anything related. Like I'm not sure if that "mLastTime = clock();" should be there after "return" -> deltaTime grows too big if mAccumulator < mStepSize (mLastTime should be updated in any case). But slo-mo is usually pretty easy to fix if the simulation is otherwise working correctly.

and it doesn't explain, what "dt" is. but it's certainly not what i passed. because it's float and it should be smaller, than 1.0f/stepSize; but if i remove all these extra-timings and leave only simulate() and fetchResults(), it's still slow-mo. this parameter only makes difference, if i divide it by really high values, like tens of thousands, then physx turns into a complete slideshow. if i make it's value bigger, it doesn't matter.

I guess the ultimate point of these snippets is to keep the physics timestep fixed while graphics run at higher fps interpolating frame results. There are obviously

better solutions than this piece of code and those will be more relevant at later development stages... Since your graphics run at constant 30fps, you could perhaps replace that code with just simulate(1.0f/30.0f) and fetchResults(true) and keep looking until you find the actual problem. fetchResults can be called right after simulate as long as that first parameter remains true. I suppose it's also possible to "hack" some speed by making that dt > 1/30 (or even better call twice those functions), did you try the direct approach?

I guess the ultimate point of these snippets is to keep the physics timestep fixed while graphics run at higher fps interpolating frame results. There are obviously

better solutions than this piece of code and those will be more relevant at later development stages... Since your graphics run at constant 30fps, you could perhaps replace that code with just simulate(1.0f/30.0f) and fetchResults(true) and keep looking until you find the actual problem. fetchResults can be called right after simulate as long as that first parameter remains true. I suppose it's also possible to "hack" some speed by making that dt > 1/30 (or even better call twice those functions), did you try the direct approach?

well, actually, my graphics run at 60 FPS in a separate thread, and logics\physics are at 30 FPS. yes, i've tried simplifying time-step function to just "simulate(1.0f/30.0f) and fetchResults(true)", it didn't make any difference. as i already said, making dt bigger, doesn't really matter. i also tried calling functions multiple times. yes, it does speed things up. in order to get something resembling normal speed, i need to call them 3-4 times. it works, but it doesn't seem like a proper solution. and it's probably expensive as hell.

dt always means delta-time, which is the time spent last frame

so, each time you accumulated more than mStepSize time, you integrate (or simulate if you will)

it's hard to say why your scene is slow, since if you provided real time to the function, it would just integrate each and every time forever

i moved mLastTime = clock(); before simulation, and now it's super fast(5x speed. speed is normal, if i multiply deltaTime by 0.2f). i can just multiply deltaTime, but i'd like to figure out the reason.

and if i use fetchResults(false), speed is normal. but calling it with a false argument seems a bit undetermined.

The clock() function gives you the ticks elapsed since the program was launch. PhysX expects its delta times in seconds. Try dividing your clock values by CLOCKS_PER_SEC and working in seconds rather than ticks.

Physx...you might find yourself in trouble....there are not many(almost none) tutorials,or documentations for it

I don't quite understand what you mean - in my opinion/experience the documentation is extremely accurate, clear and complete. And the SDK comes with a bunch of samples, as well as tutorial/guides in the documentation. I'm not sure how anyone could ask for more, to be honest.

As for solving this problem - I'd recommend using the PhysX Visual Debugger - it's extremely useful generally, and only takes a couple of lines to set up the communication in your code. Then when you simulate, you can inspect pretty much everything, including the scene timestep, gravity, objects etc. If you're unsure whether things are moving as they should, set up a little test scenario in your game where you drop a sphere, and in the debugger check that it falls the correct distance in a given time period - distance = vel * time + 0.5 * gravity * time^2

If you can't figure things out from that, you could even attach the pvd capture to a post here...

I don't quite understand what you mean - in my opinion/experience the documentation is extremely accurate, clear and complete. And the SDK comes with a bunch of samples, as well as tutorial/guides in the documentation. I'm not sure how anyone could ask for more, to be honest.

As for solving this problem - I'd recommend using the PhysX Visual Debugger - it's extremely useful generally, and only takes a couple of lines to set up the communication in your code. Then when you simulate, you can inspect pretty much everything, including the scene timestep, gravity, objects etc. If you're unsure whether things are moving as they should, set up a little test scenario in your game where you drop a sphere, and in the debugger check that it falls the correct distance in a given time period - distance = vel * time + 0.5 * gravity * time^2

If you can't figure things out from that, you could even attach the pvd capture to a post here...

literally 1st post mentions i'm using PVD. and later i mention that objects in PVD output look fine, parameters are intact. bearing that in mind, how do you think can it lead me to an explanation of the fact that i need to pre-multiply delta-time by some factor to get rid of slow-mo? if you didn't bother to read at least most of the thread and last OP's post, then why do you reply?

it works, so i moved on to other things, but i'm still a bit bothered on where does this speed factor comes from.

Spoiler

and on documentation\samples quality....

in post #10 there's a snippet from documentation, for time-stepping. it's doesn't function correctly, at least in a normal application with a basic setup. it's taken out of context of their samples framework. and there's no explanation on how it supposed to work. doc only does general time-stepping explanation, but you need to know exactly what API expects you to do.

and when it comes to convex hull creation, it uses PxToolkit::MemoryOutputStream and PxToolkit::MemoryInputData. does it explain, wtf are those and wtf is PxToolkit? no. do you need to use them? no. you can use PxDefaultMemoryOutputStream and PxDefaultMemoryInputData. how do you supposed to know that? you supposed to guess, that there are classes, that do exactly the same thing in the library itself and not to link to that useless PxTollkit library exclusively for those two, despite documentation shows you example of doing that.

also, searching through documentation by "gpuDispatcher" i failed to find, where exactly it explains, how do you check, if GPU acceleration is available. it does show some intialization routine in a Scene initialization example, but it doesn't explain it. then it does it again in Particles and states as a sufficient initialization code. so i guess, you need to assume that if cudaContextManager is not NULL, you have it running?

that's my problem with this documentation. it's a bit non-deterministic and scattered. that's just problems i came up from the top of my head, from my experience. it's not really bad, but it's not well-written, you can't just highlight the stuff you need, because information is really scattered and it has some bugs. it doesn't cover it all. no one would complain if it was complemented with decent samples, but...

when you suggest PhysX SDK samples as a source of information, i start to question your sanity. take a look at their hello world. what do you expect to see? i don't know, maybe basic initialization, creation of a basic rigid body and a plane and timestep, proper shutdown. this all could fit into a single, very small and clean cpp file. instead of that, they implemented really poorly written cross-platform framework only for samples, so none of the samples source files contatins anything useful or anything you would expect to see. it's all scattered through a pile of include files, within a confusing mess of classes and functions. most of the time it is really problematic to navigate from a sample code through this framework to find the actual code that is executed and you need to do it constantly, while trying to keep a picture of all that in your head, reconstructing how sample would look, if it wasn't written by lunatic.

literally 1st post mentions i'm using PVD. and later i mention that objects in PVD output look fine, parameters are intact. bearing that in mind, how do you think can it lead me to an explanation of the fact that i need to pre-multiply delta-time by some factor to get rid of slow-mo? if you didn't bother to read at least most of the thread and last OP's post, then why do you reply?

I replied because I thought, and think, that my suggestion should help - rather than vaguely say "it looks like it's in slow motion" - do some basic numerical comparisons of simulation against theory. I can't see any mention of you doing that. PVD is useful for that.

I missed one sentence where you mention PVD out of 15 detailed posts. I'd say that's not unreasonable (though I agree it's in the original post!). Still doesn't invalidate my suggestion though.

It seems like you code by copy and paste, and if A/B doesn't work you just try B/A instead. That doesn't really work for physics stuff, in my experience.

I replied because I thought, and think, that my suggestion should help - rather than vaguely say "it looks like it's in slow motion" - do some basic numerical comparisons of simulation against theory. I can't see any mention of you doing that. PVD is useful for that.

I missed one sentence where you mention PVD out of 15 detailed posts. I'd say that's not unreasonable (though I agree it's in the original post!). Still doesn't invalidate my suggestion though.

It seems like you code by copy and paste, and if A/B doesn't work you just try B/A instead. That doesn't really work for physics stuff, in my experience.

i mention PVD twice in my 1st post, 1st time as an item in a list. and then in post 6 i mention again, that i do test with PVD. that's why i assumed, that you didn't read this thread at all.

copy paste exactly what? the only thing i copy-pasted(and openly stated that) was time-stepping function from documentation. it was in attempts to find a reason for my original problem with objects falling through stuff, by minimizing deviations from basic documentation code. and i couldn't tweak it in a sensible way, because it lacks any description. as soon as i've got some hints on how it should work from someone, who has more experience with PhysX, i fixed it and cleaned it up. you know something more sensible to do?

other sections of code are also based on documentation code with only necessary alternations. i always do it like that, when i gradually figure out something. i see no point in wrapping it up yet, because i tweak it a lot.

about simulation numbers. ok, i spawned a unit sphere with a density of 1 at some height, and using PVD i measured that without any deltaTime scaling(so everything is slow-mo), gravity of -9.8f and stepSize of 1/30 it touched the ground in 2.5 seconds, falling 132 units from starting point. well, it's velocity wasn't constant, but i'm not sure how else can you measure it.

about simulation numbers. ok, i spawned a unit sphere with a density of 1 at some height, and using PVD i measured that without any deltaTime scaling(so everything is slow-mo), gravity of -9.8f and stepSize of 1/30 it touched the ground in 2.5 seconds, falling 132 units from starting point. well, it's velocity wasn't constant, but i'm not sure how else can you measure it.

Do you mean that in 2.5 seconds (that is: 2.5 seconds of simulation time), your sphere, starting at rest, has fallen 132m? If so, that's much further than expected - you'd expect 0.5 * 9.81 * 2.5 * 2.5 which is about 30.7m. That would suggest your simulation is running faster than normal... so I'm not sure I've interpreted your numbers right.

In post 13 your loop multiplies by mStepSize, which is definitely wrong - but then you correct it in post 15. But it's still not quite clear what your latest version looks like.

I've replaced two calls to clock with one. I wonder - with your current code, assuming your scene is really simple, that update loop may spend a lot of time just spinning round, whilst it waits for the accumulator to accumulate, in which case each time it will lose a little bit of time - maybe that's where your slowdown is coming from?