Something that the documentation does not mention, and I have had to learn the hard way, is that Rest
, Custom
and Pose
are all relative offsets to their parent bone’s transform. The reason the snippet of code you posted is not working is because it will just compare the difference between the offsets for each rest position, ultimately telling you the difference in length between each bone’s parent, if that makes sense.
To get the lengths between the bones, you will need to take the local poses and convert them to global poses. In Godot 4.0, there will be a handy function to help with this, but for now, you’ll need to make a GDScript version to perform this conversion. The following code will take a local pose and convert it to a global pose:
Transform Skeleton3D::global_pose_to_local_pose(int p_bone_idx, Transform p_global_pose) {
if (bones[p_bone_idx].parent >= 0) {
int parent_bone_idx = bones[p_bone_idx].parent;
Transform conversion_transform = (bones[parent_bone_idx].pose_global * bones[p_bone_idx].rest);
return conversion_transform.affine_inverse() * p_global_pose;
} else {
return p_global_pose;
}
}
Transform Skeleton3D::local_pose_to_global_pose(int p_bone_idx, Transform p_local_pose) {
if (bones[p_bone_idx].parent >= 0) {
int parent_bone_idx = bones[p_bone_idx].parent;
Transform conversion_transform = (bones[parent_bone_idx].pose_global * bones[p_bone_idx].rest);
return conversion_transform * p_local_pose;
} else {
return p_local_pose;
}
}
The code above is in C++ though, so you’ll need to convert it to GDScript. Then, once converted, you can compare the two transform's origins to get the distance between the bones. :smile:
Just keep in mind, this is the just the global poses, not the global positions in the scene. Another conversion step is needed to take global poses and convert them to global positions, like those seen in Spatial nodes.
Any help is more than welcome, to be honest dealing with bones right now in Godot is a nightmare, it lacks an easy way to control bones programmatically, for instance in Unity you just manipulate Transforms as bones making life so much easier.
Agreed! I'm working on making this easier as part of the GSoC, along with new IK options, but it still will not be as straightforward as Unity. I was going to make a Bone3D node to help with this, but Juan/Reduz was heavily against the idea and so it had to be dropped from the proposal.
I am working on making functions to make the conversions easier and more straightforward, so I'm hoping that will help make direct bone manipulation less of a hassle in Godot moving forward.