Hi Sergio, thanks for attaching the repro project. That made it easier to track down what’s going wrong here.
The problem is in how we’re accumulating the mesh space transforms for the two blend pose buffers. If you take a look in the non-ISPC code you’ll see that we do this:
for (const FCompactPoseBoneIndex BoneIndex : BasePose.ForEachBoneIndex())
{
const int32 PoseIndex = BoneBlendWeights[BoneIndex.GetInt()].SourceIndex;
const FCompactPoseBoneIndex ParentIndex = BoneContainer.GetParentBoneIndex(BoneIndex);
if (ParentIndex != INDEX_NONE)
{
AccumulateMeshSpaceRotation(PoseIndex, BoneIndex, SourceRotations[ParentIndex], TargetRotations[ParentIndex]);
}
else
{
AccumulateMeshSpaceRotation(PoseIndex, BoneIndex, FQuat::Identity, FQuat::Identity);
}
And looking at AccumulateMeshSpaceRotation, it does this:
auto AccumulateMeshSpaceRotation = [&](int32 PoseIndex, FCompactPoseBoneIndex BoneIndex, const FQuat& ParentSourceRotation, const FQuat& ParentTargetRotation)
{
SourceRotations[BoneIndex] = ParentSourceRotation * BasePose[BoneIndex].GetRotation();
TargetRotations[PoseIndex][BoneIndex] = ParentTargetRotation * BlendPoses[PoseIndex][BoneIndex].GetRotation();
};
So although we have two blend pose buffers that need to be accumulated into mesh space, we are accumulating them into a single TargetRotations buffer, intermingling transforms from the two buffers. Obviously, that isn’t going to give valid results in mesh space since part of the pose will come from one buffer and part from the other.
The reason that you saw a difference in behaviour when setting the blend weight to 0 is that, like you already noticed, when that’s the case, we use the ref pose as that blend pose buffer. When that is accumulated in this way with bones from the other blend pose, we get a different result from when the weight is 0.1 as we’re then accumulating with different transforms.
To fix this, I think we need to accumulate both blend pose buffers into mesh space first, then use the relevant pose index for each bone to determine which target rotation we should be blending to. I have something working locally that does this, but it’s not particularly efficient. I’m going to try and talk with the dev team tomorrow to see if there is anything more sophisticated that we could be doing. Updating the ISPC code may also be a bit tricky.
I’ll update you again once I have more info.