Archive for January, 2017

PhysX tip: rope tricks

Tuesday, January 17th, 2017

This video shows one of the ‘configurable tests’ from PEEL 1.1. It is about rope tricks, and how to make them more stable in PhysX.

The rope is first created in a naive way, and out-of-the-box there is already some visible instability in the results, even though the rope is small, nothing is attached to it, etc. Some people stop here and conclude something like “PhysX cannot do ropes”. But it is perhaps a little lazy and a little naive.

The stability of the rope will depend on multiple things. For starters, the location of the pivots has an impact on stability. By default the pivots are located on the sides of the spheres (at +radius for a sphere and -radius for the other sphere it is connected to). Click the first checkbox to put the pivots at the center of the spheres (+0 for one, +radius*2 for the other). As you can see in the video, things are already more stable that way.

But you can see a bit of stretching. The next trick then, is to create extra distance constraints between sphere N and sphere N+2 in the chain. I already mentioned this one in a previous blog post, but here you can see its effect.

The next trick is based on the observation that using a larger mass for the sphere gives a more stable rope. So a common and quite effective hack is to artificially increase the mass of the object, but just for computing its inertia tensor (you still use the proper mass for everything else otherwise). As you can see in the video, this is also enough in itself to get rid of the initial instability. There are other specific functions in the PhysX joints to achieve similar effects (such as PxJoint::setInvInertiaScale), but simply using 10x the sphere mass for computing its inertia works well enough. This is a rather common thing to do in games - and I remember they used exactly this in some of the Havok rope samples…

Ok, next, we attach a heavy box (100x the sphere’s mass) at the end of the rope, and see what happens.

Predictably, it doesn’t work well at all by default (there was already an instability without the heavy mass so no surprise here). Again, some people stop here and wrongly conclude that PhysX cannot simulate this case. Well, this is incorrect.

If we replicate the same tricks as before sequentially, we see that putting the pivots at the center of the spheres is now not enough anymore to fix the problem.

However using extra distance constraints does the trick.

And so does increasing the inertia, although there is still some clear stretching here.

Finally, the great thing about these tricks is that they’re orthogonal and can all be combined together for maximal stability. As you can see in the video, the results are quite stable and still pretty fast.

Now, an alternative to all this is simply to use the ‘articulations’ feature in PhysX. That’s what we demonstrate next. We toggle all the tricks off and simply create the rope using an articulation. As you can see, this one works out-of-the-box. No tricks needed.

However articulations have their own limitations, in particular at time of writing they are limited to 64 elements. And as you can see in PEEL, they are a lot more expensive than regular joints. So they should really only be used as a last resort, if nothing else works.

For ropes, the tricks presented here allow PhysX to simulate a chain of 200 spheres, with a heavy box attached at the end of it. It is stable, it doesn’t explode when manipulated with the mouse, and this is still with only 4 solver iterations. As you can see, the rope made of 200 spheres using regular joints is roughly as expensive as the rope made of 64 spheres in an articulation. So there is a clear price to pay just for the luxury of avoiding tricks.

If that price is not a deal-breaker, or in other words if performance is not the main concern, another effective solution (not demonstrated in the video) is simply to use smaller timesteps. You can play with this solution in PEEL, where the PhysX plugin’s UI allows one to use substeps. Since PhysX is fast, using 2 substeps is still sometimes within the physics CPU budget, while significantly increasing the stability and accuracy of all scenes. Give it a try!

PhysX tip: solver (position) iteration count / creating constraints N times

Tuesday, January 17th, 2017

The torus in this video is made of several rigid convex objects connected by fixed joints. Since the joints are fixed, the ideal behavior would be that each torus acts like a rigid compound object (with no deformation). With iterative / approximate solvers however, what you get is that the torus appears quite flexible, and it deforms like a soft body. Sometimes that’s the effect you want to achieve. Sometimes not.

If it’s not, there are two ways to improve this, as demonstrated in the video.

The first way is to increase the number of position iterations in the solver. This is done by calling PxRigidDynamic::setSolverIterationCounts(), with a higher ‘minPositionIters‘ value. The default is 4 iterations, which is usually enough for regular rigid bodies, but often insufficient for jointed systems. As you can see in the video, increasing the number of iterations makes the torus much more rigid. This is a relatively cheap solution, since each iteration is quite fast in PhysX. For example even with 32 iterations as in the video, PhysX remains faster than some other engines which, while providing a more rigid behavior by default, are still slower overall. That is, 32 iterations in PhysX can be faster than 4 iterations in other engines, for roughly the same torus rigidity.

However, increasing the number of iterations affects the performance of the whole ’simulation island’ that the object ends up a part of. Thus, the actual cost can be a bit unpredictable.

There is then a second way to increase the rigidity of the torus: just create the same constraints (i.e. the same joints) multiple times. This is pretty much equivalent to increasing the iteration counts, but the cost remains local to the object. In isolation this is more expensive than the first solution, because the joints’ setup code is performed multiple times now. But it can be a faster approach overall, in the context of a full game.

And then you can of course do both: create the constraints multiple times and also increase the solver iteration counts.

Now, this alternative approach has some issues that should be mentioned. First, for obvious reasons creating the constraints multiple times will use more memory. And second, the effect will depend on the order in which the constraints are created. For example say you have constraints 1 to N, and you want to create them 4 times. If you create them from 1 to N and repeat the sequence from scratch 4 times, it will work better than creating 4 times the same constraint before switching to the next. In other words, 1234..N1234..N1234..N1234..N is better than 1111222233334444..NNNN. This is semi-obvious but worth pointing out. For the same reason, this trick does not work equally well in all physics engines: some of them reorder constraints in arbitrary ways, etc. You can use PEEL 1.1 to check and explore how different engines react to this approach.

PhysX tip: solver (velocity) iteration count / max depenetration velocity

Tuesday, January 17th, 2017

If you create rigid bodies in an initially overlapping state in PhysX, you can get a violent reaction like the one in this video.

There are two ways to improve this, as demonstrated in the video.

The first way is to increase the number of velocity iterations in the solver. This is done by calling PxRigidDynamic::setSolverIterationCounts(), with a higher ‘minVelocityIters‘ value. The default is just 1 iteration, which is usually enough - but not when objects are overlapping. As you can see in the video, increasing the number of iterations gets rid of the explosion.

However increasing that number has a performance cost. And it is not always a good idea to increase that number for jointed systems.

So there is a second way, which is to setup a “max depenetration velocity” for the rigid body, using PxRigidBody::setMaxDepenetrationVelocity(). By default this is unlimited. In practice, limiting the depenetration velocity (e.g. to “3.0″ in the video) gets rid of the explosion, and it is much cheaper than increasing the solver iteration counts.

Visually this makes objects slowly move away from each-other until the penetration is resolved. This typical behavior can be seen in other engines like Havok.

Note that reducing the timestep does not improve the results here. The opposite happens: reducing the timestep makes the explosion even more violent, which is perhaps counter-intuitive. This is because PhysX tries to resolve the overlap in a single simulation call, and to move the object over the same distance in a shorter amount of time, it has to apply a larger force. So everything being otherwise equal, you get a more violent explosion.

Also, limiting the depenetration velocity can sometimes lead to thin objects passing through each other more easily, when they’re constantly pushed against one-another. It is easy to tweak on a per-object basis though, so generally speaking it is a good idea to limit the depenetration velocity.

PhysX tip: max angular velocity

Tuesday, January 17th, 2017

In PhysX, the angular velocity of dynamic bodies is limited and clamped to a user-defined “max angular velocity”. But the default value for it is a bit peculiar.

It’s 7.

Not 5 or 10 or 100. Just 7.

Why 7? Why not 8 or something else? This goes back all the way to NovodeX 2.0 and the story behind this specific value is not clear to me anymore. If I remember correctly it had to do with the lack of angular CCD (Continuous Collision Detection) in NovodeX: clamping the angular velocity to some low value seemed like a cheap way to prevent angular CCD issues. Or so we thought. It probably looked like a good idea at the time, but of course in retrospect, it wasn’t. Because this value is way too low - and no, I don’t remember why we picked “7″ in particular.

If you create a test scene for gyroscopic effects, like the one in this video, that default value prevents the objects from rotating, and you don’t get the expected behavior. Somehow this looks just as bad as CCD issues.

However, and fortunately, it is easy to change. For each body, call PxRigidDynamic::setMaxAngularVelocity() with a new, higher velocity limit (I used “100″ in the video). And suddenly the objects keep spinning and the scene works as expected. Problem solved!

For some reason we never updated that value. From NovodeX 2.0 to PhysX 3.4, the default max angular velocity is 7. I suppose we don’t modify it because we want to make sure that nothing breaks or changes in unexpected ways for users upgrading to a new version - as much as possible at least. We can be a bit paranoid and extreme about that kind of stuff. Do. Not. Break. People’s. Working. Code. (*)

(*) yeah I know, it didn’t always work out :)

EDIT: the default max angular velocity has finally been increased to 100 in PhysX 4.0.

PhysX 3.4 on GitHub

Tuesday, January 17th, 2017

A “pre-release” version of PhysX 3.4 has been posted on GitHub. It will be called a pre-release until around GDC this year, but there shouldn’t be many changes going in till then - basically just bug-fixes if / when customers report issues.

So for all intents and purpose, that’s basically PhysX 3.4.0’s source code, available right now. The architecture has been completely revisited since last year, to make everything work with GPU rigid bodies. If you wanted to play with “GRB”, now is your chance: it’s now tightly integrated within the usual PhysX library.

By default everything runs on the CPU as usual. But with just a few parameters to change in the scene descriptor, things can now run on the GPU instead.

Reminder: there is no binary release anymore. You must build the code yourself (*). To get access to the source code, follow the instructions here.

After that, you get access to regular GitHub repositories for either PhysX 3.3, or now for PhysX 3.4.

Note: the links will show a 404-error until you get a registered account.

(*) EDIT: except for the GPU DLL, which is only shipped as binary for now.

shopfr.org cialis