summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRhys Weatherley <rhys.weatherley@nokia.com>2009-09-21 01:30:06 (GMT)
committerRhys Weatherley <rhys.weatherley@nokia.com>2009-09-21 01:30:06 (GMT)
commit2dfdd7d0f937f2d3fe7cb5327ac199f701de7890 (patch)
tree52a16fa388dacd4788777b1dc008f56e8c9920f1
parent11fed1f64f43593a2890e0a3f27b4e2e7ebde783 (diff)
downloadQt-2dfdd7d0f937f2d3fe7cb5327ac199f701de7890.zip
Qt-2dfdd7d0f937f2d3fe7cb5327ac199f701de7890.tar.gz
Qt-2dfdd7d0f937f2d3fe7cb5327ac199f701de7890.tar.bz2
Increase precision when normalizing vectors
QVector3D::normalize() and other similar functions were losing precision when qreal was float, causing vectors with small lengths to normalize to (0, 0, 0). Do the length calculations with double precision to avoid this problem. Reviewed-by: Sarah Smith
-rw-r--r--src/gui/math3d/qquaternion.cpp12
-rw-r--r--src/gui/math3d/qvector2d.cpp8
-rw-r--r--src/gui/math3d/qvector3d.cpp10
-rw-r--r--src/gui/math3d/qvector4d.cpp12
4 files changed, 34 insertions, 8 deletions
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp
index e48bced..d5ec054 100644
--- a/src/gui/math3d/qquaternion.cpp
+++ b/src/gui/math3d/qquaternion.cpp
@@ -239,7 +239,11 @@ qreal QQuaternion::lengthSquared() const
*/
QQuaternion QQuaternion::normalized() const
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp) +
+ double(zp) * double(zp) +
+ double(wp) * double(wp);
if (qFuzzyIsNull(len - 1.0f))
return *this;
else if (!qFuzzyIsNull(len))
@@ -256,7 +260,11 @@ QQuaternion QQuaternion::normalized() const
*/
void QQuaternion::normalize()
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp) +
+ double(zp) * double(zp) +
+ double(wp) * double(wp);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;
diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp
index f12bec0..2555a6f 100644
--- a/src/gui/math3d/qvector2d.cpp
+++ b/src/gui/math3d/qvector2d.cpp
@@ -190,7 +190,9 @@ qreal QVector2D::lengthSquared() const
*/
QVector2D QVector2D::normalized() const
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp);
if (qFuzzyIsNull(len - 1.0f))
return *this;
else if (!qFuzzyIsNull(len))
@@ -207,7 +209,9 @@ QVector2D QVector2D::normalized() const
*/
void QVector2D::normalize()
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;
diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp
index 7d4ddf7..9552e3a 100644
--- a/src/gui/math3d/qvector3d.cpp
+++ b/src/gui/math3d/qvector3d.cpp
@@ -205,7 +205,10 @@ QVector3D::QVector3D(const QVector4D& vector)
*/
QVector3D QVector3D::normalized() const
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp) +
+ double(zp) * double(zp);
if (qFuzzyIsNull(len - 1.0f))
return *this;
else if (!qFuzzyIsNull(len))
@@ -222,7 +225,10 @@ QVector3D QVector3D::normalized() const
*/
void QVector3D::normalize()
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp) +
+ double(zp) * double(zp);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;
diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp
index 17acfff..1691a6d 100644
--- a/src/gui/math3d/qvector4d.cpp
+++ b/src/gui/math3d/qvector4d.cpp
@@ -255,7 +255,11 @@ qreal QVector4D::lengthSquared() const
*/
QVector4D QVector4D::normalized() const
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp) +
+ double(zp) * double(zp) +
+ double(wp) * double(wp);
if (qFuzzyIsNull(len - 1.0f))
return *this;
else if (!qFuzzyIsNull(len))
@@ -272,7 +276,11 @@ QVector4D QVector4D::normalized() const
*/
void QVector4D::normalize()
{
- qreal len = lengthSquared();
+ // Need some extra precision if the length is very small.
+ double len = double(xp) * double(xp) +
+ double(yp) * double(yp) +
+ double(zp) * double(zp) +
+ double(wp) * double(wp);
if (qFuzzyIsNull(len - 1.0f) || qFuzzyIsNull(len))
return;