From 22eae68e48d4edc18ba490e7c361faf6e9f054fd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 17 Sep 2008 16:14:28 +0000 Subject: [PATCH] From Mathias Froehlich, "This is a generic optimization that does not depend on any cpu or instruction set. The optimization is based on the observation that matrix matrix multiplication with a dense matrix 4x4 is 4^3 Operations whereas multiplication with a transform, or scale matrix is only 4^2 operations. Which is a gain of a *FACTOR*4* for these special cases. The change implements these special cases, provides a unit test for these implementation and converts uses of the expensiver dense matrix matrix routine with the specialized versions. Depending on the transform nodes in the scenegraph this change gives a noticable improovement. For example the osgforest code using the MatrixTransform is about 20% slower than the same codepath using the PositionAttitudeTransform instead of the MatrixTransform with this patch applied. If I remember right, the sse type optimizations did *not* provide a factor 4 improovement. Also these changes are totally independent of any cpu or instruction set architecture. So I would prefer to have this current kind of change instead of some hand coded and cpu dependent assembly stuff. If we need that hand tuned stuff, these can go on top of this changes which must provide than hand optimized additional variants for the specialized versions to give a even better result in the end. An other change included here is a change to rotation matrix from quaterion code. There is a sqrt call which couold be optimized away. Since we divide in effect by sqrt(length)*sqrt(length) which is just length ... " --- examples/osgdepthpeeling/osgdepthpeeling.cpp | 25 +- examples/osghangglide/osghangglide.cpp | 4 +- examples/osglogo/osglogo.cpp | 9 +- examples/osgsimulation/osgsimulation.cpp | 2 +- examples/osgunittests/UnitTests_osg.cpp | 297 ++++++++++++++++++ .../osgvertexprogram/osgvertexprogram.cpp | 4 +- include/osg/AnimationPath | 24 +- include/osg/Matrixd | 121 +++++++ include/osg/Matrixf | 121 +++++++ src/osg/AutoTransform.cpp | 27 +- src/osg/CameraView.cpp | 16 +- src/osg/Matrix_implementation.cpp | 110 ++++--- src/osg/PositionAttitudeTransform.cpp | 37 ++- src/osgManipulator/AntiSquish.cpp | 54 ++-- src/osgParticle/PrecipitationEffect.cpp | 4 +- src/osgSim/DOFTransform.cpp | 4 +- src/osgSim/Sector.cpp | 7 +- src/osgText/Text.cpp | 21 +- src/osgText/Text3D.cpp | 21 +- src/osgUtil/SceneGraphBuilder.cpp | 6 +- src/osgViewer/View.cpp | 2 +- 21 files changed, 723 insertions(+), 193 deletions(-) diff --git a/examples/osgdepthpeeling/osgdepthpeeling.cpp b/examples/osgdepthpeeling/osgdepthpeeling.cpp index 4b9e97522..f8b887db6 100644 --- a/examples/osgdepthpeeling/osgdepthpeeling.cpp +++ b/examples/osgdepthpeeling/osgdepthpeeling.cpp @@ -174,27 +174,12 @@ public: private: void rotate(float x, float y) { - osg::Matrixd baseMatrix = _modelGroupTransform->getMatrix(); + osg::Matrix baseMatrix = _modelGroupTransform->getMatrix(); - osg::Matrixd preTransMatrix; - osg::Matrixd postTransMatrix; - osg::Matrixd rotMatrixX; - osg::Matrixd rotMatrixZ; - - preTransMatrix.makeTranslate(_rotCenter); - postTransMatrix.makeTranslate(-_rotCenter); - - rotMatrixZ.makeRotate((x - _prevX) * 3., osg::Vec3d(0.0, 0.0,1.0)); - - baseMatrix.preMult(preTransMatrix); - baseMatrix.preMult(rotMatrixZ); - baseMatrix.preMult(postTransMatrix); - - rotMatrixX.makeRotate(-(y - _prevY) * 3., (baseMatrix * osg::Vec3d(1.0, 0.0,0.0))); - - baseMatrix.preMult(preTransMatrix); - baseMatrix.preMult(rotMatrixX); - baseMatrix.preMult(postTransMatrix); + baseMatrix.preMultTranslate(_rotCenter); + baseMatrix.preMultRotate(osg::Quat((x - _prevX) * 3, osg::Vec3d(0.0, 0.0, 1.0))); + baseMatrix.preMultRotate(osg::Quat(-(y - _prevY) * 3, (baseMatrix * osg::Vec3d(1.0, 0.0, 0.0)))); + baseMatrix.preMultTranslate(-_rotCenter); _modelGroupTransform->setMatrix(baseMatrix); diff --git a/examples/osghangglide/osghangglide.cpp b/examples/osghangglide/osghangglide.cpp index 3b68a6371..39058e58f 100644 --- a/examples/osghangglide/osghangglide.cpp +++ b/examples/osghangglide/osghangglide.cpp @@ -54,7 +54,7 @@ public: if (cv) { osg::Vec3 eyePointLocal = cv->getEyeLocal(); - matrix.preMult(osg::Matrix::translate(eyePointLocal.x(),eyePointLocal.y(),0.0f)); + matrix.preMultTranslate(osg::Vec3(eyePointLocal.x(),eyePointLocal.y(),0.0f)); } return true; } @@ -68,7 +68,7 @@ public: if (cv) { osg::Vec3 eyePointLocal = cv->getEyeLocal(); - matrix.postMult(osg::Matrix::translate(-eyePointLocal.x(),-eyePointLocal.y(),0.0f)); + matrix.postMultTranslate(osg::Vec3(-eyePointLocal.x(),-eyePointLocal.y(),0.0f)); } return true; } diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 0d36ae282..9fd972429 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -67,11 +67,10 @@ class MyBillboardTransform : public osg::PositionAttitudeTransform } - - matrix.preMult(osg::Matrix::translate(-_pivotPoint)* - osg::Matrix::rotate(_attitude)* - osg::Matrix::rotate(billboardRotation)* - osg::Matrix::translate(_position)); + matrix.preMultTranslate(_position); + matrix.preMultRotate(billboardRotation); + matrix.preMultRotate(_attitude); + matrix.preMultTranslate(_pivotPoint); return true; } diff --git a/examples/osgsimulation/osgsimulation.cpp b/examples/osgsimulation/osgsimulation.cpp index 4f32d1ea8..692c0a2cc 100644 --- a/examples/osgsimulation/osgsimulation.cpp +++ b/examples/osgsimulation/osgsimulation.cpp @@ -146,7 +146,7 @@ public: //osg::Matrixd matrix; ellipsoid->computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix); - matrix.preMult(osg::Matrix::rotate(_rotation)); + matrix.preMultRotate(_rotation); mt->setMatrix(matrix); } diff --git a/examples/osgunittests/UnitTests_osg.cpp b/examples/osgunittests/UnitTests_osg.cpp index 2bcdcf881..25f0e0440 100644 --- a/examples/osgunittests/UnitTests_osg.cpp +++ b/examples/osgunittests/UnitTests_osg.cpp @@ -19,6 +19,8 @@ #include "UnitTestFramework.h" #include +#include +#include #include #include @@ -84,4 +86,299 @@ OSGUTX_END_TESTSUITE OSGUTX_AUTOREGISTER_TESTSUITE_AT(Vec3, root.osg) +/////////////////////////////////////////////////////////////////////////////// +// +// Matrix Tests +// +class MatrixTestFixture +{ +public: + + MatrixTestFixture(); + + void testPreMultTranslate(const osgUtx::TestContext& ctx); + void testPostMultTranslate(const osgUtx::TestContext& ctx); + void testPreMultScale(const osgUtx::TestContext& ctx); + void testPostMultScale(const osgUtx::TestContext& ctx); + void testPreMultRotate(const osgUtx::TestContext& ctx); + void testPostMultRotate(const osgUtx::TestContext& ctx); + +private: + + // Some convenience variables for use in the tests + Matrixd _md; + Matrixf _mf; + Vec3d _v3d; + Vec3 _v3; + Quat _q1; + Quat _q2; + Quat _q3; + Quat _q4; + +}; + +MatrixTestFixture::MatrixTestFixture(): + _md(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + _mf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), + _v3d(1, 2, 3), + _v3(1, 2, 3), + _q1(1, 0, 0, 0), + _q2(0, 1, 0, 0), + _q3(0, 0, 1, 0), + _q4(0, 0, 0, 1) +{ +} + +void MatrixTestFixture::testPreMultTranslate(const osgUtx::TestContext&) +{ + osg::Matrixd tdo; + osg::Matrixd tdn; + osg::Matrixf tfo; + osg::Matrixf tfn; + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::translate(_v3d)); + tdn.preMultTranslate(_v3d); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::translate(_v3)); + tdn.preMultTranslate(_v3); + OSGUTX_TEST_F( tdo == tdn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::translate(_v3d)); + tfn.preMultTranslate(_v3d); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::translate(_v3)); + tfn.preMultTranslate(_v3); + OSGUTX_TEST_F( tfo == tfn ) +} + +void MatrixTestFixture::testPostMultTranslate(const osgUtx::TestContext&) +{ + osg::Matrixd tdo; + osg::Matrixd tdn; + osg::Matrixf tfo; + osg::Matrixf tfn; + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::translate(_v3d)); + tdn.postMultTranslate(_v3d); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::translate(_v3)); + tdn.postMultTranslate(_v3); + OSGUTX_TEST_F( tdo == tdn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::translate(_v3d)); + tfn.postMultTranslate(_v3d); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::translate(_v3)); + tfn.postMultTranslate(_v3); + OSGUTX_TEST_F( tfo == tfn ) +} + +void MatrixTestFixture::testPreMultScale(const osgUtx::TestContext&) +{ + osg::Matrixd tdo; + osg::Matrixd tdn; + osg::Matrixf tfo; + osg::Matrixf tfn; + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::scale(_v3d)); + tdn.preMultScale(_v3d); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::scale(_v3)); + tdn.preMultScale(_v3); + OSGUTX_TEST_F( tdo == tdn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::scale(_v3d)); + tfn.preMultScale(_v3d); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::scale(_v3)); + tfn.preMultScale(_v3); + OSGUTX_TEST_F( tfo == tfn ) +} + +void MatrixTestFixture::testPostMultScale(const osgUtx::TestContext&) +{ + osg::Matrixd tdo; + osg::Matrixd tdn; + osg::Matrixf tfo; + osg::Matrixf tfn; + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::scale(_v3d)); + tdn.postMultScale(_v3d); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::scale(_v3)); + tdn.postMultScale(_v3); + OSGUTX_TEST_F( tdo == tdn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::scale(_v3d)); + tfn.postMultScale(_v3d); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::scale(_v3)); + tfn.postMultScale(_v3); + OSGUTX_TEST_F( tfo == tfn ) +} + +void MatrixTestFixture::testPreMultRotate(const osgUtx::TestContext&) +{ + osg::Matrixd tdo; + osg::Matrixd tdn; + osg::Matrixf tfo; + osg::Matrixf tfn; + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::rotate(_q1)); + tdn.preMultRotate(_q1); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::rotate(_q2)); + tdn.preMultRotate(_q2); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::rotate(_q3)); + tdn.preMultRotate(_q3); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.preMult(osg::Matrixd::rotate(_q4)); + tdn.preMultRotate(_q4); + OSGUTX_TEST_F( tdo == tdn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::rotate(_q1)); + tfn.preMultRotate(_q1); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::rotate(_q2)); + tfn.preMultRotate(_q2); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::rotate(_q3)); + tfn.preMultRotate(_q3); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.preMult(osg::Matrixf::rotate(_q4)); + tfn.preMultRotate(_q4); + OSGUTX_TEST_F( tfo == tfn ) +} + +void MatrixTestFixture::testPostMultRotate(const osgUtx::TestContext&) +{ + osg::Matrixd tdo; + osg::Matrixd tdn; + osg::Matrixf tfo; + osg::Matrixf tfn; + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::rotate(_q1)); + tdn.postMultRotate(_q1); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::rotate(_q2)); + tdn.postMultRotate(_q2); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::rotate(_q3)); + tdn.postMultRotate(_q3); + OSGUTX_TEST_F( tdo == tdn ) + + tdo = _md; + tdn = _md; + tdo.postMult(osg::Matrixd::rotate(_q4)); + tdn.postMultRotate(_q4); + OSGUTX_TEST_F( tdo == tdn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::rotate(_q1)); + tfn.postMultRotate(_q1); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::rotate(_q2)); + tfn.postMultRotate(_q2); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::rotate(_q3)); + tfn.postMultRotate(_q3); + OSGUTX_TEST_F( tfo == tfn ) + + tfo = _mf; + tfn = _mf; + tfo.postMult(osg::Matrixf::rotate(_q4)); + tfn.postMultRotate(_q4); + OSGUTX_TEST_F( tfo == tfn ) +} + +OSGUTX_BEGIN_TESTSUITE(Matrix) + OSGUTX_ADD_TESTCASE(MatrixTestFixture, testPreMultTranslate) + OSGUTX_ADD_TESTCASE(MatrixTestFixture, testPostMultTranslate) + OSGUTX_ADD_TESTCASE(MatrixTestFixture, testPreMultScale) + OSGUTX_ADD_TESTCASE(MatrixTestFixture, testPostMultScale) + OSGUTX_ADD_TESTCASE(MatrixTestFixture, testPreMultRotate) + OSGUTX_ADD_TESTCASE(MatrixTestFixture, testPostMultRotate) +OSGUTX_END_TESTSUITE + +OSGUTX_AUTOREGISTER_TESTSUITE_AT(Matrix, root.osg) + + } diff --git a/examples/osgvertexprogram/osgvertexprogram.cpp b/examples/osgvertexprogram/osgvertexprogram.cpp index 636036be5..18c3e17c3 100644 --- a/examples/osgvertexprogram/osgvertexprogram.cpp +++ b/examples/osgvertexprogram/osgvertexprogram.cpp @@ -226,7 +226,7 @@ public: if (cv) { osg::Vec3 eyePointLocal = cv->getEyeLocal(); - matrix.preMult(osg::Matrix::translate(eyePointLocal)); + matrix.preMultTranslate(eyePointLocal); } return true; } @@ -238,7 +238,7 @@ public: if (cv) { osg::Vec3 eyePointLocal = cv->getEyeLocal(); - matrix.postMult(osg::Matrix::translate(-eyePointLocal)); + matrix.postMultTranslate(-eyePointLocal); } return true; } diff --git a/include/osg/AnimationPath b/include/osg/AnimationPath index 1c7168216..659f458c5 100644 --- a/include/osg/AnimationPath +++ b/include/osg/AnimationPath @@ -91,30 +91,30 @@ class OSG_EXPORT AnimationPath : public virtual osg::Object inline void getMatrix(Matrixf& matrix) const { - matrix.makeScale(_scale); - matrix.postMult(osg::Matrixf::rotate(_rotation)); - matrix.postMult(osg::Matrixf::translate(_position)); + matrix.makeRotate(_rotation); + matrix.preMultScale(_scale); + matrix.postMultTranslate(_position); } inline void getMatrix(Matrixd& matrix) const { - matrix.makeScale(_scale); - matrix.postMult(osg::Matrixd::rotate(_rotation)); - matrix.postMult(osg::Matrixd::translate(_position)); + matrix.makeRotate(_rotation); + matrix.preMultScale(_scale); + matrix.postMultTranslate(_position); } inline void getInverse(Matrixf& matrix) const { - matrix.makeScale(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()); - matrix.preMult(osg::Matrixf::rotate(_rotation.inverse())); - matrix.preMult(osg::Matrixf::translate(-_position)); + matrix.makeRotate(_rotation.inverse()); + matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z())); + matrix.preMultTranslate(-_position); } inline void getInverse(Matrixd& matrix) const { - matrix.makeScale(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z()); - matrix.preMult(osg::Matrixd::rotate(_rotation.inverse())); - matrix.preMult(osg::Matrixd::translate(-_position)); + matrix.makeRotate(_rotation.inverse()); + matrix.postMultScale(osg::Vec3d(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z())); + matrix.preMultTranslate(-_position); } protected: diff --git a/include/osg/Matrixd b/include/osg/Matrixd index 03ef6aa2f..eb671c52d 100644 --- a/include/osg/Matrixd +++ b/include/osg/Matrixd @@ -347,6 +347,25 @@ class OSG_EXPORT Matrixd void preMult( const Matrixd& ); void postMult( const Matrixd& ); + /** Optimized version of preMult(translate(v)); */ + inline void preMultTranslate( const Vec3d& v ); + inline void preMultTranslate( const Vec3f& v ); + /** Optimized version of postMult(translate(v)); */ + inline void postMultTranslate( const Vec3d& v ); + inline void postMultTranslate( const Vec3f& v ); + + /** Optimized version of preMult(scale(v)); */ + inline void preMultScale( const Vec3d& v ); + inline void preMultScale( const Vec3f& v ); + /** Optimized version of postMult(scale(v)); */ + inline void postMultScale( const Vec3d& v ); + inline void postMultScale( const Vec3f& v ); + + /** Optimized version of preMult(rotate(q)); */ + inline void preMultRotate( const Quat& q ); + /** Optimized version of postMult(rotate(q)); */ + inline void postMultRotate( const Quat& q ); + inline void operator *= ( const Matrixd& other ) { if( this == &other ) { Matrixd temp(other); @@ -647,6 +666,108 @@ inline Vec3d Matrixd::transform3x3(const Matrixd& m,const Vec3d& v) (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ; } +inline void Matrixd::preMultTranslate( const Vec3d& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + double tmp = v[i]; + if (tmp == 0) + continue; + _mat[3][0] += tmp*_mat[i][0]; + _mat[3][1] += tmp*_mat[i][1]; + _mat[3][2] += tmp*_mat[i][2]; + _mat[3][3] += tmp*_mat[i][3]; + } +} + +inline void Matrixd::preMultTranslate( const Vec3f& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + float tmp = v[i]; + if (tmp == 0) + continue; + _mat[3][0] += tmp*_mat[i][0]; + _mat[3][1] += tmp*_mat[i][1]; + _mat[3][2] += tmp*_mat[i][2]; + _mat[3][3] += tmp*_mat[i][3]; + } +} + +inline void Matrixd::postMultTranslate( const Vec3d& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + double tmp = v[i]; + if (tmp == 0) + continue; + _mat[0][i] += tmp*_mat[0][3]; + _mat[1][i] += tmp*_mat[1][3]; + _mat[2][i] += tmp*_mat[2][3]; + _mat[3][i] += tmp*_mat[3][3]; + } +} + +inline void Matrixd::postMultTranslate( const Vec3f& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + float tmp = v[i]; + if (tmp == 0) + continue; + _mat[0][i] += tmp*_mat[0][3]; + _mat[1][i] += tmp*_mat[1][3]; + _mat[2][i] += tmp*_mat[2][3]; + _mat[3][i] += tmp*_mat[3][3]; + } +} + +inline void Matrixd::preMultScale( const Vec3d& v ) +{ + _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0]; + _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1]; + _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2]; +} + +inline void Matrixd::preMultScale( const Vec3f& v ) +{ + _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0]; + _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1]; + _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2]; +} + +inline void Matrixd::postMultScale( const Vec3d& v ) +{ + _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0]; + _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1]; + _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2]; +} + +inline void Matrixd::postMultScale( const Vec3f& v ) +{ + _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0]; + _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1]; + _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2]; +} + +inline void Matrixd::preMultRotate( const Quat& q ) +{ + if (q.zeroRotation()) + return; + Matrixd r; + r.setRotate(q); + preMult(r); +} + +inline void Matrixd::postMultRotate( const Quat& q ) +{ + if (q.zeroRotation()) + return; + Matrixd r; + r.setRotate(q); + postMult(r); +} + inline Vec3f operator* (const Vec3f& v, const Matrixd& m ) { return m.preMult(v); diff --git a/include/osg/Matrixf b/include/osg/Matrixf index b7a20c9fc..178d46b6e 100644 --- a/include/osg/Matrixf +++ b/include/osg/Matrixf @@ -349,6 +349,25 @@ class OSG_EXPORT Matrixf void preMult( const Matrixf& ); void postMult( const Matrixf& ); + /** Optimized version of preMult(translate(v)); */ + inline void preMultTranslate( const Vec3d& v ); + inline void preMultTranslate( const Vec3f& v ); + /** Optimized version of postMult(translate(v)); */ + inline void postMultTranslate( const Vec3d& v ); + inline void postMultTranslate( const Vec3f& v ); + + /** Optimized version of preMult(scale(v)); */ + inline void preMultScale( const Vec3d& v ); + inline void preMultScale( const Vec3f& v ); + /** Optimized version of postMult(scale(v)); */ + inline void postMultScale( const Vec3d& v ); + inline void postMultScale( const Vec3f& v ); + + /** Optimized version of preMult(rotate(q)); */ + inline void preMultRotate( const Quat& q ); + /** Optimized version of postMult(rotate(q)); */ + inline void postMultRotate( const Quat& q ); + inline void operator *= ( const Matrixf& other ) { if( this == &other ) { Matrixf temp(other); @@ -641,6 +660,108 @@ inline Vec3d Matrixf::transform3x3(const Matrixf& m,const Vec3d& v) (m._mat[2][0]*v.x() + m._mat[2][1]*v.y() + m._mat[2][2]*v.z()) ) ; } +inline void Matrixf::preMultTranslate( const Vec3d& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + double tmp = v[i]; + if (tmp == 0) + continue; + _mat[3][0] += tmp*_mat[i][0]; + _mat[3][1] += tmp*_mat[i][1]; + _mat[3][2] += tmp*_mat[i][2]; + _mat[3][3] += tmp*_mat[i][3]; + } +} + +inline void Matrixf::preMultTranslate( const Vec3f& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + float tmp = v[i]; + if (tmp == 0) + continue; + _mat[3][0] += tmp*_mat[i][0]; + _mat[3][1] += tmp*_mat[i][1]; + _mat[3][2] += tmp*_mat[i][2]; + _mat[3][3] += tmp*_mat[i][3]; + } +} + +inline void Matrixf::postMultTranslate( const Vec3d& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + double tmp = v[i]; + if (tmp == 0) + continue; + _mat[0][i] += tmp*_mat[0][3]; + _mat[1][i] += tmp*_mat[1][3]; + _mat[2][i] += tmp*_mat[2][3]; + _mat[3][i] += tmp*_mat[3][3]; + } +} + +inline void Matrixf::postMultTranslate( const Vec3f& v ) +{ + for (unsigned i = 0; i < 3; ++i) + { + float tmp = v[i]; + if (tmp == 0) + continue; + _mat[0][i] += tmp*_mat[0][3]; + _mat[1][i] += tmp*_mat[1][3]; + _mat[2][i] += tmp*_mat[2][3]; + _mat[3][i] += tmp*_mat[3][3]; + } +} + +inline void Matrixf::preMultScale( const Vec3d& v ) +{ + _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0]; + _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1]; + _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2]; +} + +inline void Matrixf::preMultScale( const Vec3f& v ) +{ + _mat[0][0] *= v[0]; _mat[0][1] *= v[0]; _mat[0][2] *= v[0]; _mat[0][3] *= v[0]; + _mat[1][0] *= v[1]; _mat[1][1] *= v[1]; _mat[1][2] *= v[1]; _mat[1][3] *= v[1]; + _mat[2][0] *= v[2]; _mat[2][1] *= v[2]; _mat[2][2] *= v[2]; _mat[2][3] *= v[2]; +} + +inline void Matrixf::postMultScale( const Vec3d& v ) +{ + _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0]; + _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1]; + _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2]; +} + +inline void Matrixf::postMultScale( const Vec3f& v ) +{ + _mat[0][0] *= v[0]; _mat[1][0] *= v[0]; _mat[2][0] *= v[0]; _mat[3][0] *= v[0]; + _mat[0][1] *= v[1]; _mat[1][1] *= v[1]; _mat[2][1] *= v[1]; _mat[3][1] *= v[1]; + _mat[0][2] *= v[2]; _mat[1][2] *= v[2]; _mat[2][2] *= v[2]; _mat[3][2] *= v[2]; +} + + +inline void Matrixf::preMultRotate( const Quat& q ) +{ + if (q.zeroRotation()) + return; + Matrixf r; + r.setRotate(q); + preMult(r); +} + +inline void Matrixf::postMultRotate( const Quat& q ) +{ + if (q.zeroRotation()) + return; + Matrixf r; + r.setRotate(q); + postMult(r); +} inline Vec3f operator* (const Vec3f& v, const Matrixf& m ) { diff --git a/src/osg/AutoTransform.cpp b/src/osg/AutoTransform.cpp index aa99d4783..ee670c14c 100644 --- a/src/osg/AutoTransform.cpp +++ b/src/osg/AutoTransform.cpp @@ -83,19 +83,22 @@ bool AutoTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const bool AutoTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const { + if (_scale.x() == 0.0 || _scale.y() == 0.0 || _scale.z() == 0.0) + return false; + if (_referenceFrame==RELATIVE_RF) { - matrix.postMult(osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_rotation.inverse())* - osg::Matrix::scale(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z())* - osg::Matrix::translate(_pivotPoint)); + matrix.postMultTranslate(-_position); + matrix.postMultRotate(_rotation.inverse()); + matrix.postMultScale(Vec3d(1.0/_scale.x(), 1.0/_scale.y(), 1.0/_scale.z())); + matrix.postMultTranslate(_pivotPoint); } else // absolute { - matrix = osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_rotation.inverse())* - osg::Matrix::scale(1.0/_scale.x(),1.0/_scale.y(),1.0/_scale.z())* - osg::Matrix::translate(_pivotPoint); + matrix.makeRotate(_rotation.inverse()); + matrix.preMultTranslate(-_position); + matrix.postMultScale(Vec3d(1.0/_scale.x(), 1.0/_scale.y(), 1.0/_scale.z())); + matrix.postMultTranslate(_pivotPoint); } return true; } @@ -104,10 +107,10 @@ void AutoTransform::computeMatrix() const { if (!_matrixDirty) return; - _cachedMatrix.set(osg::Matrix::translate(-_pivotPoint)* - osg::Matrix::scale(_scale)* - osg::Matrix::rotate(_rotation)* - osg::Matrix::translate(_position)); + _cachedMatrix.makeRotate(_rotation); + _cachedMatrix.postMultTranslate(_position); + _cachedMatrix.preMultScale(_scale); + _cachedMatrix.preMultTranslate(-_pivotPoint); _matrixDirty = false; } diff --git a/src/osg/CameraView.cpp b/src/osg/CameraView.cpp index 2630bf820..62a6d34cb 100644 --- a/src/osg/CameraView.cpp +++ b/src/osg/CameraView.cpp @@ -25,13 +25,13 @@ bool CameraView::computeLocalToWorldMatrix(Matrix& matrix,NodeVisitor*) const { if (_referenceFrame==RELATIVE_RF) { - matrix.preMult(osg::Matrix::rotate(_attitude)* - osg::Matrix::translate(_position)); + matrix.preMultTranslate(_position); + matrix.preMultRotate(_attitude); } else // absolute { - matrix = osg::Matrix::rotate(_attitude)* - osg::Matrix::translate(_position); + matrix.makeRotate(_attitude); + matrix.postMultTranslate(_position); } return true; } @@ -41,13 +41,13 @@ bool CameraView::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const { if (_referenceFrame==RELATIVE_RF) { - matrix.postMult(osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_attitude.inverse())); + matrix.postMultTranslate(-_position); + matrix.postMultRotate(_attitude.inverse()); } else // absolute { - matrix = osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_attitude.inverse()); + matrix.makeRotate(_attitude.inverse()); + matrix.preMultTranslate(-_position); } return true; } diff --git a/src/osg/Matrix_implementation.cpp b/src/osg/Matrix_implementation.cpp index be906659d..980f8d7cb 100644 --- a/src/osg/Matrix_implementation.cpp +++ b/src/osg/Matrix_implementation.cpp @@ -18,6 +18,7 @@ #include +#include #include using namespace osg; @@ -62,56 +63,71 @@ void Matrix_implementation::set( value_type a00, value_type a01, value_type a02, #define QZ q._v[2] #define QW q._v[3] -void Matrix_implementation::setRotate(const Quat& q_in) +void Matrix_implementation::setRotate(const Quat& q) { - Quat q(q_in); double length2 = q.length2(); - if (length2!=1.0 && length2!=0) + if (fabs(length2) <= std::numeric_limits::min()) { - // normalize quat if required. - q /= sqrt(length2); + _mat[0][0] = 0.0; _mat[1][0] = 0.0; _mat[2][0] = 0.0; + _mat[0][1] = 0.0; _mat[1][1] = 0.0; _mat[2][1] = 0.0; + _mat[0][2] = 0.0; _mat[1][2] = 0.0; _mat[2][2] = 0.0; + } + else + { + double rlength2; + // normalize quat if required. + // We can avoid the expensive sqrt in this case since all 'coefficients' below are products of two q components. + // That is a square of a square root, so it is possible to avoid that + if (length2 != 1.0) + { + rlength2 = 2.0/length2; + } + else + { + rlength2 = 2.0; + } + + // Source: Gamasutra, Rotating Objects Using Quaternions + // + //http://www.gamasutra.com/features/19980703/quaternions_01.htm + + double wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; + + // calculate coefficients + x2 = rlength2*QX; + y2 = rlength2*QY; + z2 = rlength2*QZ; + + xx = QX * x2; + xy = QX * y2; + xz = QX * z2; + + yy = QY * y2; + yz = QY * z2; + zz = QZ * z2; + + wx = QW * x2; + wy = QW * y2; + wz = QW * z2; + + // Note. Gamasutra gets the matrix assignments inverted, resulting + // in left-handed rotations, which is contrary to OpenGL and OSG's + // methodology. The matrix assignment has been altered in the next + // few lines of code to do the right thing. + // Don Burns - Oct 13, 2001 + _mat[0][0] = 1.0 - (yy + zz); + _mat[1][0] = xy - wz; + _mat[2][0] = xz + wy; + + + _mat[0][1] = xy + wz; + _mat[1][1] = 1.0 - (xx + zz); + _mat[2][1] = yz - wx; + + _mat[0][2] = xz - wy; + _mat[1][2] = yz + wx; + _mat[2][2] = 1.0 - (xx + yy); } - - // Source: Gamasutra, Rotating Objects Using Quaternions - // - //http://www.gamasutra.com/features/19980703/quaternions_01.htm - - double wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; - - // calculate coefficients - x2 = QX + QX; - y2 = QY + QY; - z2 = QZ + QZ; - - xx = QX * x2; - xy = QX * y2; - xz = QX * z2; - - yy = QY * y2; - yz = QY * z2; - zz = QZ * z2; - - wx = QW * x2; - wy = QW * y2; - wz = QW * z2; - - // Note. Gamasutra gets the matrix assignments inverted, resulting - // in left-handed rotations, which is contrary to OpenGL and OSG's - // methodology. The matrix assignment has been altered in the next - // few lines of code to do the right thing. - // Don Burns - Oct 13, 2001 - _mat[0][0] = 1.0 - (yy + zz); - _mat[1][0] = xy - wz; - _mat[2][0] = xz + wy; - - - _mat[0][1] = xy + wz; - _mat[1][1] = 1.0 - (xx + zz); - _mat[2][1] = yz - wx; - - _mat[0][2] = xz - wy; - _mat[1][2] = yz + wx; - _mat[2][2] = 1.0 - (xx + yy); #if 0 _mat[0][3] = 0.0; @@ -903,7 +919,7 @@ void Matrix_implementation::makeLookAt(const Vec3d& eye,const Vec3d& center,cons s[2], u[2], -f[2], 0.0, 0.0, 0.0, 0.0, 1.0); - preMult(Matrix_implementation::translate(-eye)); + preMultTranslate(-eye); } diff --git a/src/osg/PositionAttitudeTransform.cpp b/src/osg/PositionAttitudeTransform.cpp index 8294b7bfc..1be9ed8c4 100644 --- a/src/osg/PositionAttitudeTransform.cpp +++ b/src/osg/PositionAttitudeTransform.cpp @@ -15,7 +15,7 @@ using namespace osg; PositionAttitudeTransform::PositionAttitudeTransform(): - _scale(1.0f,1.0f,1.0f) + _scale(1.0,1.0,1.0) { } @@ -23,17 +23,17 @@ bool PositionAttitudeTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVis { if (_referenceFrame==RELATIVE_RF) { - matrix.preMult(osg::Matrix::translate(-_pivotPoint)* - osg::Matrix::scale(_scale)* - osg::Matrix::rotate(_attitude)* - osg::Matrix::translate(_position)); + matrix.preMultTranslate(_position); + matrix.preMultRotate(_attitude); + matrix.preMultScale(_scale); + matrix.preMultTranslate(-_pivotPoint); } else // absolute { - matrix = osg::Matrix::translate(-_pivotPoint)* - osg::Matrix::scale(_scale)* - osg::Matrix::rotate(_attitude)* - osg::Matrix::translate(_position); + matrix.makeRotate(_attitude); + matrix.postMultTranslate(_position); + matrix.preMultScale(_scale); + matrix.preMultTranslate(-_pivotPoint); } return true; } @@ -41,19 +41,22 @@ bool PositionAttitudeTransform::computeLocalToWorldMatrix(Matrix& matrix,NodeVis bool PositionAttitudeTransform::computeWorldToLocalMatrix(Matrix& matrix,NodeVisitor*) const { + if (_scale.x() == 0.0 || _scale.y() == 0.0 || _scale.z() == 0.0) + return false; + if (_referenceFrame==RELATIVE_RF) { - matrix.postMult(osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_attitude.inverse())* - osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* - osg::Matrix::translate(_pivotPoint)); + matrix.postMultTranslate(-_position); + matrix.postMultRotate(_attitude.inverse()); + matrix.postMultScale(Vec3d(1.0/_scale.x(), 1.0/_scale.y(), 1.0/_scale.z())); + matrix.postMultTranslate(_pivotPoint); } else // absolute { - matrix = osg::Matrix::translate(-_position)* - osg::Matrix::rotate(_attitude.inverse())* - osg::Matrix::scale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.z())* - osg::Matrix::translate(_pivotPoint); + matrix.makeRotate(_attitude.inverse()); + matrix.preMultTranslate(-_position); + matrix.postMultScale(Vec3d(1.0/_scale.x(), 1.0/_scale.y(), 1.0/_scale.z())); + matrix.postMultTranslate(_pivotPoint); } return true; } diff --git a/src/osgManipulator/AntiSquish.cpp b/src/osgManipulator/AntiSquish.cpp index 6aad20d28..a3f9b465d 100644 --- a/src/osgManipulator/AntiSquish.cpp +++ b/src/osgManipulator/AntiSquish.cpp @@ -116,15 +116,12 @@ osg::Matrix AntiSquish::computeUnSquishedMatrix(const osg::Matrix& LTW, bool& fl // if (_usePivot) { - osg::Matrix tmpPivot; - tmpPivot.setTrans(-_pivot); - unsquished.postMult(tmpPivot); + unsquished.postMultTranslate(-_pivot); osg::Matrix tmps, invtmps; so.get(tmps); - invtmps = osg::Matrix::inverse(tmps); - if (invtmps.isNaN()) - { + if (!invtmps.invert(tmps)) + { flag = false; return osg::Matrix::identity(); } @@ -132,49 +129,50 @@ osg::Matrix AntiSquish::computeUnSquishedMatrix(const osg::Matrix& LTW, bool& fl //SO^ unsquished.postMult(invtmps); //S - unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2])); + unsquished.postMultScale(s); //SO unsquished.postMult(tmps); - tmpPivot.makeIdentity(); - osg::Matrix tmpr; - r.get(tmpr); //R - unsquished.postMult(tmpr); + unsquished.postMultRotate(r); //T - unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2])); + unsquished.postMultTranslate(t); osg::Matrix invltw; - invltw = osg::Matrix::inverse(LTW); - if (invltw.isNaN()) - { - flag =false; + if (!invltw.invert(LTW)) + { + flag = false; return osg::Matrix::identity(); } // LTW^ unsquished.postMult( invltw ); // Position - tmpPivot.makeIdentity(); if (_usePosition) - tmpPivot.setTrans(_position); + unsquished.postMult(_position); else - tmpPivot.setTrans(_pivot); - - unsquished.postMult(tmpPivot); + unsquished.postMult(_pivot); } else { osg::Matrix tmps, invtmps; so.get(tmps); - invtmps = osg::Matrix::inverse(tmps); + if (!invtmps.invert(tmps)) + { + flag = false; + return osg::Matrix::identity(); + } unsquished.postMult(invtmps); - unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2])); + unsquished.postMultScale(s); unsquished.postMult(tmps); - osg::Matrix tmpr; - r.get(tmpr); - unsquished.postMult(tmpr); - unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2])); - unsquished.postMult( osg::Matrix::inverse(LTW) ); + unsquished.postMultRotate(r); + unsquished.postMultTranslate(t); + osg::Matrix invltw; + if (!invltw.invert(LTW)) + { + flag = false; + return osg::Matrix::identity(); + } + unsquished.postMult( invltw ); } if (unsquished.isNaN()) diff --git a/src/osgParticle/PrecipitationEffect.cpp b/src/osgParticle/PrecipitationEffect.cpp index 38e3f0f42..6f067f2b2 100644 --- a/src/osgParticle/PrecipitationEffect.cpp +++ b/src/osgParticle/PrecipitationEffect.cpp @@ -837,8 +837,8 @@ bool PrecipitationEffect::build(const osg::Vec3 eyeLocal, int i, int j, int k, f } *mymodelview = *(cv->getModelViewMatrix()); - mymodelview->preMult(osg::Matrix::translate(position)); - mymodelview->preMult(osg::Matrix::scale(scale)); + mymodelview->preMultTranslate(position); + mymodelview->preMultScale(scale); cv->updateCalculatedNearFar(*(cv->getModelViewMatrix()),bb); diff --git a/src/osgSim/DOFTransform.cpp b/src/osgSim/DOFTransform.cpp index b6c55bd7e..a61205dde 100644 --- a/src/osgSim/DOFTransform.cpp +++ b/src/osgSim/DOFTransform.cpp @@ -132,7 +132,7 @@ bool DOFTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisito //and scale: - current.preMult(osg::Matrix::scale(getCurrentScale())); + current.preMultScale(getCurrentScale()); l2w.postMult(current); @@ -201,7 +201,7 @@ bool DOFTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisito } //and scale: - current.postMult(osg::Matrix::scale(1./getCurrentScale()[0], 1./getCurrentScale()[1], 1./getCurrentScale()[2])); + current.postMultScale(osg::Vec3d(1./getCurrentScale()[0], 1./getCurrentScale()[1], 1./getCurrentScale()[2])); w2l.postMult(current); diff --git a/src/osgSim/Sector.cpp b/src/osgSim/Sector.cpp index 80a2f238a..ef3e9733b 100644 --- a/src/osgSim/Sector.cpp +++ b/src/osgSim/Sector.cpp @@ -234,10 +234,9 @@ void DirectionalSector::computeMatrix() double pitch = atan2(_direction[2], sqrt(_direction[0]*_direction[0] + _direction[1]*_direction[1])); double roll = _rollAngle; - _local_to_LP = osg::Matrixd::identity(); - _local_to_LP.preMult(osg::Matrix::rotate(heading, 0.0, 0.0, -1.0)); - _local_to_LP.preMult(osg::Matrix::rotate(pitch, 1.0, 0.0, 0.0)); - _local_to_LP.preMult(osg::Matrix::rotate(roll, 0.0, 1.0, 0.0)); + _local_to_LP.setRotate(osg::Quat(heading, 0.0, 0.0, -1.0)); + _local_to_LP.preMultRotate(osg::Quat(pitch, 1.0, 0.0, 0.0)); + _local_to_LP.preMultRotate(osg::Quat(roll, 0.0, 1.0, 0.0)); } void DirectionalSector::setDirection(const osg::Vec3& direction) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 8ee03a518..a50120a83 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -640,15 +640,14 @@ void Text::computePositions(unsigned int contextID) const atc._modelview.setTrans(trans); } - if (!_rotation.zeroRotation() ) - { - matrix.postMult(osg::Matrix::rotate(_rotation)); - } + matrix.postMultRotate(_rotation); if (_characterSizeMode!=OBJECT_COORDS) { - osg::Matrix M(rotate_matrix*osg::Matrix::translate(_position)*atc._modelview); + osg::Matrix M(rotate_matrix); + M.postMultTranslate(_position); + M.postMult(atc._modelview); osg::Matrix& P = atc._projection; // compute the pixel size vector. @@ -693,12 +692,12 @@ void Text::computePositions(unsigned int contextID) const if (P10<0) scale_font_vert=-scale_font_vert; - matrix.postMult(osg::Matrix::scale(scale_font_hori, scale_font_vert,1.0f)); + matrix.postMultScale(osg::Vec3f(scale_font_hori, scale_font_vert,1.0f)); } else if (pixelSizeVert>getFontHeight()) { float scale_font = getFontHeight()/pixelSizeVert; - matrix.postMult(osg::Matrix::scale(scale_font, scale_font,1.0f)); + matrix.postMultScale(osg::Vec3f(scale_font, scale_font,1.0f)); } } @@ -708,13 +707,13 @@ void Text::computePositions(unsigned int contextID) const matrix.postMult(rotate_matrix); } - matrix.postMult(osg::Matrix::translate(_position)); + matrix.postMultTranslate(_position); } else if (!_rotation.zeroRotation()) { - matrix.makeTranslate(-_offset); - matrix.postMult(osg::Matrix::rotate(_rotation)); - matrix.postMult(osg::Matrix::translate(_position)); + matrix.makeRotate(_rotation); + matrix.preMultTranslate(-_offset); + matrix.postMultTranslate(_position); } else { diff --git a/src/osgText/Text3D.cpp b/src/osgText/Text3D.cpp index 5ba6c6b32..521d82d2a 100644 --- a/src/osgText/Text3D.cpp +++ b/src/osgText/Text3D.cpp @@ -457,22 +457,11 @@ void Text3D::computePositions(unsigned int contextID) const float scale = _font->getScale(); - osg::Matrix scaleMatrix = osg::Matrix::scale(scale * _characterHeight, - scale * _characterHeight / _characterAspectRatio, - _characterDepth); - if (!_rotation.zeroRotation()) - { - matrix.makeTranslate(-_offset); - matrix.postMult(scaleMatrix); - matrix.postMult(osg::Matrix::rotate(_rotation)); - matrix.postMult(osg::Matrix::translate(_position)); - } - else - { - matrix.makeTranslate(-_offset); - matrix.postMult(scaleMatrix); - matrix.postMult(osg::Matrix::translate(_position)); - } + osg::Vec3 scaleVec(scale * _characterHeight, scale * _characterHeight / _characterAspectRatio, _characterDepth); + matrix.makeTranslate(-_offset); + matrix.postMultScale(scaleVec); + matrix.postMultRotate(_rotation); + matrix.postMultTranslate(_position); _normal = osg::Matrix::transform3x3(osg::Vec3(0.0f,0.0f,1.0f),matrix); diff --git a/src/osgUtil/SceneGraphBuilder.cpp b/src/osgUtil/SceneGraphBuilder.cpp index 1f02845dd..7e26efab9 100644 --- a/src/osgUtil/SceneGraphBuilder.cpp +++ b/src/osgUtil/SceneGraphBuilder.cpp @@ -86,7 +86,7 @@ void SceneGraphBuilder::MultMatrixd(const GLdouble* m) void SceneGraphBuilder::Translated(GLdouble x, GLdouble y, GLdouble z) { if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd()); - _matrixStack.back().preMult(osg::Matrixd::translate(x,y,z)); + _matrixStack.back().preMultTranslate(osg::Vec3d(x,y,z)); matrixChanged(); } @@ -94,7 +94,7 @@ void SceneGraphBuilder::Translated(GLdouble x, GLdouble y, GLdouble z) void SceneGraphBuilder::Scaled(GLdouble x, GLdouble y, GLdouble z) { if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd()); - _matrixStack.back().preMult(osg::Matrixd::scale(x,y,z)); + _matrixStack.back().preMultScale(osg::Vec3d(x,y,z)); matrixChanged(); } @@ -102,7 +102,7 @@ void SceneGraphBuilder::Scaled(GLdouble x, GLdouble y, GLdouble z) void SceneGraphBuilder::Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { if (_matrixStack.empty()) _matrixStack.push_back(osg::Matrixd()); - _matrixStack.back().preMult(osg::Matrixd::rotate(osg::inDegrees(angle),x,y,z)); + _matrixStack.back().preMultRotate(osg::Quat(osg::inDegrees(angle),osg::Vec3d(x,y,z))); matrixChanged(); } diff --git a/src/osgViewer/View.cpp b/src/osgViewer/View.cpp index 22c15918a..e71081b7f 100644 --- a/src/osgViewer/View.cpp +++ b/src/osgViewer/View.cpp @@ -96,7 +96,7 @@ public: x = osg::Matrixd::transform3x3(x,coordinateFrame); y = osg::Matrixd::transform3x3(y,coordinateFrame); z = osg::Matrixd::transform3x3(z,coordinateFrame); - coordinateFrame.preMult(osg::Matrixd::scale(1.0/x.length(),1.0/y.length(),1.0/z.length())); + coordinateFrame.preMultScale(osg::Vec3d(1.0/x.length(),1.0/y.length(),1.0/z.length())); // reapply the position. coordinateFrame.setTrans(pos);