improve the virtual hand model animation

This commit is contained in:
Mamadou Babaei
2023-03-28 10:39:48 +02:00
parent b8199b902c
commit c9acdc614d
4 changed files with 113 additions and 20 deletions
@@ -93,8 +93,10 @@ void FSGVirtualHandAnimInstanceProxy::PreEvaluateAnimation(UAnimInstance* InAnim
return;
}
BonesRotations.Empty();
BonesRotations = Hand->GetFingersBonesRotations();
// BonesRotations.Empty();
// BonesRotations = Hand->GetFingersBonesRotations();
BonesTransforms.Empty();
BonesTransforms = Hand->GetFingersBonesTransforms();
}
bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
@@ -123,16 +125,20 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
return FAnimInstanceProxy::Evaluate(Output);
}
FComponentSpacePoseContext PoseContext(this);
// TODO
// Necessary?
Output.ResetToRefPose();
FComponentSpacePoseContext PoseContext(Output.AnimInstanceProxy);
PoseContext.Pose.InitPose(Output.Pose);
for (const TTuple<FName, FRotator>& Bone: BonesRotations)
for (const TTuple<FName, FTransform>& Bone: BonesTransforms)
{
FName BoneName(Bone.Key);
FRotator BoneRotation(Bone.Value);
FTransform BoneTransform(Bone.Value);
const int32 BoneIndex = GetRequiredBones().GetPoseBoneIndexForBoneName(BoneName);
ensureAlwaysMsgf(BoneIndex != INDEX_NONE, TEXT("Invalid BoneIndex!"));
ensureAlwaysMsgf(BoneIndex != INDEX_NONE, TEXT("Invalid finger bone index!"));
FBoneReference BoneReference;
BoneReference.BoneName = MoveTemp(BoneName);
@@ -141,11 +147,13 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
FAnimNode_ModifyBone BoneController;
BoneController.BoneToModify = MoveTemp(BoneReference);
BoneController.Rotation = BoneTransform.Rotator();
BoneController.RotationMode = EBoneModificationMode::BMM_Replace;
BoneController.RotationSpace = EBoneControlSpace::BCS_ParentBoneSpace;
BoneController.Rotation = MoveTemp(BoneRotation);
BoneController.ScaleMode = EBoneModificationMode::BMM_Ignore;
BoneController.TranslationMode = EBoneModificationMode::BMM_Ignore;
if (BoneController.IsValidToEvaluate(HandSkeleton, PoseContext.Pose.GetPose().GetBoneContainer()))
if (BoneController.IsValidToEvaluate(HandSkeleton, Output.Pose.GetBoneContainer()))
{
TArray<FBoneTransform> BoneTransforms;
BoneController.EvaluateSkeletalControl_AnyThread(PoseContext, BoneTransforms);
@@ -153,11 +161,6 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
const TArray<FBoneTransform>::SizeType BoneTransformsNum = BoneTransforms.Num();
if (BoneTransformsNum > 0)
{
const FCompactPoseBoneIndex PoseBoneIndex{
BoneController.BoneToModify.GetCompactPoseIndex(
PoseContext.Pose.GetPose().GetBoneContainer())
};
PoseContext.Pose.LocalBlendCSBoneTransforms(BoneTransforms, 1.0f);
PoseContext.Pose.ConvertComponentPosesToLocalPoses(PoseContext.Pose, Output.Pose);
@@ -380,17 +380,105 @@ TMap<FName, FRotator> ASGVirtualHand::GetFingersBonesRotations()
for (int32 JointIndex = 0; JointIndex < FingerJointAngles.Num(); ++JointIndex)
{
const FVector& FingerJointAngle{FingerJointAngles[JointIndex]};
FRotator RefBoneRotation{GetFingerBoneRefRotation(FingerIndex, JointIndex)};
// const FVector& FingerJointAngle{FingerJointAngles[JointIndex]};
// FRotator RefBoneRotation{GetFingerBoneRefRotation(FingerIndex, JointIndex)};
// FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
// FRotator BoneRotation{(RefBoneRotation.Vector() + FingerJointAngle).Rotation()};
// Rotations.Emplace(MoveTemp(BoneName), MoveTemp(BoneRotation));
// const FVector& FingerJointAngle{FingerJointAngles[JointIndex]};
// FQuat FingerJointQuat(FingerJointAngle.Rotation().Quaternion());
//
// FRotator RefBoneRotation{GetFingerBoneRefRotation(FingerIndex, JointIndex)};
// FQuat RefBoneQuat(RefBoneRotation.Quaternion());
//
// FQuat BoneWorldQuat{FingerJointQuat * RefBoneQuat};
//
// FRotator BoneRotation{BoneWorldQuat.Rotator()};
//
// FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
// Rotations.Emplace(MoveTemp(BoneName), MoveTemp(BoneRotation));
//
// const FVector& FingerJointAngle{FingerJointAngles[JointIndex]};
// const FTransform& RefBoneTransform{GetFingerBoneRefTransform(FingerIndex, JointIndex)};
// // const FVector ComponentSpaceVector{RefBoneTransform.TransformPosition(FingerJointAngle)};
// FQuat ComponentSpaceQuat = RefBoneTransform.GetRotation() * FingerJointAngle.Rotation().Quaternion();
// FRotator BoneRotation{ComponentSpaceQuat.Rotator()};
// FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
// Rotations.Emplace(MoveTemp(BoneName), MoveTemp(BoneRotation));
// const FVector& FingerJointAngle{FingerJointAngles[JointIndex]};
// const FTransform& RefBoneTransform{GetFingerBoneRefTransform(FingerIndex, JointIndex)};
//
// FVector BoneSpaceVector = RefBoneTransform.InverseTransformPosition(FingerJointAngle);
// FRotator BoneSpaceRotator = BoneSpaceVector.Rotation();
// FRotator BoneRotation = RefBoneTransform.Rotator().RotateVector(BoneSpaceRotator.Vector()).Rotation();
//
// FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
//
// SGLOG(BoneName, FingerJointAngle, BoneRotation, BoneSpaceRotator);
//
// Rotations.Emplace(MoveTemp(BoneName), MoveTemp(BoneSpaceRotator));
const FVector& JointAngle{FMath::RadiansToDegrees(FingerJointAngles[JointIndex])};
const FQuat JointRotation{FQuat::MakeFromEuler(JointAngle)};
const FTransform& BoneRefTransform{GetFingerBoneRefTransform(FingerIndex, JointIndex)};
FQuat NewBoneRotation{BoneRefTransform.GetRotation() * JointRotation};
FTransform NewBoneTransform{BoneRefTransform};
NewBoneTransform.SetRotation(NewBoneRotation);
FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
FRotator BoneRotation{(RefBoneRotation.Vector() + FingerJointAngle).Rotation()};
Rotations.Emplace(MoveTemp(BoneName), MoveTemp(BoneRotation));
SGLOG(BoneName, JointRotation.Rotator(), BoneRefTransform.Rotator(), NewBoneTransform.Rotator());
Rotations.Emplace(MoveTemp(BoneName), MoveTemp(NewBoneRotation));
}
}
return MoveTemp(Rotations);
}
TMap<FName, FTransform> ASGVirtualHand::GetFingersBonesTransforms()
{
TMap<FName, FTransform> Transforms;
const USGHandPose* HandPose = GetHandPose();
if (!IsValid(HandPose))
{
return MoveTemp(Transforms);
}
const TArray<TArray<FVector>> HandAngles = HandPose->GetHandAngles();
for (int32 FingerIndex = 0; FingerIndex < HandAngles.Num(); ++FingerIndex)
{
const TArray<FVector>& FingerJointAngles = HandAngles[FingerIndex];
for (int32 JointIndex = 0; JointIndex < FingerJointAngles.Num(); ++JointIndex)
{
const FVector& JointAngle{FMath::RadiansToDegrees(FingerJointAngles[JointIndex])};
const FQuat JointRotation{FQuat::MakeFromEuler(JointAngle)};
const FTransform& BoneRefTransform{GetFingerBoneRefTransform(FingerIndex, JointIndex)};
FQuat NewBoneRotation{JointRotation * BoneRefTransform.GetRotation()};
FTransform NewBoneTransform{BoneRefTransform};
NewBoneTransform.SetRotation(NewBoneRotation);
FName BoneName{GetFingerBoneName(FingerIndex, JointIndex)};
SGLOG(BoneName, JointRotation.Rotator(), BoneRefTransform.Rotator(), NewBoneTransform.Rotator());
Transforms.Emplace(MoveTemp(BoneName), MoveTemp(NewBoneTransform));
}
}
return MoveTemp(Transforms);
}
ASGVirtualHand::FImpl::FImpl(ASGVirtualHand* InOwner)
: Owner(InOwner)
{
@@ -47,7 +47,8 @@ struct SENSEGLOVE_API FSGVirtualHandAnimInstanceProxy : public FAnimInstanceProx
GENERATED_USTRUCT_BODY()
public:
TMap<FName, FRotator> BonesRotations;
//TMap<FName, FRotator> BonesRotations;
TMap<FName, FTransform> BonesTransforms;
public:
FSGVirtualHandAnimInstanceProxy();
@@ -178,9 +178,10 @@ public:
public:
const FName& GetFingerBoneName(int32 Finger, int32 Joint) const;
const FTransform& GetFingerBoneRefTransform(int32 Finger, int32 Joint) const;
FRotator GetFingerBoneRefRotation(int32 Finger, int32 Joint) const;
FRotator GetFingerBoneRefRotation(int32 Finger, int32 Joint) const;
TMap<FName, FRotator> GetFingersBonesRotations();
TMap<FName, FTransform> GetFingersBonesTransforms();
};