-
-
Notifications
You must be signed in to change notification settings - Fork 23.6k
Add Deterministic option to IterateIK3D #112524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
fire
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reviewed the enhancement a little.
| float rot_axis_length = (global_pose.origin - parent_global_pose.origin).length() * 0.2; // Use 20% of the bone length for the rotation axis vector. | ||
| Vector3 axis = global_pose.basis.xform(axis_vector.normalized()) * rot_axis_length; | ||
| draw_line(surface_tool, global_pose.origin - axis, global_pose.origin + axis, bone_color); | ||
| float rot_axis_length = bone_vector.length() * 0.2; // Use 20% of the bone length for the rotation axis vector. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there some reasoning behind the 20% magic constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This review should be sent #111815, though there's no particular reason. I suppose it could be set as a fixed value by the EditorSetting.
FYI, the changes added to the behavior in this PR are only below; As explained, it simply resets the state before iteration.
void IterateIK3D::_init_joints(Skeleton3D *p_skeleton, int p_index) {
IterateIK3DSetting *setting = iterate_settings[p_index];
if (!setting) {
return;
}
cached_space = p_skeleton->get_global_transform_interpolated();
if (setting->simulation_dirty) {
_clear_joints(p_index);
setting->init_joints(p_skeleton, mutable_bone_axes);
setting->simulation_dirty = false;
} else if (deterministic) {
setting->init_joints(p_skeleton, mutable_bone_axes); // <- Here.
}
If deterministic option is
true, the previous frame's result is discarded. At this point, the new result is calculated from the bone pose excluding the IterateIK3D as the initial state. This means the result will be always equal as long as the target position and the previous bone pose are the same. However, ifangular_delta_limitandmax_iterationsare set too small, the end bone of the chain will never reach the target.Setting deterministic option is
trueandangular_delta_limitto 180 degrees will produce the same results as the old SkeletonIK in FABRIK.Deterministic FABRIK3D:

Old SkeletonIK3D:

(As I mentioned in #110120 (comment), the handling of Tips differs)