17 #ifndef BT_SIMD__QUATERNION_H_ 18 #define BT_SIMD__QUATERNION_H_ 25 #ifdef BT_USE_DOUBLE_PRECISION 26 #define btQuaternionData btQuaternionDoubleData 27 #define btQuaternionDataName "btQuaternionDoubleData" 29 #define btQuaternionData btQuaternionFloatData 30 #define btQuaternionDataName "btQuaternionFloatData" 31 #endif //BT_USE_DOUBLE_PRECISION 38 #define vOnes (_mm_set_ps(1.0f, 1.0f, 1.0f, 1.0f)) 42 #if defined(BT_USE_SSE) 44 #define vQInv (_mm_set_ps(+0.0f, -0.0f, -0.0f, -0.0f)) 45 #define vPPPM (_mm_set_ps(-0.0f, +0.0f, +0.0f, +0.0f)) 47 #elif defined(BT_USE_NEON) 60 #if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE))|| defined(BT_USE_NEON) 70 mVec128 = rhs.mVec128;
103 #ifndef BT_EULER_DEFAULT_ZYX 135 setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
136 cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
137 sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
138 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
155 setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
156 cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
157 cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
158 cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
173 sqy = m_floats[1] * m_floats[1];
174 sqz = m_floats[2] * m_floats[2];
175 squ = m_floats[3] * m_floats[3];
176 sarg =
btScalar(-2.) * (m_floats[0] * m_floats[2] - m_floats[3] * m_floats[1]);
187 }
else if (sarg >=
btScalar(0.99999))
195 rollX =
btAtan2(2 * (m_floats[1] * m_floats[2] + m_floats[3] * m_floats[0]), squ - sqx - sqy + sqz);
196 yawZ =
btAtan2(2 * (m_floats[0] * m_floats[1] + m_floats[3] * m_floats[2]), squ + sqx - sqy - sqz);
204 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 205 mVec128 = _mm_add_ps(mVec128, q.mVec128);
206 #elif defined(BT_USE_NEON) 207 mVec128 = vaddq_f32(mVec128, q.mVec128);
221 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 222 mVec128 = _mm_sub_ps(mVec128, q.mVec128);
223 #elif defined(BT_USE_NEON) 224 mVec128 = vsubq_f32(mVec128, q.mVec128);
238 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 239 __m128 vs = _mm_load_ss(&s);
240 vs = bt_pshufd_ps(vs, 0);
241 mVec128 = _mm_mul_ps(mVec128, vs);
242 #elif defined(BT_USE_NEON) 243 mVec128 = vmulq_n_f32(mVec128, s);
258 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 259 __m128 vQ2 = q.get128();
261 __m128 A1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(0,1,2,0));
262 __m128 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0));
266 __m128 A2 = bt_pshufd_ps(mVec128, BT_SHUFFLE(1,2,0,1));
267 __m128 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
271 B1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(2,0,1,2));
272 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
276 mVec128 = bt_splat_ps(mVec128, 3);
277 mVec128 = mVec128 * vQ2;
280 mVec128 = mVec128 - B1;
281 A1 = _mm_xor_ps(A1, vPPPM);
282 mVec128 = mVec128+ A1;
284 #elif defined(BT_USE_NEON) 286 float32x4_t vQ1 = mVec128;
287 float32x4_t vQ2 = q.get128();
288 float32x4_t A0, A1, B1, A2, B2, A3, B3;
289 float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz;
293 tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) );
296 tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) );
299 vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1);
301 vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
303 vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
304 vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
306 A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx);
307 B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx);
309 A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
310 B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
312 A3 = vcombine_f32(vQ1zx, vQ1yz);
313 B3 = vcombine_f32(vQ2yz, vQ2xz);
315 A1 = vmulq_f32(A1, B1);
316 A2 = vmulq_f32(A2, B2);
317 A3 = vmulq_f32(A3, B3);
318 A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1);
320 A1 = vaddq_f32(A1, A2);
321 A0 = vsubq_f32(A0, A3);
324 A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
325 A0 = vaddq_f32(A0, A1);
341 #if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 344 vd = _mm_mul_ps(mVec128, q.mVec128);
346 __m128 t = _mm_movehl_ps(vd, vd);
347 vd = _mm_add_ps(vd, t);
348 t = _mm_shuffle_ps(vd, vd, 0x55);
349 vd = _mm_add_ss(vd, t);
351 return _mm_cvtss_f32(vd);
352 #elif defined(BT_USE_NEON) 353 float32x4_t vd = vmulq_f32(mVec128, q.mVec128);
354 float32x2_t
x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd));
356 return vget_lane_f32(x, 0);
389 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 392 vd = _mm_mul_ps(mVec128, mVec128);
394 __m128 t = _mm_movehl_ps(vd, vd);
395 vd = _mm_add_ps(vd, t);
396 t = _mm_shuffle_ps(vd, vd, 0x55);
397 vd = _mm_add_ss(vd, t);
399 vd = _mm_sqrt_ss(vd);
400 vd = _mm_div_ss(vOnes, vd);
401 vd = bt_pshufd_ps(vd, 0);
402 mVec128 = _mm_mul_ps(mVec128, vd);
415 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 416 __m128 vs = _mm_load_ss(&s);
417 vs = bt_pshufd_ps(vs, 0x00);
420 #elif defined(BT_USE_NEON) 496 return btVector3(m_floats[0] * s, m_floats[1] * s, m_floats[2] * s);
502 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 504 #elif defined(BT_USE_NEON) 505 return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)vQInv));
516 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 518 #elif defined(BT_USE_NEON) 531 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 533 #elif defined(BT_USE_NEON) 545 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 547 #elif defined(BT_USE_NEON) 548 return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)btvMzeroMask) );
560 if( diff.
dot(diff) > sum.
dot(sum) )
571 if( diff.
dot(diff) < sum.
dot(sum) )
645 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 646 __m128 vQ1 = q1.get128();
647 __m128 vQ2 = q2.get128();
648 __m128 A0, A1, B1, A2, B2;
650 A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0));
651 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0));
655 A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1));
656 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
660 B1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2));
661 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
665 A0 = bt_splat_ps(vQ1, 3);
671 A1 = _mm_xor_ps(A1, vPPPM);
676 #elif defined(BT_USE_NEON) 678 float32x4_t vQ1 = q1.get128();
679 float32x4_t vQ2 = q2.get128();
680 float32x4_t A0, A1, B1, A2, B2, A3, B3;
681 float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz;
685 tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) );
688 tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) );
691 vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1);
693 vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
695 vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
696 vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
698 A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx);
699 B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx);
701 A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
702 B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
704 A3 = vcombine_f32(vQ1zx, vQ1yz);
705 B3 = vcombine_f32(vQ2yz, vQ2xz);
707 A1 = vmulq_f32(A1, B1);
708 A2 = vmulq_f32(A2, B2);
709 A3 = vmulq_f32(A3, B3);
710 A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1);
712 A1 = vaddq_f32(A1, A2);
713 A0 = vsubq_f32(A0, A3);
716 A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
717 A0 = vaddq_f32(A0, A1);
723 q1.
w() * q2.
x() + q1.
x() * q2.
w() + q1.
y() * q2.
z() - q1.
z() * q2.
y(),
724 q1.
w() * q2.
y() + q1.
y() * q2.
w() + q1.
z() * q2.
x() - q1.
x() * q2.
z(),
725 q1.
w() * q2.
z() + q1.
z() * q2.
w() + q1.
x() * q2.
y() - q1.
y() * q2.
x(),
726 q1.
w() * q2.
w() - q1.
x() * q2.
x() - q1.
y() * q2.
y() - q1.
z() * q2.
z());
733 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 734 __m128 vQ1 = q.get128();
735 __m128 vQ2 = w.get128();
736 __m128 A1, B1, A2, B2, A3, B3;
738 A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(3,3,3,0));
739 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(0,1,2,0));
743 A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1));
744 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
748 A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2));
749 B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
754 A1 = _mm_xor_ps(A1, vPPPM);
759 #elif defined(BT_USE_NEON) 761 float32x4_t vQ1 = q.get128();
762 float32x4_t vQ2 = w.get128();
763 float32x4_t A1, B1, A2, B2, A3, B3;
764 float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz;
766 vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1);
770 tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) );
773 tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) );
777 vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
779 vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
780 vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
782 A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx);
783 B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx);
785 A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
786 B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
788 A3 = vcombine_f32(vQ1zx, vQ1yz);
789 B3 = vcombine_f32(vQ2yz, vQ2xz);
791 A1 = vmulq_f32(A1, B1);
792 A2 = vmulq_f32(A2, B2);
793 A3 = vmulq_f32(A3, B3);
795 A1 = vaddq_f32(A1, A2);
798 A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
800 A1 = vsubq_f32(A1, A3);
806 q.
w() * w.
x() + q.
y() * w.
z() - q.
z() * w.
y(),
807 q.
w() * w.
y() + q.
z() * w.
x() - q.
x() * w.
z(),
808 q.
w() * w.
z() + q.
x() * w.
y() - q.
y() * w.
x(),
809 -q.
x() * w.
x() - q.
y() * w.
y() - q.
z() * w.
z());
816 #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 817 __m128 vQ1 = w.get128();
818 __m128 vQ2 = q.get128();
819 __m128 A1, B1, A2, B2, A3, B3;
821 A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0));
822 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0));
826 A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1));
827 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
831 A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2));
832 B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
837 A1 = _mm_xor_ps(A1, vPPPM);
842 #elif defined(BT_USE_NEON) 844 float32x4_t vQ1 = w.get128();
845 float32x4_t vQ2 = q.get128();
846 float32x4_t A1, B1, A2, B2, A3, B3;
847 float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz;
852 tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) );
855 tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) );
858 vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1);
860 vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
862 vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
863 vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
865 A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx);
866 B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx);
868 A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
869 B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
871 A3 = vcombine_f32(vQ1zx, vQ1yz);
872 B3 = vcombine_f32(vQ2yz, vQ2xz);
874 A1 = vmulq_f32(A1, B1);
875 A2 = vmulq_f32(A2, B2);
876 A3 = vmulq_f32(A3, B3);
878 A1 = vaddq_f32(A1, A2);
881 A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
883 A1 = vsubq_f32(A1, A3);
889 +w.
x() * q.
w() + w.
y() * q.
z() - w.
z() * q.
y(),
890 +w.
y() * q.
w() + w.
z() * q.
x() - w.
x() * q.
z(),
891 +w.
z() * q.
w() + w.
x() * q.
y() - w.
y() * q.
x(),
892 -w.
x() * q.
x() - w.
y() * q.
y() - w.
z() * q.
z());
933 return q1.
slerp(q2, t);
941 #if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) 942 return btVector3(_mm_and_ps(q.get128(), btvFFF0fMask));
943 #elif defined(BT_USE_NEON) 944 return btVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), btvFFF0Mask));
994 for (
int i=0;i<4;i++)
1000 for (
int i=0;i<4;i++)
1008 for (
int i=0;i<4;i++)
1014 for (
int i=0;i<4;i++)
1022 for (
int i=0;i<4;i++)
1028 for (
int i = 0; i<4; i++)
1034 for (
int i=0;i<4;i++)
1039 #endif //BT_SIMD__QUATERNION_H_ static T sum(const btAlignedObjectArray< T > &items)
void deSerialize(const struct btQuaternionFloatData &dataIn)
btScalar getAngle() const
Return the angle [0, 2Pi] of rotation represented by this quaternion.
btQuaternion & operator*=(const btQuaternion &q)
Multiply this quaternion by q on the right.
btQuaternion farthest(const btQuaternion &qd) const
btQuaternion(const btScalar &yaw, const btScalar &pitch, const btScalar &roll)
Constructor from Euler angles.
void serialize(struct btQuaternionData &dataOut) const
btScalar btSin(btScalar x)
static const btQuaternion & getIdentity()
const btScalar & z() const
Return the z value.
btQuaternion & safeNormalize()
void serializeDouble(struct btQuaternionDoubleData &dataOut) const
void deSerializeDouble(const struct btQuaternionDoubleData &dataIn)
void deSerializeFloat(const struct btQuaternionFloatData &dataIn)
void btPlaneSpace1(const T &n, T &p, T &q)
btScalar btSqrt(btScalar y)
btScalar dot(const btQuaternion &q) const
Return the dot product between this quaternion and another.
const btScalar & getW() const
#define SIMD_FORCE_INLINE
btQuaternion & operator/=(const btScalar &s)
Inversely scale this quaternion.
btQuaternion operator-(const btQuaternion &q2) const
Return the difference between this quaternion and the other.
btQuaternion & operator-=(const btQuaternion &q)
Subtract out a quaternion.
const btScalar & y() const
Return the y value.
btVector3 getAxis() const
Return the axis of the rotation represented by this quaternion.
btQuaternion operator-() const
Return the negative of this quaternion This simply negates each element.
const btScalar & getY() const
Return the y value.
const btScalar & getX() const
Return the x value.
const btScalar & w() const
Return the w value.
btScalar dot(const btVector3 &v) const
Return the dot product.
btQuaternion & operator+=(const btQuaternion &q)
Add two quaternions.
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
btQuaternion nearest(const btQuaternion &qd) const
btScalar length() const
Return the length of the quaternion.
btQuaternion operator*(const btScalar &s) const
Return a scaled version of this quaternion.
const btScalar & x() const
Return the x value.
btVector3 quatRotate(const btQuaternion &rotation, const btVector3 &v)
const btScalar & getZ() const
Return the z value.
void serializeFloat(struct btQuaternionFloatData &dataOut) const
btQuaternion shortestArcQuat(const btVector3 &v0, const btVector3 &v1)
void setRotation(const btVector3 &axis, const btScalar &_angle)
Set the rotation using axis angle notation.
btQuaternion & normalize()
Normalize the quaternion Such that x^2 + y^2 + z^2 +w^2 = 1.
btQuaternion shortestArcQuatNormalize2(btVector3 &v0, btVector3 &v1)
btScalar btAtan2(btScalar x, btScalar y)
void setValue(const btScalar &_x, const btScalar &_y, const btScalar &_z)
Set x,y,z and zero w.
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
btQuaternion()
No initialization constructor.
const btScalar & getY() const
Return the y value.
The btQuadWord class is base class for btVector3 and btQuaternion.
const btScalar & getX() const
Return the x value.
btQuaternion inverse() const
Return the inverse of this quaternion.
btScalar length() const
Return the length of the vector.
btScalar length2() const
Return the length squared of the quaternion.
const btScalar & y() const
Return the y value.
btScalar angleShortestPath(const btQuaternion &q) const
Return the angle between this quaternion and the other along the shortest path.
btVector3 can be used to represent 3D points and vectors.
#define ATTRIBUTE_ALIGNED16(a)
btQuaternion(const btScalar &_x, const btScalar &_y, const btScalar &_z, const btScalar &_w)
Constructor from scalars.
void getEulerZYX(btScalar &yawZ, btScalar &pitchY, btScalar &rollX) const
Get the euler angles from this quaternion.
btScalar btAcos(btScalar x)
void setEulerZYX(const btScalar &yawZ, const btScalar &pitchY, const btScalar &rollX)
Set the quaternion using euler angles.
btQuaternion normalized() const
Return a normalized version of this quaternion.
btQuaternion & operator*=(const btScalar &s)
Scale this quaternion.
btScalar angle(const btQuaternion &q) const
Return the ***half*** angle between this quaternion and the other.
btScalar getAngleShortestPath() const
Return the angle [0, Pi] of rotation represented by this quaternion along the shortest path...
btQuaternion operator+(const btQuaternion &q2) const
Return the sum of this quaternion and the other.
const btScalar & x() const
Return the x value.
btQuaternion operator/(const btScalar &s) const
Return an inversely scaled versionof this quaternion.
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
btScalar btAsin(btScalar x)
void setEuler(const btScalar &yaw, const btScalar &pitch, const btScalar &roll)
Set the quaternion using Euler angles.
btScalar btAngle(const btQuaternion &q1, const btQuaternion &q2)
Return the angle between two quaternions.
btQuaternion(const btVector3 &_axis, const btScalar &_angle)
Axis angle Constructor.
const btScalar & getZ() const
Return the z value.
btQuaternion slerp(const btQuaternion &q, const btScalar &t) const
Return the quaternion which is the result of Spherical Linear Interpolation between this and the othe...
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar btCos(btScalar x)
btScalar btFabs(btScalar x)
const btScalar & z() const
Return the z value.