1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-07 12:30:27 +00:00

Fixes the SkeletonIK twisting issue by using the skeleton global pose without overrides

(cherry picked from commit c1bc87ed0d)
This commit is contained in:
TwistedTwigleg
2021-04-27 17:56:19 -04:00
committed by Rémi Verschelde
parent feaf4e6207
commit e9c8889ae8
4 changed files with 78 additions and 106 deletions

View File

@@ -243,65 +243,56 @@ void Skeleton::_notification(int p_what) {
Bone &b = bonesptr[order[i]];
if (b.global_pose_override_amount >= 0.999) {
b.pose_global = b.global_pose_override;
} else {
if (b.disable_rest) {
if (b.enabled) {
Transform pose = b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global * pose;
} else {
b.pose_global = pose;
}
} else {
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global;
} else {
b.pose_global = Transform();
}
if (b.disable_rest) {
if (b.enabled) {
Transform pose = b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global * pose;
b.pose_global_no_override = bonesptr[b.parent].pose_global_no_override * pose;
} else {
b.pose_global = pose;
b.pose_global_no_override = pose;
}
} else {
if (b.enabled) {
Transform pose = b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
} else {
b.pose_global = b.rest * pose;
}
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global;
b.pose_global_no_override = bonesptr[b.parent].pose_global_no_override;
} else {
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global * b.rest;
} else {
b.pose_global = b.rest;
}
b.pose_global = Transform();
b.pose_global_no_override = Transform();
}
}
if (b.global_pose_override_amount >= CMP_EPSILON) {
b.pose_global = b.pose_global.interpolate_with(b.global_pose_override, b.global_pose_override_amount);
} else {
if (b.enabled) {
Transform pose = b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
b.pose_global_no_override = bonesptr[b.parent].pose_global_no_override * (b.rest * pose);
} else {
b.pose_global = b.rest * pose;
b.pose_global_no_override = b.rest * pose;
}
} else {
if (b.parent >= 0) {
b.pose_global = bonesptr[b.parent].pose_global * b.rest;
b.pose_global_no_override = bonesptr[b.parent].pose_global_no_override * b.rest;
} else {
b.pose_global = b.rest;
b.pose_global_no_override = b.rest;
}
}
}
if (b.global_pose_override_amount >= CMP_EPSILON) {
b.pose_global = b.pose_global.interpolate_with(b.global_pose_override, b.global_pose_override_amount);
}
if (b.global_pose_override_reset) {
b.global_pose_override_amount = 0.0;
}
@@ -405,6 +396,13 @@ Transform Skeleton::get_bone_global_pose(int p_bone) const {
return bones[p_bone].pose_global;
}
Transform Skeleton::get_bone_global_pose_no_override(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
if (dirty)
const_cast<Skeleton *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
return bones[p_bone].pose_global_no_override;
}
// skeleton creation api
void Skeleton::add_bone(const String &p_name) {
@@ -885,6 +883,7 @@ void Skeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton::clear_bones_global_pose_override);
ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton::set_bone_global_pose_override, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_bone_global_pose", "bone_idx"), &Skeleton::get_bone_global_pose);
ClassDB::bind_method(D_METHOD("get_bone_global_pose_no_override", "bone_idx"), &Skeleton::get_bone_global_pose_no_override);
ClassDB::bind_method(D_METHOD("get_bone_custom_pose", "bone_idx"), &Skeleton::get_bone_custom_pose);
ClassDB::bind_method(D_METHOD("set_bone_custom_pose", "bone_idx", "custom_pose"), &Skeleton::set_bone_custom_pose);