I am running into an issue where rigid bodies attached to a ragdolls not falling asleep properly even if their linear speeds dropping below the thresholds set in the physics material (with the ‘Sleep Linear Velocity Threshold’ parameter). Resulting in the rigid bodies never fully settle and continue on with jittery motion.
I am currently using the physics asset provided by Metahuman (m_tal_nrw_body_Physics) and calling SetAllBodiesBelowSimulatePhysics() to activate ragdoll.
After digging into it some more, it appears that rigid bodies with constraints are skipped entirely when performing the sleep tests:
void FPBDIslandManager::ProcessParticlesSleep(const FRealSingle Dt) { // Check the sleepiness of particles that are not in any islands. // @todo(chaos): this is very expensive because we have to search for a material in GetParticleSleepThresholds. // We should probably cache a particle's sleep (and disable) thresholds somewhere. TArray<FGeometryParticleHandle*> SleptParticles; TArray<FGeometryParticleHandle*> DisabledParticles; for (FTransientPBDRigidParticleHandle& Rigid : Particles.GetActiveDynamicMovingKinematicParticlesView()) { if (Rigid.IsDynamic() && !Rigid.IsInConstraintGraph())
This is intentional? are there other ways to put these rigid bodies to sleep?
Yes this is intentional. I am a little surprised that the function below this isn’t putting the whole island to sleep, but that could be due to the jittering you mention.
I’d suggest using a system approach for this (ie call through the ‘owner’ class) - there are functions such as USkeletalMeshComponent::IsAnyRigidBodyAwake and USkeletalMeshComponent::PutAllRigidBodiesToSleep which should help you.
Can you clarify on how USkeletalMeshComponent::IsAnyRigidBodyAwake() can help me? As far as I can tell the rigid bodies never got put to sleep because Chaos disables the code path for rigid bodies on the ragdoll (i.e. they are constrained). The only way I can think of is by externally monitoring the linear speeds of the bodies and then manually put the bodies to sleep, effectively doing the work ProcessParticlesSleep() is already doing.
Is it possible to put in a support ticket request for this? As ragdoll physics isn’t really usable feature out of the box if it’s struggling to come to a settle.
On reflection you are correct, in this case that function likely won’t help you. Chaos disables the code path for a _single_ rigid body with a constraint, it would turn off an inactive island. The idea of monitoring linear speeds is reasonable enough - the other way you could do it is to monitor movement within an area, and if it doesn’t exceed a tolerance (ie X stays between 9.95 and 10.05 for 2 seconds) value in all 6 degrees of freedom then it can be put to sleep - that is used sometimes specifically for jitter in physics.
I have taken a look at the default manny and you are correct it doesn’t settle as standard, I’ll reach out dev wise to see if this is known and what the expectations are for an example asset.
I’m unsure what happened yesterday, but I can confirm that the default manny physics asset does in fact go to sleep (as does another project I am looking at in 5.4). I’ve looked at the code path and it is as suspected the Island sleep which is controlling that behaviour.
This means that the issue you have is not the same. I’d suspect a physics asset setup. From what you said this is a default one we use with metahuman? Could you ping me across a repro project in a default version of our engine so we can investigate please?
‘m_med_nrw_body_Physics’ is the physics asset under ‘Content\MetaHumans\Common\Male\Medium\NormalWeight\Body’
interestingly enough…the ragdoll does settle in the physics asset editor, but it would start jittering again when the mouse cursor is in the viewport, perhaps it’s caused by any slight variance in framerate?
I’ve taken a look and there is a definite setup difference between the normal manny type physics asset and the one you are using. It looks like most of the constraints have been left as default settings which won’t resemble how joints actually move, so the character just crumples on a heap. This will affect convergence a lot since there is now a large interconnected pile of bodies folded around each other - that is terrible for convergence (which is needed for an island to sleep).
I’ll raise this as an issue on a public bug tracker, and post back here. In the meantime you can improve the stability by copying across some more sensible joint settings from the default manny physics asset.
I’ve followed your advice and tried out the default Manny asset, and unfortunately it’s exhibiting the exact same symptoms I’ve described here:
interestingly enough…the ragdoll does settle in the physics asset editor, but it would start jittering again when the mouse cursor is in the viewport, perhaps it’s caused by any slight variance in framerate?
I can see that in the Physics Asset editor. I’m unsure what is causing that - I’ll ask around. However does this settle in PIE since that is the important situation?
If you let it sleep (which may take a little while) then this will stop. You are correct that this is probably the dt getting a bit larger while processing the mouse events, which will affect the simulation.
If the simulation is that sensitive to dt being different, that does reinforce the need of having the ability to specify a custom threshold to allow the physics bodies to go to sleep - presumably once the bodies are asleep the unstable frame rate will no longer be a factor unless they are manually woken up again. If memory serves correctly this did used to be supported with PhysX and is no longer the case after the transition to Chaos.
As mentioned before, it would be really nice to have this as an out of the box feature, as I assume every project attempting to integrate ragdoll into the game will run into this issue at one point.
Correct, once asleep any variations will be irrelevant. Do you recall how the PhysX handled custom thresholds? Was it at the individual level, or island level?
To increase convergence and ensure sleep happens you can clip the maximum dt allowed, enable substepping, increase iterations in the solver if you need faster convergence.
Coming back to the earlier question though - does this happen in the game, or it is purely in a tool which is editor only?
I’m really struggling to see this on my end. I can get it in the editor, but not in game (although it can take upto 10 seconds in some cases). From chatting with the devs as well, and from what I’ve had in support wise, this is the first we’ve heard of this.
I was reflecting on this today, and if instability can be caused by the time changing even slightly in game, then I’d suggest you specifically alter the Physics Asset’s solver properties - this way any extra cost is localised.
[Image Removed]Initially I’d increase the Velocity solver counts from 2 to 4 and see if that fixes it.
UE4 won’t really help much in this case, this is a completely different physics engine, and they have completely different advantages and disadvantages. (As far as I can remember, Physx is a velocity based engine, we are a position based engine, so completely different in at least one major component).
here’s a similar issue that was reported, the response points to the solver being sensitive to variable framerates. [Content removed]
‘To increase convergence and ensure sleep happens you can clip the maximum dt allowed, enable substepping, increase iterations in the solver if you need faster convergence.’
can you elaborate on what exactly ‘convergence’ means? your comment seems to indicate that the ragdoll does come to a sleep eventually, is it based on some thresholds that are not exposed?
‘I can get it in the editor, but not in game (although it can take upto 10 seconds in some cases)’
The most common usage for ragdolls is probably death hit reactions, and it will look a bit silly if the dead body continues to twitch and jitter for that long.
I will try tweaking the solver iterations, and try enabling substepping and see if that helps. If ragdolls are still having trouble settling, is monitoring the speed of the bodies externally and putting them to sleep a viable option?
Apologies - certainly. Convergence is essentially when the physics gets the correct answer. Iterations is how many ‘refinements’ it can use to get the correct answer. In this case, the constraints and collisions are ‘fighting’ each other - so they don’t agree on the direction to move the body in overall. This is a very common issue in physics. You will be seeing this as the ‘jitter’ you mention.
When the ragdoll goes to sleep in the normal case it is from the ‘island sleep’ function in the physics. This uses the current state (linear and angular velocity) and compares it to a physics material sleep value. This is actually exposed and is where I’d probably look to try first. In PhysicsMaterial.h you can see a SleepLinearVelocity, SleepAngularVelocity and SleepCounterThreshold - all of these will find their way through to that function.
[Image Removed]
If you open that material up in editor you can see the values to alter.