Jump to content

[SOLVED] 2.21 Post-Animation bone adjustment


photo

Recommended Posts

Posted

I'm trying to adjust bone position/scale using the new ObjectMeshSkinned in 2.21 after all animation is calculated in the Animation graph.  I've read through the updated API docs and it seems the best way to do this would be to access the base pose layer in the NodeSkeletonPose, however despite trying various variations I cannot seem to edit the bone position/scale afterward, all animation seems locked to what comes out of the graph.  Below is the code I've been attempting, which I'm running in PostUpdate() (though I have also tried it in other Update() functions as well)... do you have any advice on best practices here?

 

            public NodeSkeletonPose skeletonAnimation;


                    // Reference Skeleton
                    SkeletonPoseDecomposed pose = new SkeletonPoseDecomposed();
                    pose.Skeleton = skeletonAnimation.Skeleton; 

                    // Pull from the LAYER, not the final Pose
                    skeletonAnimation.GetLayerPose(0, pose);

                    int boneIndex = skeletonAnimation.Skeleton.FindJoint("head");
                    if (boneIndex != -1)
                    {
                        // Get, Modify, and Re-Set
                        FloatTransform poseTransform = pose.GetTransform(boneIndex);
                        
                        poseTransform.position += new vec3(0f, 0f, 2.5f);
                        poseTransform.scale = new vec3(2.5f, 2.5f, 2.5f);

                        pose.SetTransform(boneIndex, poseTransform);
                    }

                    // Push back to the layer
                    skeletonAnimation.SetLayerPose(0, pose);
                    
                    // Recalculate world transforms for the renderer
                    skeletonAnimation.ForceApplyPose();
 

 

Posted

Hello.

Layers are internal data of the animation graph. When a graph is assigned to NodeSkeletonPose, modifying layers externally won't work correctly:

  1. In Update: the graph will overwrite your values during its own update.
  2. In PostUpdate: the final pose has already been computed from the layers, so layer changes will have no effect.

For manual corrections after the graph has run, use the following methods in PostUpdate to directly access the joints of the final pose:

  1. SetJointTransform / GetJointTransform
  2. SetJointPosition / GetJointPosition
  3. SetJointRotation / GetJointRotation
  4. SetJointScale / GetJointScale

All of them operate on local transforms of the final pose joints. After making changes, call ForceApplyPose() to update skinning for all objects in the hierarchy.

Here is a small example:

void PostUpdate()
{
	// get local transform of the head joint from the final pose
	mat4 headLocalTransform = skeletonPose.GetJointTransform(headJoint);
	// compute object-space transform by traversing parent chain
	mat4 headObjectTransform = GetJointObjectSpaceTransform(headJoint);

	// convert target position to the joint's local space
	vec3 targetLocalPosition = MathLib.Inverse(headObjectTransform) * targetObjectPosition;

	// compute rotation from current direction to target
	vec3 currentDirection = new vec3(headLocalTransform.AxisZ);
	vec3 targetDirection = MathLib.Normalize(targetLocalPosition - headLocalTransform.Translate);
	quat diff = MathLib.RotationFromTo(currentDirection, targetDirection);

	// apply rotation to the local transform
	headLocalTransform = headLocalTransform * MathLib.Rotate(diff);
	skeletonPose.SetJointTransform(headJoint, headLocalTransform);

	// update skinning
	skeletonPose.ForceApplyPose();
}

mat4 GetJointObjectSpaceTransform(int joint)
{
	mat4 t = skeletonPose.GetJointTransform(joint);
	int jointParent = skeletonPose.Skeleton.GetJointParent(joint);
	while (jointParent != -1)
	{
		t = skeletonPose.GetJointTransform(jointParent) * t;
		jointParent = skeletonPose.Skeleton.GetJointParent(jointParent);
	}
	return t;
}

 

  • Like 1
Posted

Thank you so much, this is extremely helpful, and works just as you suggested!

  • silent changed the title to [SOLVED] 2.21 Post-Animation bone adjustment
×
×
  • Create New...