I have a problem with my class derived from FAnimNode_SkeletalControlBase: I set rotation of all the bones in mannequin in EvaluateSkeletalControl_AnyThread method. However FBoneTransform holds also a position so I think that’s why UE4 ignores bones’ restrictions and sets position of each bone to 0,0,0.
This is is my code:
void FAnimNode_SensoAnimate::SetBoneTransform(const FTransform & ComponentTransform, FCSPose<FCompactPose> & Pose, const FBoneReference & Bone, const SAvatarSensor & SensorData, TArray<FBoneTransform> & OutTransforms, FQuat *StartRotation)
{
const FBoneContainer& BoneContainer = Pose.GetPose().GetBoneContainer();
auto CompactPoseBoneToModify = Bone.GetCompactPoseIndex(BoneContainer);
auto NewBoneTM = Pose.GetComponentSpaceTransform(CompactPoseBoneToModify);
const FQuat sensoQuat(-SensorData.data.rotation.z, -SensorData.data.rotation.y, -SensorData.data.rotation.x, SensorData.data.rotation.w);
// Convert to Bone Space.
FAnimationRuntime::ConvertCSTransformToBoneSpace(ComponentTransform, Pose, NewBoneTM, CompactPoseBoneToModify, BCS_BoneSpace);
NewBoneTM.SetRotation(sensoQuat);
// Convert back to Component Space.
FAnimationRuntime::ConvertBoneSpaceTransformToCS(ComponentTransform, Pose, NewBoneTM, CompactPoseBoneToModify, BCS_BoneSpace);
OutTransforms.Add(FBoneTransform(CompactPoseBoneToModify, NewBoneTM));
}
void FAnimNode_SensoAnimate::EvaluateSkeletalControl_AnyThread(FComponentSpacePoseContext& Output, TArray < FBoneTransform > & OutBoneTransforms)
{
check(OutBoneTransforms.Num() == 0);
const FBoneContainer& RequiredBones = Output.AnimInstanceProxy->GetRequiredBones();
if (sensoLib->GetMyAvatar(&avatar))
{
FTransform ComponentTransform = Output.AnimInstanceProxy->GetComponentTransform();
if (PelvisBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, PelvisBone, avatar.sensorsData[AVATAR_PELVIS], OutBoneTransforms, &m_pelvisStartRotation);
if (SpineBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, SpineBone, avatar.sensorsData[AVATAR_SPINE], OutBoneTransforms, &m_spineStartRotation);
if (NeckBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, NeckBone, avatar.sensorsData[AVATAR_NECK], OutBoneTransforms, &m_neckStartRotation);
if (HipLeftBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, HipLeftBone, avatar.sensorsData[AVATAR_HIP_LEFT], OutBoneTransforms, &m_hipLeftStartRotation);
if (KneeLeftBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, KneeLeftBone, avatar.sensorsData[AVATAR_KNEE_LEFT], OutBoneTransforms, &m_kneeLeftStartRotation);
if (FootLeftBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, FootLeftBone, avatar.sensorsData[AVATAR_FOOT_LEFT], OutBoneTransforms, &m_footLeftStartRotation);
if (HipRightBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, HipRightBone, avatar.sensorsData[AVATAR_HIP_RIGHT], OutBoneTransforms, &m_hipRightStartRotation);
if (KneeRightBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, KneeRightBone, avatar.sensorsData[AVATAR_KNEE_RIGHT], OutBoneTransforms, &m_kneeRightStartRotation);
if (FootRightBone.IsValidToEvaluate(RequiredBones))
SetBoneTransform(ComponentTransform, Output.Pose, FootRightBone, avatar.sensorsData[AVATAR_FOOT_RIGHT], OutBoneTransforms, &m_footRightStartRotation);
}
}
The result:
Thanks in advance!