BoneIndex out of index after MasterBoneMap mapping

Core problems

In USkinnedMeshComponent::GetTypedSkinnedVertexPosition, it checks that it has the proper master pose component.

If it does, map the bone index to the index of master bones, like below:

int32 BoneIndex = Section.BoneMap[SrcSoftVertex->InfluenceBones[InfluenceIndex]];
if(MasterPoseComponentInst)
{		
    check(MasterBoneMap.Num() == SkeletalMesh->RefSkeleton.GetNum());
    BoneIndex = MasterBoneMap[BoneIndex];
}

after then, it access the ref bases inverse matrix and component space transforms to get the RefToLocal matrix:

const FMatrix RefToLocal = SkeletalMesh->RefBasesInvMatrix[BoneIndex] 
          * BaseComponent->GetComponentSpaceTransforms()[BoneIndex].ToMatrixWithScale();

At this point, the Mapped BoneIndex can exceed the number of SkeletalMesh’s RefBasesInvMatrix

Situations

Preparations

  • One character skeletal mesh with proper bone hierarchy.
  • One additional skeletal mesh with almost same bone hierarchy.
  • Character skeletal mesh has extra dummy bones which are not influence to the main bone hierarchy.

Setting up

  1. Import character skeletal mesh
  2. Import additional skeletal mesh with the same (using combobox)
  3. Set master pose of the additional mesh as Character skeletal mesh (in c++)
  4. When I call the GetSkinnedVertexPosition which calls the GetTypedSkinnedVertexPosition, It has crashed.

My solutions

Solution 1

I think, the index of RefBasesInvMatrix does not need to be mapped to the MasterBone’s one. So I just use the mapped bone index only for accessing Component space transforms of MasterPoseComponent.

int32 BoneIndex = Section.BoneMap[SrcSoftVertex->InfluenceBones[InfluenceIndex]];
int32 MappedIndex = BoneIndex;
if(MasterPoseComponentInst)
{
    check(MasterBoneMap.Num() == SkeletalMesh->RefSkeleton.GetNum());
    MappedIndex = MasterBoneMap[BoneIndex];
}
const FMatrix RefToLocal = SkeletalMesh->RefBasesInvMatrix[BoneIndex] 
          * BaseComponent->GetComponentSpaceTransforms()[MappedIndex].ToMatrixWithScale();

It seems that it resolved this problem. But I’m not quite sure I’ve corrected.

Solution 2

I’ve solved this with another way.

If the MasterPoseComponent is set, RefBasesInvMatrix also be used those of MasterPoseComponent. Look this:

const FMatrix RefToLocal = BaseComponent->RefBasesInvMatrix[BoneIndex] 
          * BaseComponent->GetComponentSpaceTransforms()[BoneIndex].ToMatrixWithScale();

I think it is more reasonable than the Solution1.

Requests

Whatever the solution is, If MasterPoseComponent must have the same hierarchy with those of target mesh, Engine should warn to us or leave some logs about this situation.

Testing version

I’ve tested this on UE4.13, but the part of code has no difference with UE4.15

1 Like

hello? anybody here?

Hey alleysark,

Can you provide some more details about the assets that you’ve got? Is ProperHeirarchySkelMesh sharing a with AlmostTheSameSkelMesh? I’m just a bit confused what your assets look like. Could be useful to include screenshots and give more details. Could also be useful to include the fbx files or an example project. If you’d like, you can attach those here or PM me or on the forums with a download link.

  • W.

Hi ,
I really appreciate your comment!

Sorry to say, those problematic FBXs are sort of private resources (of my company). So I just draw hierarchy of these skeletons.

This is a master .

And this is a slave .

The only different is that the master has some extra (red) bones.
These extra bones not affect to the transforms of main (black) bones.

Alleysark.

Hi Alleysark,

We believe we have a setup that matches your description.We have two skeletons, one with some extra bones. After setting the with extra bones as the Master , and the other as the slave, I was able to call GetSkinnedVertexPosition and retrieve the FVector for one of the vertices of the mesh without resulting in a crash.

Could you elaborate on how you are calling GetSkinnedVertexPosition? Also, would it be possible to get the callstack that you receive when the crash occurs?

Hi ,

I’ve explain that the Mapped BoneIndex can exceed the number of SkeletalMesh’s RefBasesInvMatrix. It means that it sometimes not exceed that range.

I have three slave meshes, two meshes are not exceed the bone index range, but the last one always exceed when I try to get skinned position.

And I sent you the problematic resources with crash reports. I hope this help you to reproduce this bug.

Thanks a lot!

Hi Alleysark,

Thank you for the sample assets. I was able to immediately reproduce the crash that you described using those assets in the same test I had attempted previously with the assets we had created to test this. I have entered UE-43935 to report this issue, and to have it investigated further.

If you are confident with the second possible solution that you mentioned in your original post, I would suggest submitting that fix as a Pull Request on GitHub. That is our preferred method for receiving bug fixes from our users, and I can make sure that gets linked to the ticket I entered for this issue.

Edit: I just wanted to point out that the ticket I entered had a test project attached to it that is only available internally. The test assets that you provided will not be publicly available.

I am really appreciate your treatment!

Honestly, the second possible solution will only work for the case that the master contains slave absolutely.

If master has extra bones which affects to the transforms of slave , It’ll mess up all the possible solutions.
It also could be a disaster if the slave has extra bones which are not involved in the hierarchy of master .

So, the possible solutions can be different relative to what the master and slave hierarchy policy be chosen.

Alleysark.

Side Note: There are two alternatives to Set Master Pose Component (we’re trying to steer people away from Master Pose). They are Poseable Meshes and using Copy Pose in an AnimBP. You can find a little more in-depth here.

  • W.