Hi Geoff, thanks for the reply.
I traced the code a bit and I think I’ve found the issue.
In
void FPBDIslandManager::ProcessSleep(const FRealSingle Dt)
It will only process island sleep if Island->Flags.bIsSleepAllowed is set to true, which it does every frame with this comment:
// This gets set to false again next tick if there are moving kinematics in the island Island->Flags.bIsSleepAllowed = true;
Next in here:
void FPBDIslandManager::UpdateGraphNode(FPBDIslandParticle* Node)
It looks like it will not allow the island to sleep if the particle is moving. This is the test to determine if the particle is moving:
bool IsParticleMoving(const FGeometryParticleHandle* Particle)
It looks like there are a few kinematic spheres in position mode (I don’t know what they are to be honest, as they are not associated with any bone and the debug names are empty)
And to check if the sphere is moving it checks if the delta between the target and the particle position is non-zero:
// For kinematic particles check whether their current mode and target will cause the particle to move // For all other modes (Velocity, None and Reset) check that the velocity is non-zero const FKinematicGeometryParticleHandle* Kinematic = Particle->CastToKinematicParticle(); const FKinematicTarget& KinematicTarget = Kinematic->KinematicTarget(); if (KinematicTarget.GetMode() == EKinematicTargetMode::Position) { bIsStationary = (Kinematic->GetX() - KinematicTarget.GetPosition()).IsZero() && (Kinematic->GetRf() * KinematicTarget.GetRotation().Inverse()).IsIdentity(); } else { bIsStationary = Kinematic->GetV().IsZero() && Kinematic->GetW().IsZero(); }
These spheres then prevent the entire island to go to sleep. I double checked the actual delta and it looks very small. Perhaps we just need some sort of threshold here?
Kind regards,
Ben