Announcement

Collapse
No announcement yet.

C++ AnimGraph - Modify transform on array of bones

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    C++ AnimGraph - Modify transform on array of bones

    Hi all,

    i'm working on game from some times, and i switched to C++ because i need specifics customs functionnality.
    But thoses days i have a problem with modify an array of bones from my custom Anim Graph, let me explain:

    I want modify rotation many spine bones (an array of bones), thoses bones wil lcopy with RInterpTo the Effector bone (to do dynamic dragon snake tail interpolation).

    Like i see in source code for Transform Modify and Spline IK, the update it's writing in
    Code:
    EvaluateSkeletalControl_AnyThread
    The rotation work perfectly today, but the true problem it's about update Joint position from parent bone of each bone iteration.

    As i update an array of bones with the OutBoneTransforms FBoneTransform array, i think the component space don't enought update the new bone transformation as long as we are in the EvaluateSkeletalControl_AnyThread function. So we need to recalculate new Joint bone from parent bone.

    I'm insipired of SplineIk and TwoBoneIk to stuff it, but, there are things that escapes me (i have some many bugs with several try).
    Usually I find the solution shortly with Google Search and Documentation, but i don't find any solution in Forums and some web sites yet.

    Reference of TwoBoneIK.cpp who try to updtae joint post of LowerClimb :

    - https://github.com/EpicGames/UnrealE.../TwoBoneIK.cpp

    I saturate on these calculations, that's why I post here to have your lights / tips, can you help me please ? ^^

    Sorry for this long text to read !

    It's the update transform part code :

    Code:
    // Effect it's the head bone in this exemple
    FCompactPoseBoneIndex CompactEffectorPoseBoneToModify = Effector.GetCompactPoseIndex(BoneContainer);
    // -- used for read only
    const FTransform EffectorBoneTransform = Output.Pose.GetComponentSpaceTransform(CompactEffectorPoseBoneToModify);
    
    // Last bone transform (the parent of current bone in for each)
    FTransform InitialLastBoneTransform = EffectorBoneTransform;
    FTransform LastBoneTransform = EffectorBoneTransform;
    
    // For each child bone stored in my custom struct
    for(MyCachedBone& CurrentCachdBone : MyCachedBoneList)
    {
        // Get current compact bone to modify
        FCompactPoseBoneIndex CurrentCompactPoseBoneToModify = CurrentCachdBone.Bone.GetCompactPoseIndex(BoneContainer);
        // -- used for read only
        const FTransform CurrentBoneTransform = Output.Pose.GetComponentSpaceTransform(CurrentCompactPoseBoneToModify);
        // -- used for modification
        FTransform NewBoneTM = CurrentBoneTransform;
        FTransform ComponentTransform = Output.AnimInstanceProxy->GetComponentTransform();
    
        // =================================================
        // -- ROTATION PART
        // =================================================
        // Convert to Bone Space.
        FAnimationRuntime::ConvertCSTransformToBoneSpace(ComponentTransform, Output.Pose, NewBoneTM, CurrentCompactPoseBoneToModify, RotationSpace);
    
        // -- Update Rotation Transform
        const FQuat BoneQuat(NewRotation);
        NewBoneTM.SetRotation(BoneQuat);
    
        // Convert back to Component Space.
        FAnimationRuntime::ConvertBoneSpaceTransformToCS(ComponentTransform, Output.Pose, NewBoneTM, CurrentCompactPoseBoneToModify, RotationSpace);
    
        // =================================================
        // -- LOCATION PART
        // =================================================
         // Convert to Bone Space.
        FAnimationRuntime::ConvertCSTransformToBoneSpace(ComponentTransform, Output.Pose, NewBoneTM, CurrentCompactPoseBoneToModify, TranslationSpace);
    
        // -- Update Translation Transform
        FVector FinalJoinPos = LastBoneTransform.GetTranslation();
    
        // Calcul length of joint
        float BoneLength = (CurrentBoneTransform.GetTranslation() - InitialLastBoneTransform.GetTranslation()).Size();
    
        // -- TODO
        // will modify FinalJoinPos from some formula etc...
        // ... Some stuff ...
    
        // -- Apply final translation
        NewBoneTM.SetTranslation(FinalJoinPos);
    
        // Convert back to Component Space.
        FAnimationRuntime::ConvertBoneSpaceTransformToCS(ComponentTransform, Output.Pose, NewBoneTM, CurrentCompactPoseBoneToModify, TranslationSpace);
    
        // =================================================
        // -- Apply transform and update next var
        // =================================================
        // Apply nexw transform
        OutBoneTransforms.Add( FBoneTransform(BoneToModify.GetCompactPoseIndex(BoneContainer), NewBoneTM) );
    
        // Finally update last transform
        LastBoneTransform = NewBoneTM;
    
        // And update last initial bone transform for next child
        InitialLastBoneTransform = CurrentBoneTransform;
    }
    i would love to have your help,

    Best regards
    Last edited by D-Zak; 11-06-2019, 05:17 PM.

    #2
    Hi all,

    Finally with more tests and research, i found a Korean web site which use
    Code:
    Output.Pose.LocalBlendCSBoneTransforms(Transform, 1.0f);
    to keep offset for each bone !

    I don't need to set translation, can only use rotation transform in a foreach iterations from cached bone list

    S i don't use
    Code:
    OutBoneTransforms.Add(FBoneTransform(CompactCurrentPoseBoneToModify, NewBoneTM));
    but i write this for each iterations :

    Code:
           
            // Workaround ensure our rotations are offset for each bone
            CachedTransformList.Add(FBoneTransform(CachedBoneData.Bone.GetCompactPoseIndex(BoneContainer), NewBoneTM));
            Output.Pose.LocalBlendCSBoneTransforms(CachedTransformList, 1.0f);
            CachedTransformList.Reset();
    I share this for those who were in the same situation as me, hope that it helps you

    Have good days !

    Comment


      #3
      Can you share how you added your C++ code to be executed by the anim instance?
      EvaluateSkeletalControl_AnyThread is part of the anim nodes but how did you get it into the anim instance in C++?

      Thanks!

      Comment


        #4
        Hi !

        I just made Anim Graph Node in C++ but used in Blueprint. I have "AnimNode_DUTransformBone" and "DUAnimGraphNode_ModifyBone".

        If you want see the code i uploaded here for you: https://drive.google.com/open?id=1FK...2RLQYa5d7Zf4Dq

        Have a good days !

        Comment


          #5
          D-Zak Ah I see, thank you good sir!

          Comment

          Working...
          X