diff --git a/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp b/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp index 156e5c7a..97fa2aed 100644 --- a/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp +++ b/Source/SenseGlove/Private/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.cpp @@ -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& Bone: BonesRotations) + for (const TTuple& 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 BoneTransforms; BoneController.EvaluateSkeletalControl_AnyThread(PoseContext, BoneTransforms); @@ -153,11 +161,6 @@ bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output) const TArray::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); diff --git a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHand.cpp b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHand.cpp index f071f07e..4e6dca87 100644 --- a/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHand.cpp +++ b/Source/SenseGlove/Private/SenseGlove/GameFramework/SGVirtualHand.cpp @@ -380,17 +380,105 @@ TMap 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 ASGVirtualHand::GetFingersBonesTransforms() +{ + TMap Transforms; + + const USGHandPose* HandPose = GetHandPose(); + if (!IsValid(HandPose)) + { + return MoveTemp(Transforms); + } + + const TArray> HandAngles = HandPose->GetHandAngles(); + + for (int32 FingerIndex = 0; FingerIndex < HandAngles.Num(); ++FingerIndex) + { + const TArray& 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) { diff --git a/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h b/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h index 469ae774..37bb2716 100644 --- a/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h +++ b/Source/SenseGlove/Public/SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h @@ -47,7 +47,8 @@ struct SENSEGLOVE_API FSGVirtualHandAnimInstanceProxy : public FAnimInstanceProx GENERATED_USTRUCT_BODY() public: - TMap BonesRotations; + //TMap BonesRotations; + TMap BonesTransforms; public: FSGVirtualHandAnimInstanceProxy(); diff --git a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHand.h b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHand.h index 6c88eee8..faac729f 100644 --- a/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHand.h +++ b/Source/SenseGlove/Public/SenseGlove/GameFramework/SGVirtualHand.h @@ -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 GetFingersBonesRotations(); + + TMap GetFingersBonesTransforms(); }; \ No newline at end of file