Skip to content
This repository was archived by the owner on Feb 24, 2025. It is now read-only.

Commit f6cfaea

Browse files
author
Anatoly Grishin
committed
Merge pull request #251 from T4Larson/slerpfix
replaced bullet's unstable quaternion slerp
2 parents a041ea1 + 1fd08c8 commit f6cfaea

File tree

4 files changed

+35
-4
lines changed

4 files changed

+35
-4
lines changed

src/entity.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ void Entity::updateCurrentBoneFrame(SSBoneFrame *bf, const btTransform* etr)
770770
if(k == 0)
771771
{
772772
btag->transform.getOrigin() += bf->pos;
773-
btag->qrotate = src_btag->qrotate.slerp(next_btag->qrotate, bf->animations.lerp);
773+
btag->qrotate = Quat_Slerp(src_btag->qrotate, next_btag->qrotate, bf->animations.lerp);
774774
}
775775
else
776776
{
@@ -789,7 +789,7 @@ void Entity::updateCurrentBoneFrame(SSBoneFrame *bf, const btTransform* etr)
789789
break;
790790
}
791791
}
792-
btag->qrotate = ov_src_btag->qrotate.slerp(ov_next_btag->qrotate, ov_lerp);
792+
btag->qrotate = Quat_Slerp(ov_src_btag->qrotate, ov_next_btag->qrotate, ov_lerp);
793793
}
794794
btag->transform.setRotation(btag->qrotate);
795795
}

src/mesh.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ void SkeletalModel::interpolateFrames()
284284
for(uint16_t k = 0; k < mesh_count; k++)
285285
{
286286
bf->bone_tags[k].offset = anim->frames[j - 1].bone_tags[k].offset.lerp(anim->frames[j].bone_tags[k].offset, lerp);
287-
bf->bone_tags[k].qrotate = anim->frames[j - 1].bone_tags[k].qrotate.slerp(anim->frames[j].bone_tags[k].qrotate, lerp);
287+
bf->bone_tags[k].qrotate = Quat_Slerp(anim->frames[j - 1].bone_tags[k].qrotate, anim->frames[j].bone_tags[k].qrotate, lerp);
288288
}
289289
bf++;
290290
}

src/vmath.cpp

+31-1
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,34 @@ void Mat4_RotateZ(btTransform& mat, btScalar ang)
6868
m[1] = -mat.getBasis().getColumn(0) * sina + mat.getBasis().getColumn(1) * cosa;
6969

7070
mat.getBasis() = m.transpose();
71-
}
71+
}
72+
73+
btQuaternion Quat_Slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
74+
{
75+
const btScalar magnitude = btSqrt(q1.length2() * q2.length2());
76+
btAssert(magnitude > btScalar(0));
77+
78+
const btScalar product = q1.dot(q2) / magnitude;
79+
const btScalar absproduct = btFabs(product);
80+
81+
if(absproduct < btScalar(1.0 - SIMD_EPSILON))
82+
{
83+
const btScalar theta = btAcos(absproduct);
84+
const btScalar d = btSin(theta);
85+
btAssert(d > btScalar(0))
86+
87+
const btScalar sign = (product < 0) ? btScalar(-1) : btScalar(1);
88+
const btScalar s0 = btSin((btScalar(1.0) - t) * theta) / d;
89+
const btScalar s1 = btSin(sign * t * theta) / d;
90+
91+
return btQuaternion(
92+
(q1.x() * s0 + q2.x() * s1),
93+
(q1.y() * s0 + q2.y() * s1),
94+
(q1.z() * s0 + q2.z() * s1),
95+
(q1.w() * s0 + q2.w() * s1));
96+
}
97+
else
98+
{
99+
return btQuaternion(q1);
100+
}
101+
}

src/vmath.h

+1
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,6 @@ void Mat4_Scale(btTransform &mat, btScalar x, btScalar y, btScalar z);
9292
void Mat4_RotateX(btTransform &mat, btScalar ang);
9393
void Mat4_RotateY(btTransform &mat, btScalar ang);
9494
void Mat4_RotateZ(btTransform &mat, btScalar ang);
95+
btQuaternion Quat_Slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t);
9596

9697
#endif // VMATH_H

0 commit comments

Comments
 (0)