Introduce QQuaternion::dotProduct()
Change-Id: I14b9857ca0a43808b7d536fc258a6bb10f611211 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>bb10
parent
6c973dee2c
commit
a5d5353b59
|
|
@ -212,10 +212,19 @@ QT_BEGIN_NAMESPACE
|
|||
\sa scalar(), setX(), setY(), setZ()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2)
|
||||
\since 5.5
|
||||
|
||||
Returns the dot product of \a q1 and \a q2.
|
||||
|
||||
\sa length()
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns the length of the quaternion. This is also called the "norm".
|
||||
|
||||
\sa lengthSquared(), normalized()
|
||||
\sa lengthSquared(), normalized(), dotProduct()
|
||||
*/
|
||||
float QQuaternion::length() const
|
||||
{
|
||||
|
|
@ -225,7 +234,7 @@ float QQuaternion::length() const
|
|||
/*!
|
||||
Returns the squared length of the quaternion.
|
||||
|
||||
\sa length()
|
||||
\sa length(), dotProduct()
|
||||
*/
|
||||
float QQuaternion::lengthSquared() const
|
||||
{
|
||||
|
|
@ -240,7 +249,7 @@ float QQuaternion::lengthSquared() const
|
|||
will be returned as-is. Otherwise the normalized form of the
|
||||
quaternion of length 1 will be returned.
|
||||
|
||||
\sa length(), normalize()
|
||||
\sa normalize(), length(), dotProduct()
|
||||
*/
|
||||
QQuaternion QQuaternion::normalized() const
|
||||
{
|
||||
|
|
@ -792,13 +801,10 @@ QQuaternion QQuaternion::slerp
|
|||
return q2;
|
||||
|
||||
// Determine the angle between the two quaternions.
|
||||
QQuaternion q2b;
|
||||
float dot;
|
||||
dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
|
||||
if (dot >= 0.0f) {
|
||||
q2b = q2;
|
||||
} else {
|
||||
q2b = -q2;
|
||||
QQuaternion q2b(q2);
|
||||
float dot = QQuaternion::dotProduct(q1, q2);
|
||||
if (dot < 0.0f) {
|
||||
q2b = -q2b;
|
||||
dot = -dot;
|
||||
}
|
||||
|
||||
|
|
@ -844,13 +850,10 @@ QQuaternion QQuaternion::nlerp
|
|||
return q2;
|
||||
|
||||
// Determine the angle between the two quaternions.
|
||||
QQuaternion q2b;
|
||||
float dot;
|
||||
dot = q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
|
||||
if (dot >= 0.0f)
|
||||
q2b = q2;
|
||||
else
|
||||
q2b = -q2;
|
||||
QQuaternion q2b(q2);
|
||||
float dot = QQuaternion::dotProduct(q1, q2);
|
||||
if (dot < 0.0f)
|
||||
q2b = -q2b;
|
||||
|
||||
// Perform the linear interpolation.
|
||||
return (q1 * (1.0f - t) + q2b * t).normalized();
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ public:
|
|||
void setZ(float z);
|
||||
void setScalar(float scalar);
|
||||
|
||||
Q_DECL_CONSTEXPR static inline float dotProduct(const QQuaternion &q1, const QQuaternion &q2);
|
||||
|
||||
float length() const;
|
||||
float lengthSquared() const;
|
||||
|
||||
|
|
@ -168,6 +170,11 @@ inline void QQuaternion::setY(float aY) { yp = aY; }
|
|||
inline void QQuaternion::setZ(float aZ) { zp = aZ; }
|
||||
inline void QQuaternion::setScalar(float aScalar) { wp = aScalar; }
|
||||
|
||||
Q_DECL_CONSTEXPR inline float QQuaternion::dotProduct(const QQuaternion &q1, const QQuaternion &q2)
|
||||
{
|
||||
return q1.xp * q2.xp + q1.yp * q2.yp + q1.zp * q2.zp + q1.wp * q2.wp;
|
||||
}
|
||||
|
||||
inline QQuaternion QQuaternion::inverted() const
|
||||
{
|
||||
// Need some extra precision if the length is very small.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ public:
|
|||
private slots:
|
||||
void create();
|
||||
|
||||
void dotProduct_data();
|
||||
void dotProduct();
|
||||
|
||||
void length_data();
|
||||
void length();
|
||||
|
||||
|
|
@ -219,6 +222,58 @@ void tst_QQuaternion::create()
|
|||
QCOMPARE(v10.w(), 34.0f);
|
||||
}
|
||||
|
||||
// Test the computation of dot product.
|
||||
void tst_QQuaternion::dotProduct_data()
|
||||
{
|
||||
QTest::addColumn<float>("x1");
|
||||
QTest::addColumn<float>("y1");
|
||||
QTest::addColumn<float>("z1");
|
||||
QTest::addColumn<float>("scalar1");
|
||||
QTest::addColumn<float>("x2");
|
||||
QTest::addColumn<float>("y2");
|
||||
QTest::addColumn<float>("z2");
|
||||
QTest::addColumn<float>("scalar2");
|
||||
QTest::addColumn<float>("dot");
|
||||
|
||||
QTest::newRow("null")
|
||||
<< 0.0f << 0.0f << 0.0f << 0.0f
|
||||
<< 0.0f << 0.0f << 0.0f << 0.0f
|
||||
<< 0.0f;
|
||||
|
||||
QTest::newRow("identity")
|
||||
<< 0.0f << 0.0f << 0.0f << 1.0f
|
||||
<< 0.0f << 0.0f << 0.0f << 1.0f
|
||||
<< 1.0f;
|
||||
|
||||
QTest::newRow("unitvec")
|
||||
<< 1.0f << 0.0f << 0.0f << 0.0f
|
||||
<< 0.0f << 1.0f << 0.0f << 0.0f
|
||||
<< 0.0f;
|
||||
|
||||
QTest::newRow("complex")
|
||||
<< 1.0f << 2.0f << 3.0f << 4.0f
|
||||
<< 4.0f << 5.0f << 6.0f << 7.0f
|
||||
<< 60.0f;
|
||||
}
|
||||
void tst_QQuaternion::dotProduct()
|
||||
{
|
||||
QFETCH(float, x1);
|
||||
QFETCH(float, y1);
|
||||
QFETCH(float, z1);
|
||||
QFETCH(float, scalar1);
|
||||
QFETCH(float, x2);
|
||||
QFETCH(float, y2);
|
||||
QFETCH(float, z2);
|
||||
QFETCH(float, scalar2);
|
||||
QFETCH(float, dot);
|
||||
|
||||
QQuaternion q1(scalar1, x1, y1, z1);
|
||||
QQuaternion q2(scalar2, x2, y2, z2);
|
||||
|
||||
QCOMPARE(QQuaternion::dotProduct(q1, q2), dot);
|
||||
QCOMPARE(QQuaternion::dotProduct(q2, q1), dot);
|
||||
}
|
||||
|
||||
// Test length computation for quaternions.
|
||||
void tst_QQuaternion::length_data()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue