@@ -142,17 +142,18 @@ void SkeletonModification2DTwoBoneIK::_execute(float p_delta) {
142142 return ;
143143 }
144144
145- // Adopted from the links below:
145+ // Adapted from the links below:
146146 // http://theorangeduck.com/page/simple-two-joint
147147 // https://www.alanzucconi.com/2018/05/02/ik-2d-2/
148148 // With modifications by TwistedTwigleg
149149 Vector2 target_difference = target->get_global_position () - joint_one_bone->get_global_position ();
150150 float joint_one_to_target = target_difference.length ();
151151 float angle_atan = target_difference.angle ();
152152
153- float bone_one_length = joint_one_bone->get_length () * MIN (joint_one_bone->get_global_scale ().x , joint_one_bone->get_global_scale ().y );
154- float bone_two_length = joint_two_bone->get_length () * MIN (joint_two_bone->get_global_scale ().x , joint_two_bone->get_global_scale ().y );
153+ float bone_one_length = joint_one_bone->get_length () * MIN (joint_one_bone->get_global_scale ().abs (). x , joint_one_bone->get_global_scale (). abs ().y );
154+ float bone_two_length = joint_two_bone->get_length () * MIN (joint_two_bone->get_global_scale ().abs (). x , joint_two_bone->get_global_scale (). abs ().y );
155155 bool override_angles_due_to_out_of_range = false ;
156+ bool same_scale_sign = true ;
156157
157158 if (joint_one_to_target < target_minimum_distance) {
158159 joint_one_to_target = target_minimum_distance;
@@ -165,6 +166,10 @@ void SkeletonModification2DTwoBoneIK::_execute(float p_delta) {
165166 override_angles_due_to_out_of_range = true ;
166167 }
167168
169+ if (joint_one_bone->get_global_scale ().sign ().x != joint_one_bone->get_global_scale ().sign ().y ) {
170+ same_scale_sign = false ;
171+ }
172+
168173 if (!override_angles_due_to_out_of_range) {
169174 float angle_0 = Math::acos (((joint_one_to_target * joint_one_to_target) + (bone_one_length * bone_one_length) - (bone_two_length * bone_two_length)) / (2.0 * joint_one_to_target * bone_one_length));
170175 float angle_1 = Math::acos (((bone_two_length * bone_two_length) + (bone_one_length * bone_one_length) - (joint_one_to_target * joint_one_to_target)) / (2.0 * bone_two_length * bone_one_length));
@@ -177,12 +182,23 @@ void SkeletonModification2DTwoBoneIK::_execute(float p_delta) {
177182 if (std::isnan (angle_0) || std::isnan (angle_1)) {
178183 // We cannot solve for this angle! Do nothing to avoid setting the rotation (and scale) to NaN.
179184 } else {
180- joint_one_bone->set_global_rotation (angle_atan - angle_0 - joint_one_bone->get_bone_angle ());
185+ if (same_scale_sign) {
186+ joint_one_bone->set_global_rotation (angle_atan - angle_0 - joint_one_bone->get_bone_angle ());
187+ } else {
188+ joint_one_bone->set_global_rotation (angle_atan + angle_0 + joint_one_bone->get_bone_angle ());
189+ }
190+
181191 joint_two_bone->set_rotation (-Math::PI - angle_1 - joint_two_bone->get_bone_angle () + joint_one_bone->get_bone_angle ());
182192 }
193+
183194 } else {
184- joint_one_bone->set_global_rotation (angle_atan - joint_one_bone->get_bone_angle ());
185- joint_two_bone->set_global_rotation (angle_atan - joint_two_bone->get_bone_angle ());
195+ if (same_scale_sign) {
196+ joint_one_bone->set_global_rotation (angle_atan - joint_one_bone->get_bone_angle ());
197+ joint_two_bone->set_global_rotation (angle_atan - joint_two_bone->get_bone_angle ());
198+ } else {
199+ joint_one_bone->set_global_rotation (angle_atan + joint_one_bone->get_bone_angle ());
200+ joint_two_bone->set_global_rotation (angle_atan + joint_two_bone->get_bone_angle ());
201+ }
186202 }
187203
188204 stack->skeleton ->set_bone_local_pose_override (joint_one_bone_idx, joint_one_bone->get_transform (), stack->strength , true );
@@ -211,7 +227,8 @@ void SkeletonModification2DTwoBoneIK::_draw_editor_gizmo() {
211227 }
212228 stack->skeleton ->draw_set_transform (
213229 stack->skeleton ->to_local (operation_bone_one->get_global_position ()),
214- operation_bone_one->get_global_rotation () - stack->skeleton ->get_global_rotation ());
230+ operation_bone_one->get_global_rotation () - stack->skeleton ->get_global_rotation (),
231+ operation_bone_one->get_global_scale ());
215232
216233 Color bone_ik_color = Color (1.0 , 0.65 , 0.0 , 0.4 );
217234#ifdef TOOLS_ENABLED
0 commit comments