Download

Freezing Skeletal Mesh into Pose and toggling simulate physics

Hey everyone,

I’ve had moderate success in forcing a Skeletal Mesh into a specific pose when simulating (rather than fully rag-dolling).

I use the mesh’s existing physics body setup as a template to spawn a set of Constraint Components, which make each joint stick (softly) into the required pose.

Ideally, I’d like to get it fully rigid. This is the code i’ve come up with:



void AAICharacter::FreezePhysConstraintsInPose(FName ConstraintProfileName)
{
    auto constraintsCopy = GetMesh()->Constraints;

    for (int32 index = 0; index < constraintsCopy.Num(); index++)
    {
        auto constraint = constraintsCopy[index];

        if (!constraint) continue;

        FString constraintName(constraint->ConstraintBone1.ToString(), constraint->ConstraintBone2.GetStringLength() + 2);
        constraintName += "_";
        constraint->ConstraintBone2.AppendString(constraintName);

        if (auto newConstraintComponent = NewObject<UPhysicsConstraintComponent>(this, *constraintName))
        {
            newConstraintComponent->SetupAttachment(GetMesh());
            newConstraintComponent->SetWorldTransform(GetMesh()->GetSocketTransform(constraint->ConstraintBone1));
            newConstraintComponent->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Locked, 0.f);
            newConstraintComponent->SetAngularSwing2Limit(EAngularConstraintMotion::ACM_Locked, 0.f);
            newConstraintComponent->SetAngularTwistLimit(EAngularConstraintMotion::ACM_Locked, 0.f);
            newConstraintComponent->ConstraintInstance.ProfileInstance.TwistLimit.bSoftConstraint = false;
            newConstraintComponent->ConstraintInstance.ProfileInstance.ConeLimit.bSoftConstraint = false;
            newConstraintComponent->ConstraintInstance.ProfileInstance.TwistLimit.ContactDistance = 1.f;
            newConstraintComponent->ConstraintInstance.ProfileInstance.ConeLimit.ContactDistance = 1.f;
            newConstraintComponent->SetConstrainedComponents(
                GetMesh(),
                constraint->ConstraintBone1,
                GetMesh(),
                constraint->ConstraintBone2);
            newConstraintComponent->RegisterComponent();
        }
    }
}


I’ve uploaded a video, because it does look rather entertaining: https://youtu.be/sYKP41c9S10

I’ve attempted something that tries to Weld all the physics bodies in a skeletal mesh together, however I usually end up with some abstract art as a result (the mesh spazzes out rather spectacularly), code similar to below could run in the above loop, again using the existing constraints to know where things should stick:



ConstraintBody1->Weld(ConstraintBody2, ConstraintBody2->GetUnrealWorldTransform());


I’m fairly certain the ultimate solution will involve the physics welding, however, as well documented as the BodyInstance class actually is, the welding process is not so well documented. The core of the issue to me seems to be welding order, so the set of questions is:

  • Should Skeletal Mesh Bodies in the hierarchy be welded from leaves to root, or root to leaves?
  • Should Skeletal Mesh Bodies all be welded to a single parent (like the pelvis body, or, constructing a new one), or as above, per joint?
  • What transform should i feed in as the second parameter, going by the weld implementation it should be the second bodies world transform, but should it be?
  • Am I crazy and this won’t work?