Skip to content

Commit

Permalink
Merge pull request #77469 from lyuma/skeleton_ik_roll_fix
Browse files Browse the repository at this point in the history
Fix for SkeletonIK3D interpolation and bone roll
  • Loading branch information
akien-mga committed Jun 6, 2023
2 parents e2fcc4d + 9aa46bf commit 2a1bc05
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 22 deletions.
2 changes: 1 addition & 1 deletion core/math/basis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ void Basis::rotate_to_align(Vector3 p_start_direction, Vector3 p_end_direction)
real_t dot = p_start_direction.dot(p_end_direction);
dot = CLAMP(dot, -1.0f, 1.0f);
const real_t angle_rads = Math::acos(dot);
set_axis_angle(axis, angle_rads);
*this = Basis(axis, angle_rads) * (*this);
}
}

Expand Down
22 changes: 1 addition & 21 deletions scene/3d/skeleton_ik_3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,26 +249,6 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform3D &p_invers
}
}

static Vector3 get_bone_axis_forward_vector(Skeleton3D *skeleton, int p_bone) {
// If it is a child/leaf bone...
if (skeleton->get_bone_parent(p_bone) > 0) {
return skeleton->get_bone_rest(p_bone).origin.normalized();
}
// If it has children...
Vector<int> child_bones = skeleton->get_bone_children(p_bone);
if (child_bones.size() == 0) {
WARN_PRINT_ONCE("Cannot calculate forward direction for bone " + itos(p_bone));
WARN_PRINT_ONCE("Assuming direction of (0, 1, 0) for bone");
return Vector3(0, 1, 0);
}
Vector3 combined_child_dir = Vector3(0, 0, 0);
for (int i = 0; i < child_bones.size(); i++) {
combined_child_dir += skeleton->get_bone_rest(child_bones[i]).origin.normalized();
}
combined_child_dir = combined_child_dir / child_bones.size();
return combined_child_dir.normalized();
}

void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) {
if (blending_delta <= 0.01f) {
// Before skipping, make sure we undo the global pose overrides
Expand Down Expand Up @@ -307,7 +287,7 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
new_bone_pose.origin = ci->current_pos;

if (!ci->children.is_empty()) {
Vector3 forward_vector = get_bone_axis_forward_vector(p_task->skeleton, ci->bone);
Vector3 forward_vector = (ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized();
// Rotate the bone towards the next bone in the chain:
new_bone_pose.basis.rotate_to_align(forward_vector, new_bone_pose.origin.direction_to(ci->children[0].current_pos));

Expand Down

0 comments on commit 2a1bc05

Please sign in to comment.