Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet2/src/LinearMath/btQuaternion.h')
-rw-r--r--extern/bullet2/src/LinearMath/btQuaternion.h164
1 files changed, 121 insertions, 43 deletions
diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h
index 264751b33e7..cbeca2681cc 100644
--- a/extern/bullet2/src/LinearMath/btQuaternion.h
+++ b/extern/bullet2/src/LinearMath/btQuaternion.h
@@ -17,39 +17,56 @@ subject to the following restrictions:
#ifndef SIMD__QUATERNION_H_
#define SIMD__QUATERNION_H_
+
#include "btVector3.h"
+#include "btQuadWord.h"
-///The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform.
+/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */
class btQuaternion : public btQuadWord {
public:
+ /**@brief No initialization constructor */
btQuaternion() {}
// template <typename btScalar>
// explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
-
+ /**@brief Constructor from scalars */
btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)
: btQuadWord(x, y, z, w)
{}
-
+ /**@brief Axis angle Constructor
+ * @param axis The axis which the rotation is around
+ * @param angle The magnitude of the rotation around the angle (Radians) */
btQuaternion(const btVector3& axis, const btScalar& angle)
{
setRotation(axis, angle);
}
-
+ /**@brief Constructor from Euler angles
+ * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z
+ * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y
+ * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */
btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
+#ifndef BT_EULER_DEFAULT_ZYX
setEuler(yaw, pitch, roll);
+#else
+ setEulerZYX(yaw, pitch, roll);
+#endif
}
-
+ /**@brief Set the rotation using axis angle notation
+ * @param axis The axis around which to rotate
+ * @param angle The magnitude of the rotation in Radians */
void setRotation(const btVector3& axis, const btScalar& angle)
{
btScalar d = axis.length();
- assert(d != btScalar(0.0));
+ btAssert(d != btScalar(0.0));
btScalar s = btSin(angle * btScalar(0.5)) / d;
setValue(axis.x() * s, axis.y() * s, axis.z() * s,
btCos(angle * btScalar(0.5)));
}
-
+ /**@brief Set the quaternion using Euler angles
+ * @param yaw Angle around Y
+ * @param pitch Angle around X
+ * @param roll Angle around Z */
void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
@@ -66,122 +83,165 @@ public:
sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
}
-
- btQuaternion& operator+=(const btQuaternion& q)
+ /**@brief Set the quaternion using euler angles
+ * @param yaw Angle around Z
+ * @param pitch Angle around Y
+ * @param roll Angle around X */
+ void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
{
- m_x += q.x(); m_y += q.y(); m_z += q.z(); m_unusedW += q.m_unusedW;
+ btScalar halfYaw = btScalar(yaw) * btScalar(0.5);
+ btScalar halfPitch = btScalar(pitch) * btScalar(0.5);
+ btScalar halfRoll = btScalar(roll) * btScalar(0.5);
+ btScalar cosYaw = btCos(halfYaw);
+ btScalar sinYaw = btSin(halfYaw);
+ btScalar cosPitch = btCos(halfPitch);
+ btScalar sinPitch = btSin(halfPitch);
+ btScalar cosRoll = btCos(halfRoll);
+ btScalar sinRoll = btSin(halfRoll);
+ setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x
+ cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y
+ cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z
+ cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx
+ }
+ /**@brief Add two quaternions
+ * @param q The quaternion to add to this one */
+ SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q)
+ {
+ m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
return *this;
}
+ /**@brief Subtract out a quaternion
+ * @param q The quaternion to subtract from this one */
btQuaternion& operator-=(const btQuaternion& q)
{
- m_x -= q.x(); m_y -= q.y(); m_z -= q.z(); m_unusedW -= q.m_unusedW;
+ m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
return *this;
}
+ /**@brief Scale this quaternion
+ * @param s The scalar to scale by */
btQuaternion& operator*=(const btScalar& s)
{
- m_x *= s; m_y *= s; m_z *= s; m_unusedW *= s;
+ m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
return *this;
}
-
+ /**@brief Multiply this quaternion by q on the right
+ * @param q The other quaternion
+ * Equivilant to this = this * q */
btQuaternion& operator*=(const btQuaternion& q)
{
- setValue(m_unusedW * q.x() + m_x * q.m_unusedW + m_y * q.z() - m_z * q.y(),
- m_unusedW * q.y() + m_y * q.m_unusedW + m_z * q.x() - m_x * q.z(),
- m_unusedW * q.z() + m_z * q.m_unusedW + m_x * q.y() - m_y * q.x(),
- m_unusedW * q.m_unusedW - m_x * q.x() - m_y * q.y() - m_z * q.z());
+ setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
+ m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
+ m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
+ m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
return *this;
}
-
+ /**@brief Return the dot product between this quaternion and another
+ * @param q The other quaternion */
btScalar dot(const btQuaternion& q) const
{
- return m_x * q.x() + m_y * q.y() + m_z * q.z() + m_unusedW * q.m_unusedW;
+ return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
}
+ /**@brief Return the length squared of the quaternion */
btScalar length2() const
{
return dot(*this);
}
+ /**@brief Return the length of the quaternion */
btScalar length() const
{
return btSqrt(length2());
}
+ /**@brief Normalize the quaternion
+ * Such that x^2 + y^2 + z^2 +w^2 = 1 */
btQuaternion& normalize()
{
return *this /= length();
}
+ /**@brief Return a scaled version of this quaternion
+ * @param s The scale factor */
SIMD_FORCE_INLINE btQuaternion
operator*(const btScalar& s) const
{
- return btQuaternion(x() * s, y() * s, z() * s, m_unusedW * s);
+ return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
}
-
+ /**@brief Return an inversely scaled versionof this quaternion
+ * @param s The inverse scale factor */
btQuaternion operator/(const btScalar& s) const
{
- assert(s != btScalar(0.0));
+ btAssert(s != btScalar(0.0));
return *this * (btScalar(1.0) / s);
}
-
+ /**@brief Inversely scale this quaternion
+ * @param s The scale factor */
btQuaternion& operator/=(const btScalar& s)
{
- assert(s != btScalar(0.0));
+ btAssert(s != btScalar(0.0));
return *this *= btScalar(1.0) / s;
}
-
+ /**@brief Return a normalized version of this quaternion */
btQuaternion normalized() const
{
return *this / length();
}
-
+ /**@brief Return the angle between this quaternion and the other
+ * @param q The other quaternion */
btScalar angle(const btQuaternion& q) const
{
btScalar s = btSqrt(length2() * q.length2());
- assert(s != btScalar(0.0));
+ btAssert(s != btScalar(0.0));
return btAcos(dot(q) / s);
}
-
+ /**@brief Return the angle of rotation represented by this quaternion */
btScalar getAngle() const
{
- btScalar s = btScalar(2.) * btAcos(m_unusedW);
+ btScalar s = btScalar(2.) * btAcos(m_floats[3]);
return s;
}
-
+ /**@brief Return the inverse of this quaternion */
btQuaternion inverse() const
{
- return btQuaternion(-m_x, -m_y, -m_z, m_unusedW);
+ return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
}
+ /**@brief Return the sum of this quaternion and the other
+ * @param q2 The other quaternion */
SIMD_FORCE_INLINE btQuaternion
operator+(const btQuaternion& q2) const
{
const btQuaternion& q1 = *this;
- return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_unusedW + q2.m_unusedW);
+ return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
}
+ /**@brief Return the difference between this quaternion and the other
+ * @param q2 The other quaternion */
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q2) const
{
const btQuaternion& q1 = *this;
- return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_unusedW - q2.m_unusedW);
+ return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
}
+ /**@brief Return the negative of this quaternion
+ * This simply negates each element */
SIMD_FORCE_INLINE btQuaternion operator-() const
{
const btQuaternion& q2 = *this;
- return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_unusedW);
+ return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]);
}
-
+ /**@todo document this and it's use */
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
{
btQuaternion diff,sum;
@@ -192,6 +252,10 @@ public:
return (-qd);
}
+ /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion
+ * @param q The other quaternion to interpolate with
+ * @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q.
+ * Slerp interpolates assuming constant velocity. */
btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
{
btScalar theta = angle(q);
@@ -200,10 +264,10 @@ public:
btScalar d = btScalar(1.0) / btSin(theta);
btScalar s0 = btSin((btScalar(1.0) - t) * theta);
btScalar s1 = btSin(t * theta);
- return btQuaternion((m_x * s0 + q.x() * s1) * d,
- (m_y * s0 + q.y() * s1) * d,
- (m_z * s0 + q.z() * s1) * d,
- (m_unusedW * s0 + q.m_unusedW * s1) * d);
+ return btQuaternion((m_floats[0] * s0 + q.x() * s1) * d,
+ (m_floats[1] * s0 + q.y() * s1) * d,
+ (m_floats[2] * s0 + q.z() * s1) * d,
+ (m_floats[3] * s0 + q.m_floats[3] * s1) * d);
}
else
{
@@ -211,13 +275,19 @@ public:
}
}
- SIMD_FORCE_INLINE const btScalar& getW() const { return m_unusedW; }
+ static const btQuaternion& getIdentity()
+ {
+ static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.));
+ return identityQuat;
+ }
+
+ SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; }
};
-
+/**@brief Return the negative of a quaternion */
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q)
{
@@ -226,7 +296,7 @@ operator-(const btQuaternion& q)
-
+/**@brief Return the product of two quaternions */
SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q1, const btQuaternion& q2) {
return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
@@ -253,6 +323,7 @@ operator*(const btVector3& w, const btQuaternion& q)
-w.x() * q.x() - w.y() * q.y() - w.z() * q.z());
}
+/**@brief Calculate the dot product between two quaternions */
SIMD_FORCE_INLINE btScalar
dot(const btQuaternion& q1, const btQuaternion& q2)
{
@@ -260,25 +331,32 @@ dot(const btQuaternion& q1, const btQuaternion& q2)
}
+/**@brief Return the length of a quaternion */
SIMD_FORCE_INLINE btScalar
length(const btQuaternion& q)
{
return q.length();
}
+/**@brief Return the angle between two quaternions*/
SIMD_FORCE_INLINE btScalar
angle(const btQuaternion& q1, const btQuaternion& q2)
{
return q1.angle(q2);
}
-
+/**@brief Return the inverse of a quaternion*/
SIMD_FORCE_INLINE btQuaternion
inverse(const btQuaternion& q)
{
return q.inverse();
}
+/**@brief Return the result of spherical linear interpolation betwen two quaternions
+ * @param q1 The first quaternion
+ * @param q2 The second quaternion
+ * @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2
+ * Slerp assumes constant velocity between positions. */
SIMD_FORCE_INLINE btQuaternion
slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t)
{