@@ -1498,6 +1498,7 @@ void SpringBoneSimulator3D::_init_joints(Skeleton3D *p_skeleton, SpringBone3DSet
14981498 setting->joints [i]->verlet ->prev_tail = setting->joints [i]->verlet ->current_tail ;
14991499 setting->joints [i]->verlet ->forward_vector = axis.normalized ();
15001500 setting->joints [i]->verlet ->length = axis.length ();
1501+ setting->joints [i]->verlet ->prev_rot = Quaternion (0 , 0 , 0 , 1 );
15011502 } else if (setting->extend_end_bone && setting->end_bone_length > 0 ) {
15021503 Vector3 axis = get_end_bone_axis (setting->end_bone , setting->end_bone_direction );
15031504 if (axis.is_zero_approx ()) {
@@ -1508,6 +1509,7 @@ void SpringBoneSimulator3D::_init_joints(Skeleton3D *p_skeleton, SpringBone3DSet
15081509 setting->joints [i]->verlet ->length = setting->end_bone_length ;
15091510 setting->joints [i]->verlet ->current_tail = setting->cached_center .xform (p_skeleton->get_bone_global_pose (setting->joints [i]->bone ).xform (axis * setting->end_bone_length ));
15101511 setting->joints [i]->verlet ->prev_tail = setting->joints [i]->verlet ->current_tail ;
1512+ setting->joints [i]->verlet ->prev_rot = Quaternion (0 , 0 , 0 , 1 );
15111513 }
15121514 }
15131515 setting->simulation_dirty = false ;
@@ -1570,10 +1572,13 @@ void SpringBoneSimulator3D::_process_joints(double p_delta, Skeleton3D *p_skelet
15701572 verlet->prev_tail = verlet->current_tail ;
15711573 verlet->current_tail = next_tail;
15721574
1573- // Apply rotation.
1575+ // Convert position to rotation.
15741576 Vector3 from = current_rot.xform (verlet->forward_vector );
15751577 Vector3 to = p_inverted_center_transform.basis .xform (next_tail - current_origin).normalized ();
1576- Quaternion from_to = get_from_to_rotation (from, to);
1578+ Quaternion from_to = get_from_to_rotation (from, to, verlet->prev_rot );
1579+ verlet->prev_rot = from_to;
1580+
1581+ // Apply rotation.
15771582 from_to *= current_rot;
15781583 from_to = get_local_pose_rotation (p_skeleton, p_joints[i]->bone , from_to);
15791584 p_skeleton->set_bone_pose_rotation (p_joints[i]->bone , from_to);
@@ -1588,10 +1593,13 @@ Quaternion SpringBoneSimulator3D::get_local_pose_rotation(Skeleton3D *p_skeleton
15881593 return p_skeleton->get_bone_global_pose (parent).basis .orthonormalized ().inverse () * p_global_pose_rotation;
15891594}
15901595
1591- Quaternion SpringBoneSimulator3D::get_from_to_rotation (const Vector3 &p_from, const Vector3 &p_to) {
1596+ Quaternion SpringBoneSimulator3D::get_from_to_rotation (const Vector3 &p_from, const Vector3 &p_to, const Quaternion &p_prev_rot) {
1597+ if (Math::is_equal_approx ((float )p_from.dot (p_to), -1 .0f )) {
1598+ return p_prev_rot; // For preventing to glitch, checking dot for detecting flip is more accurate than checking cross.
1599+ }
15921600 Vector3 axis = p_from.cross (p_to);
15931601 if (axis.is_zero_approx ()) {
1594- return Quaternion ( 0 , 0 , 0 , 1 ) ;
1602+ return p_prev_rot ;
15951603 }
15961604 float angle = p_from.angle_to (p_to);
15971605 if (Math::is_zero_approx (angle)) {
0 commit comments