So I have a FCompactPose OutPose which holds a struct variable of it’s parent class FBaseCompactPose SourcePose.
In AnimNodeSequencePlayer::Evaluate_AnyThread(), I create an FBoneContainer which contains a TArray<FCompactPoseBoneIndex> SkeletonToCompactPose, which is essentially just an array of int32 representing each bone in a skeleton.
Upon initialization, it has the correct number of bones with correct indices. This FBoneContainer is then stored in OutPose.SourcePose
Next, GetAnimationPose(FCompactPose& OutPose) is called, which then calls GetBonePose(FCompactPose& OutPose).
In GetBonePose(FCompactPose& OutPose), a new const FBoneContainer& RequiredBones is set to equal OutPose.SourcePose.GetFBoneContainer().
In this case, in a skeleton with 80 bones FCompactPoseBoneIndex and SkeletonBoneIndex should both equal 0 up to 79. When the FBoneContainer is initialized this is true. But in AnimSequence::GetBonePose(FCompactPose& OutPose), FCompactPoseBoneIndex at SkeletonBoneIndex of 1 equals a random number in the 100s, once 714, another time 652. But only the value at the index of 1, all other indices are as they should be.
This is how it’s accessed:
const FCompactPoseBoneIndex BoneIndex = RequiredBones.GetCompactPoseIndexFromSkeletonIndex(SkeletonBoneIndex);
//Nasty, we break our type safety, code in the lower levels should be adjusted for this
const int32 CompactPoseBoneIndex = BoneIndex.GetInt();
UE_LOG(LogTemp, Warning, TEXT("CompactPoseBoneIndex: %d, SkeletonBoneIndex: %d. AnimSequence::GetBonePose()"), CompactPoseBoneIndex, SkeletonBoneIndex);
How could this single index, which isn’t even the very first index in the array, be changed but not the others?
The SourcePose variable in OutPose is not UPROPERTY(), so I thought maybe it might be getting garbage collected, but all the other values are saved and correct.
Any help is appreciated!
replacing RequiredBones with an FBoneContainer initialized in GetBonePose fixes the issue.
This is only a workaround though, I don’t want to be initializing a new bonecontainer each frame.
Unfortunately, const FBoneContainer& RequiredBones is a reference, so I can not call AddToRoot().
The only problem seems to lie in when it calls FCompactPoseBoneIndex::GetInt()
This is where I create the temporary FBoneContainer.
At the bottom &RequiredBones = refContainer
TArray<FBoneIndexType> refBones;
FBoneContainer refContainer;
if (GetSkeleton() && GetSkeleton()->IsUniversallyCompatible(GetSkeleton()))
{
USkeleton* AnimSourceSkeleton = GetSkeleton();
FReferenceSkeleton refSkel = GetSkeleton()->GetReferenceSkeleton();
int32 numBones = refSkel.GetNum();
refBones.Empty();
refBones.AddUninitialized(numBones);
//Hack, refBones uninitialized means each index equals some crazy number, or possibly just the first
for (int index = 0; index < refBones.Num(); ++index)
{
refBones[index] = index;
}
UE_LOG(LogTemp, Warning, TEXT("Num of RefBones: %d. AnimSequence::GetSourceBonePose()"), refBones.Num());
refContainer.InitializeTo(refBones, FCurveEvaluationOption(), *AnimSourceSkeleton);
const FReferenceSkeleton* containerSkel = &refContainer.GetReferenceSkeleton();
if (refContainer.GetAsset())
{
OutPose.SourcePose.SetBoneContainer(&refContainer);
OutPose.SourcePose.ResetToRefPose();
}
}
//Get SourcePose bone containers instead
const FBoneContainer& RequiredBones = OutPose.SourcePose.GetBoneContainer();
Then further down in the same function
// Handle root bone separately if it is track 0. so we start w/ Index 1.
for (int32 TrackIndex = (bFirstTrackIsRootBone ? 1 : 0); TrackIndex < NumTracks; TrackIndex++)
{
const int32 SkeletonBoneIndex = GetSkeletonIndexFromCompressedDataTrackIndex(TrackIndex);
// not sure it's safe to assume that SkeletonBoneIndex can never be INDEX_NONE
if (SkeletonBoneIndex != INDEX_NONE)
{
FCompactPoseBoneIndex BoneIndex = RequiredBones.GetCompactPoseIndexFromSkeletonIndex(SkeletonBoneIndex);
//This seems to be where the issue is, then it's drawn out below on BoneIndex.GetInt()
//But when BoneIndex = refContainer.GetCompacePose... The problem goes away.
if (refContainer.IsValid())
{
UE_LOG(LogTemp, Warning, TEXT("RefContainer.IsValid(). AnimSequence::GetSourceBonePose()"));
BoneIndex = refContainer.GetCompactPoseIndexFromSkeletonIndex(SkeletonBoneIndex);
}
//Nasty, we break our type safety, code in the lower levels should be adjusted for this
const int32 CompactPoseBoneIndex = BoneIndex.GetInt();
// It always starts on TrackIndex = 1, so I'm unsure if the element at index 0 is a crazy number like the element at index 1
UE_LOG(LogTemp, Warning, TEXT("CompactPoseBoneIndex: %d, SkeletonBoneIndex: %d. AnimSequence::GetSourceBonePose()"), CompactPoseBoneIndex, SkeletonBoneIndex);
if (CompactPoseBoneIndex != INDEX_NONE)
{
Thanks for helping, I’m learning as I’m going with programming