summaryrefslogtreecommitdiffstats
path: root/src/gui/math3d
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/math3d')
-rw-r--r--src/gui/math3d/qmatrix4x4.cpp145
-rw-r--r--src/gui/math3d/qquaternion.cpp29
-rw-r--r--src/gui/math3d/qvector2d.cpp6
-rw-r--r--src/gui/math3d/qvector3d.cpp8
-rw-r--r--src/gui/math3d/qvector4d.cpp16
5 files changed, 111 insertions, 93 deletions
diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp
index 2c3d616..031c5ef 100644
--- a/src/gui/math3d/qmatrix4x4.cpp
+++ b/src/gui/math3d/qmatrix4x4.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qmatrix4x4.h"
+#include <private/qnumeric_p.h>
#include <QtCore/qmath.h>
#include <QtCore/qvariant.h>
#include <QtGui/qmatrix.h>
@@ -58,7 +59,7 @@ QT_BEGIN_NAMESPACE
\sa QVector3D, QGenericMatrix
*/
-static const qreal inv_dist_to_plane = 1. / 1024.;
+static const qreal inv_dist_to_plane = qreal(1.) / qreal(1024.);
/*!
\fn QMatrix4x4::QMatrix4x4()
@@ -506,22 +507,23 @@ QMatrix4x4 QMatrix4x4::transposed() const
*/
QMatrix4x4& QMatrix4x4::operator/=(qreal divisor)
{
- m[0][0] /= divisor;
- m[0][1] /= divisor;
- m[0][2] /= divisor;
- m[0][3] /= divisor;
- m[1][0] /= divisor;
- m[1][1] /= divisor;
- m[1][2] /= divisor;
- m[1][3] /= divisor;
- m[2][0] /= divisor;
- m[2][1] /= divisor;
- m[2][2] /= divisor;
- m[2][3] /= divisor;
- m[3][0] /= divisor;
- m[3][1] /= divisor;
- m[3][2] /= divisor;
- m[3][3] /= divisor;
+ const qreal inv_divisor = (1 / divisor);
+ m[0][0] *= inv_divisor;
+ m[0][1] *= inv_divisor;
+ m[0][2] *= inv_divisor;
+ m[0][3] *= inv_divisor;
+ m[1][0] *= inv_divisor;
+ m[1][1] *= inv_divisor;
+ m[1][2] *= inv_divisor;
+ m[1][3] *= inv_divisor;
+ m[2][0] *= inv_divisor;
+ m[2][1] *= inv_divisor;
+ m[2][2] *= inv_divisor;
+ m[2][3] *= inv_divisor;
+ m[3][0] *= inv_divisor;
+ m[3][1] *= inv_divisor;
+ m[3][2] *= inv_divisor;
+ m[3][3] *= inv_divisor;
flagBits = General;
return *this;
}
@@ -662,23 +664,24 @@ QMatrix4x4& QMatrix4x4::operator/=(qreal divisor)
*/
QMatrix4x4 operator/(const QMatrix4x4& matrix, qreal divisor)
{
+ const qreal inv_divisor = (1 / divisor);
QMatrix4x4 m(1); // The "1" says to not load the identity.
- m.m[0][0] = matrix.m[0][0] / divisor;
- m.m[0][1] = matrix.m[0][1] / divisor;
- m.m[0][2] = matrix.m[0][2] / divisor;
- m.m[0][3] = matrix.m[0][3] / divisor;
- m.m[1][0] = matrix.m[1][0] / divisor;
- m.m[1][1] = matrix.m[1][1] / divisor;
- m.m[1][2] = matrix.m[1][2] / divisor;
- m.m[1][3] = matrix.m[1][3] / divisor;
- m.m[2][0] = matrix.m[2][0] / divisor;
- m.m[2][1] = matrix.m[2][1] / divisor;
- m.m[2][2] = matrix.m[2][2] / divisor;
- m.m[2][3] = matrix.m[2][3] / divisor;
- m.m[3][0] = matrix.m[3][0] / divisor;
- m.m[3][1] = matrix.m[3][1] / divisor;
- m.m[3][2] = matrix.m[3][2] / divisor;
- m.m[3][3] = matrix.m[3][3] / divisor;
+ m.m[0][0] = matrix.m[0][0] * inv_divisor;
+ m.m[0][1] = matrix.m[0][1] * inv_divisor;
+ m.m[0][2] = matrix.m[0][2] * inv_divisor;
+ m.m[0][3] = matrix.m[0][3] * inv_divisor;
+ m.m[1][0] = matrix.m[1][0] * inv_divisor;
+ m.m[1][1] = matrix.m[1][1] * inv_divisor;
+ m.m[1][2] = matrix.m[1][2] * inv_divisor;
+ m.m[1][3] = matrix.m[1][3] * inv_divisor;
+ m.m[2][0] = matrix.m[2][0] * inv_divisor;
+ m.m[2][1] = matrix.m[2][1] * inv_divisor;
+ m.m[2][2] = matrix.m[2][2] * inv_divisor;
+ m.m[2][3] = matrix.m[2][3] * inv_divisor;
+ m.m[3][0] = matrix.m[3][0] * inv_divisor;
+ m.m[3][1] = matrix.m[3][1] * inv_divisor;
+ m.m[3][2] = matrix.m[3][2] * inv_divisor;
+ m.m[3][3] = matrix.m[3][3] * inv_divisor;
return m;
}
@@ -1011,7 +1014,7 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
s = 0.0f;
c = -1.0f;
} else {
- qreal a = angle * M_PI / 180.0f;
+ qreal a = angle * Q_PI180;
c = qCos(a);
s = qSin(a);
}
@@ -1066,10 +1069,11 @@ void QMatrix4x4::rotate(qreal angle, qreal x, qreal y, qreal z)
if (!quick) {
qreal len = x * x + y * y + z * z;
if (!qFuzzyIsNull(len - 1.0f) && !qFuzzyIsNull(len)) {
+ const qreal inv_len = 1 / len;
len = qSqrt(len);
- x /= len;
- y /= len;
- z /= len;
+ x *= inv_len;
+ y *= inv_len;
+ z *= inv_len;
}
ic = 1.0f - c;
m.m[0][0] = x * x * ic + c;
@@ -1118,7 +1122,7 @@ void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
s = 0.0f;
c = -1.0f;
} else {
- qreal a = angle * M_PI / 180.0f;
+ qreal a = angle * Q_PI180;
c = qCos(a);
s = qSin(a);
}
@@ -1169,10 +1173,11 @@ void QMatrix4x4::projectedRotate(qreal angle, qreal x, qreal y, qreal z)
if (!quick) {
qreal len = x * x + y * y + z * z;
if (!qFuzzyIsNull(len - 1.0f) && !qFuzzyIsNull(len)) {
+ const qreal inv_len = 1 / len;
len = qSqrt(len);
- x /= len;
- y /= len;
- z /= len;
+ x *= inv_len;
+ y *= inv_len;
+ z *= inv_len;
}
ic = 1.0f - c;
m.m[0][0] = x * x * ic + c;
@@ -1299,35 +1304,39 @@ void QMatrix4x4::ortho(qreal left, qreal right, qreal bottom, qreal top, qreal n
qreal width = right - left;
qreal invheight = top - bottom;
qreal clip = farPlane - nearPlane;
+ qreal inv_width = 1 / width;
+ qreal inv_invheight = 1 / invheight;
+ qreal inv_clip = 1 / clip;
#ifndef QT_NO_VECTOR3D
if (clip == 2.0f && (nearPlane + farPlane) == 0.0f) {
// We can express this projection as a translate and scale
// which will be more efficient to modify with further
// transformations than producing a "General" matrix.
+
translate(QVector3D
- (-(left + right) / width,
- -(top + bottom) / invheight,
+ (-(left + right) * inv_width,
+ -(top + bottom) * inv_invheight,
0.0f));
scale(QVector3D
- (2.0f / width,
- 2.0f / invheight,
+ (2.0f * inv_width,
+ 2.0f * inv_invheight,
-1.0f));
return;
}
#endif
QMatrix4x4 m(1);
- m.m[0][0] = 2.0f / width;
+ m.m[0][0] = 2.0f * inv_width;
m.m[1][0] = 0.0f;
m.m[2][0] = 0.0f;
- m.m[3][0] = -(left + right) / width;
+ m.m[3][0] = -(left + right) * inv_width;
m.m[0][1] = 0.0f;
- m.m[1][1] = 2.0f / invheight;
+ m.m[1][1] = 2.0f * inv_invheight;
m.m[2][1] = 0.0f;
- m.m[3][1] = -(top + bottom) / invheight;
+ m.m[3][1] = -(top + bottom) * inv_invheight;
m.m[0][2] = 0.0f;
m.m[1][2] = 0.0f;
- m.m[2][2] = -2.0f / clip;
- m.m[3][2] = -(nearPlane + farPlane) / clip;
+ m.m[2][2] = -2.0f * inv_clip;
+ m.m[3][2] = -(nearPlane + farPlane) * inv_clip;
m.m[0][3] = 0.0f;
m.m[1][3] = 0.0f;
m.m[2][3] = 0.0f;
@@ -1354,21 +1363,24 @@ void QMatrix4x4::frustum(qreal left, qreal right, qreal bottom, qreal top, qreal
// Construct the projection.
QMatrix4x4 m(1);
- qreal width = right - left;
- qreal invheight = top - bottom;
- qreal clip = farPlane - nearPlane;
- m.m[0][0] = 2.0f * nearPlane / width;
+ const qreal width = right - left;
+ const qreal invheight = top - bottom;
+ const qreal clip = farPlane - nearPlane;
+ const qreal inv_width = 1 / width;
+ const qreal inv_invheight = 1 / invheight;
+ const qreal inv_clip = 1 / clip;
+ m.m[0][0] = 2.0f * nearPlane * inv_width;
m.m[1][0] = 0.0f;
- m.m[2][0] = (left + right) / width;
+ m.m[2][0] = (left + right) * inv_width;
m.m[3][0] = 0.0f;
m.m[0][1] = 0.0f;
- m.m[1][1] = 2.0f * nearPlane / invheight;
- m.m[2][1] = (top + bottom) / invheight;
+ m.m[1][1] = 2.0f * nearPlane * inv_invheight;
+ m.m[2][1] = (top + bottom) * inv_invheight;
m.m[3][1] = 0.0f;
m.m[0][2] = 0.0f;
m.m[1][2] = 0.0f;
- m.m[2][2] = -(nearPlane + farPlane) / clip;
- m.m[3][2] = -2.0f * nearPlane * farPlane / clip;
+ m.m[2][2] = -(nearPlane + farPlane) * inv_clip;
+ m.m[3][2] = -2.0f * nearPlane * farPlane * inv_clip;
m.m[0][3] = 0.0f;
m.m[1][3] = 0.0f;
m.m[2][3] = -1.0f;
@@ -1394,12 +1406,13 @@ void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal f
// Construct the projection.
QMatrix4x4 m(1);
- qreal radians = (angle / 2.0f) * M_PI / 180.0f;
- qreal sine = qSin(radians);
+ const qreal radians = (angle * 0.5f) * Q_PI180;
+ const qreal sine = qSin(radians);
if (sine == 0.0f)
return;
- qreal cotan = qCos(radians) / sine;
- qreal clip = farPlane - nearPlane;
+ const qreal cotan = qCos(radians) / sine;
+ const qreal clip = farPlane - nearPlane;
+ const qreal inv_clip = 1 / clip;
m.m[0][0] = cotan / aspect;
m.m[1][0] = 0.0f;
m.m[2][0] = 0.0f;
@@ -1410,8 +1423,8 @@ void QMatrix4x4::perspective(qreal angle, qreal aspect, qreal nearPlane, qreal f
m.m[3][1] = 0.0f;
m.m[0][2] = 0.0f;
m.m[1][2] = 0.0f;
- m.m[2][2] = -(nearPlane + farPlane) / clip;
- m.m[3][2] = -(2.0f * nearPlane * farPlane) / clip;
+ m.m[2][2] = -(nearPlane + farPlane) * inv_clip;
+ m.m[3][2] = -(2.0f * nearPlane * farPlane) * inv_clip;
m.m[0][3] = 0.0f;
m.m[1][3] = 0.0f;
m.m[2][3] = -1.0f;
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index 626cb3c..da629e6 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -269,11 +269,12 @@ void QQuaternion::normalize()
return;
len = qSqrt(len);
+ const double inv_len = 1 / len;
- xp /= len;
- yp /= len;
- zp /= len;
- wp /= len;
+ xp *= inv_len;
+ yp *= inv_len;
+ zp *= inv_len;
+ wp *= inv_len;
}
/*!
@@ -357,7 +358,7 @@ QQuaternion QQuaternion::fromAxisAndAngle(const QVector3D& axis, qreal angle)
// http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q56
// We normalize the result just in case the values are close
// to zero, as suggested in the above FAQ.
- qreal a = (angle / 2.0f) * M_PI / 180.0f;
+ qreal a = (angle * 0.5f) * Q_PI180;
qreal s = qSin(a);
qreal c = qCos(a);
QVector3D ax = axis.normalized();
@@ -375,11 +376,12 @@ QQuaternion QQuaternion::fromAxisAndAngle
{
qreal length = qSqrt(x * x + y * y + z * z);
if (!qFuzzyIsNull(length - 1.0f) && !qFuzzyIsNull(length)) {
- x /= length;
- y /= length;
- z /= length;
+ const qreal inv_length = 1 / length;
+ x *= inv_length;
+ y *= inv_length;
+ z *= inv_length;
}
- qreal a = (angle / 2.0f) * M_PI / 180.0f;
+ qreal a = (angle * 0.5f) * Q_PI180;
qreal s = qSin(a);
qreal c = qCos(a);
return QQuaternion(c, x * s, y * s, z * s).normalized();
@@ -516,12 +518,13 @@ QQuaternion QQuaternion::slerp
// then revert to simple linear interpolation.
qreal factor1 = 1.0f - t;
qreal factor2 = t;
- if ((1.0f - dot) > 0.0000001) {
+ if ((1.0f - dot) > qreal(0.0000001)) {
qreal angle = qreal(qAcos(dot));
qreal sinOfAngle = qreal(qSin(angle));
- if (sinOfAngle > 0.0000001) {
- factor1 = qreal(qSin((1.0f - t) * angle)) / sinOfAngle;
- factor2 = qreal(qSin(t * angle)) / sinOfAngle;
+ if (sinOfAngle > qreal(0.0000001)) {
+ const qreal inv_sinOfAngle = 1 / sinOfAngle;
+ factor1 = qreal(qSin((1.0f - t) * angle)) * inv_sinOfAngle;
+ factor2 = qreal(qSin(t * angle)) * inv_sinOfAngle;
}
}
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index 2555a6f..a959979 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -216,9 +216,9 @@ void QVector2D::normalize()
return;
len = qSqrt(len);
-
- xp /= len;
- yp /= len;
+ const double inv_len = 1 / len;
+ xp *= inv_len;
+ yp *= inv_len;
}
/*!
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 9552e3a..a8cc807 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -233,10 +233,10 @@ void QVector3D::normalize()
return;
len = qSqrt(len);
-
- xp /= len;
- yp /= len;
- zp /= len;
+ const double inv_len = 1 / len;
+ xp *= inv_len;
+ yp *= inv_len;
+ zp *= inv_len;
}
/*!
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index 1691a6d..e4b2b82 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -285,11 +285,11 @@ void QVector4D::normalize()
return;
len = qSqrt(len);
-
- xp /= len;
- yp /= len;
- zp /= len;
- wp /= len;
+ const double inv_len = 1 / len;
+ xp *= inv_len;
+ yp *= inv_len;
+ zp *= inv_len;
+ wp *= inv_len;
}
/*!
@@ -459,7 +459,8 @@ QVector2D QVector4D::toVector2DAffine() const
{
if (qIsNull(wp))
return QVector2D();
- return QVector2D(xp / wp, yp / wp, 1);
+ const qreal inv_wp = 1 / wp;
+ return QVector2D(xp * inv_wp, yp * inv_wp, 1);
}
#endif
@@ -486,7 +487,8 @@ QVector3D QVector4D::toVector3DAffine() const
{
if (qIsNull(wp))
return QVector3D();
- return QVector3D(xp / wp, yp / wp, zp / wp, 1);
+ const qreal inv_wp = 1 / wp;
+ return QVector3D(xp * inv_wp, yp * inv_wp, zp * inv_wp, 1);
}
#endif