@@ -1520,6 +1520,7 @@ void SpringBoneSimulator3D::_init_joints(Skeleton3D *p_skeleton, SpringBone3DSet
15201520 setting->joints [i]->verlet ->prev_tail = setting->joints [i]->verlet ->current_tail ;
15211521 setting->joints [i]->verlet ->forward_vector = axis.normalized ();
15221522 setting->joints [i]->verlet ->length = axis.length ();
1523+ setting->joints [i]->verlet ->prev_rot = Quaternion (0 , 0 , 0 , 1 );
15231524 } else if (setting->extend_end_bone && setting->end_bone_length > 0 ) {
15241525 Vector3 axis = get_end_bone_axis (setting->end_bone , setting->end_bone_direction );
15251526 if (axis.is_zero_approx ()) {
@@ -1530,6 +1531,7 @@ void SpringBoneSimulator3D::_init_joints(Skeleton3D *p_skeleton, SpringBone3DSet
15301531 setting->joints [i]->verlet ->length = setting->end_bone_length ;
15311532 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 ));
15321533 setting->joints [i]->verlet ->prev_tail = setting->joints [i]->verlet ->current_tail ;
1534+ setting->joints [i]->verlet ->prev_rot = Quaternion (0 , 0 , 0 , 1 );
15331535 }
15341536 }
15351537 setting->simulation_dirty = false ;
@@ -1592,10 +1594,13 @@ void SpringBoneSimulator3D::_process_joints(double p_delta, Skeleton3D *p_skelet
15921594 verlet->prev_tail = verlet->current_tail ;
15931595 verlet->current_tail = next_tail;
15941596
1595- // Apply rotation.
1597+ // Convert position to rotation.
15961598 Vector3 from = current_rot.xform (verlet->forward_vector );
15971599 Vector3 to = p_inverted_center_transform.basis .xform (next_tail - current_origin).normalized ();
1598- Quaternion from_to = get_from_to_rotation (from, to);
1600+ Quaternion from_to = get_from_to_rotation (from, to, verlet->prev_rot );
1601+ verlet->prev_rot = from_to;
1602+
1603+ // Apply rotation.
15991604 from_to *= current_rot;
16001605 from_to = get_local_pose_rotation (p_skeleton, p_joints[i]->bone , from_to);
16011606 p_skeleton->set_bone_pose_rotation (p_joints[i]->bone , from_to);
@@ -1610,10 +1615,13 @@ Quaternion SpringBoneSimulator3D::get_local_pose_rotation(Skeleton3D *p_skeleton
16101615 return p_skeleton->get_bone_global_pose (parent).basis .orthonormalized ().inverse () * p_global_pose_rotation;
16111616}
16121617
1613- Quaternion SpringBoneSimulator3D::get_from_to_rotation (const Vector3 &p_from, const Vector3 &p_to) {
1618+ Quaternion SpringBoneSimulator3D::get_from_to_rotation (const Vector3 &p_from, const Vector3 &p_to, const Quaternion &p_prev_rot) {
1619+ if (Math::is_equal_approx ((float )p_from.dot (p_to), -1 .0f )) {
1620+ return p_prev_rot; // For preventing to glitch, checking dot for detecting flip is more accurate than checking cross.
1621+ }
16141622 Vector3 axis = p_from.cross (p_to);
16151623 if (axis.is_zero_approx ()) {
1616- return Quaternion ( 0 , 0 , 0 , 1 ) ;
1624+ return p_prev_rot ;
16171625 }
16181626 float angle = p_from.angle_to (p_to);
16191627 if (Math::is_zero_approx (angle)) {
0 commit comments