Skip to content

Commit 912c86a

Browse files
committed
Changed SpringBone to return the prev rotation instead of init
1 parent b3a44e8 commit 912c86a

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

scene/3d/spring_bone_simulator_3d.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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)) {

scene/3d/spring_bone_simulator_3d.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class SpringBoneSimulator3D : public SkeletonModifier3D {
7272
Vector3 prev_tail;
7373
Vector3 current_tail;
7474
Vector3 forward_vector;
75+
Quaternion prev_rot;
7576
float length = 0.0;
7677
};
7778

@@ -266,7 +267,7 @@ class SpringBoneSimulator3D : public SkeletonModifier3D {
266267

267268
// Helper.
268269
static Quaternion get_local_pose_rotation(Skeleton3D *p_skeleton, int p_bone, const Quaternion &p_global_pose_rotation);
269-
static Quaternion get_from_to_rotation(const Vector3 &p_from, const Vector3 &p_to);
270+
static Quaternion get_from_to_rotation(const Vector3 &p_from, const Vector3 &p_to, const Quaternion &p_prev_rot);
270271
static Vector3 snap_position_to_plane(const Transform3D &p_rest, RotationAxis p_axis, const Vector3 &p_position);
271272
static Vector3 limit_length(const Vector3 &p_origin, const Vector3 &p_destination, float p_length);
272273

0 commit comments

Comments
 (0)