Index: /OpenSceneGraph/trunk/include/osg/AnimationPath
===================================================================
--- /OpenSceneGraph/trunk/include/osg/AnimationPath (revision 8768)
+++ /OpenSceneGraph/trunk/include/osg/AnimationPath (revision 8868)
@@ -92,28 +92,28 @@
             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);
             }
 
Index: /OpenSceneGraph/trunk/include/osg/Matrixd
===================================================================
--- /OpenSceneGraph/trunk/include/osg/Matrixd (revision 7890)
+++ /OpenSceneGraph/trunk/include/osg/Matrixd (revision 8868)
@@ -348,4 +348,23 @@
         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 ) {
@@ -648,4 +667,106 @@
 }
 
+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 )
 {
Index: /OpenSceneGraph/trunk/include/osg/Matrixf
===================================================================
--- /OpenSceneGraph/trunk/include/osg/Matrixf (revision 7890)
+++ /OpenSceneGraph/trunk/include/osg/Matrixf (revision 8868)
@@ -350,4 +350,23 @@
         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 ) {
@@ -642,4 +661,106 @@
 }
 
+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 )
Index: /OpenSceneGraph/trunk/src/osgUtil/SceneGraphBuilder.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgUtil/SceneGraphBuilder.cpp (revision 7941)
+++ /OpenSceneGraph/trunk/src/osgUtil/SceneGraphBuilder.cpp (revision 8868)
@@ -87,5 +87,5 @@
 {
     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();
@@ -95,5 +95,5 @@
 {
     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();
@@ -103,5 +103,5 @@
 {
     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();
Index: /OpenSceneGraph/trunk/src/osg/AutoTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/AutoTransform.cpp (revision 8804)
+++ /OpenSceneGraph/trunk/src/osg/AutoTransform.cpp (revision 8868)
@@ -84,17 +84,20 @@
 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;
@@ -105,8 +108,8 @@
     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;
Index: /OpenSceneGraph/trunk/src/osg/CameraView.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/CameraView.cpp (revision 5328)
+++ /OpenSceneGraph/trunk/src/osg/CameraView.cpp (revision 8868)
@@ -26,11 +26,11 @@
     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;
@@ -42,11 +42,11 @@
     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;
Index: /OpenSceneGraph/trunk/src/osg/PositionAttitudeTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/PositionAttitudeTransform.cpp (revision 5328)
+++ /OpenSceneGraph/trunk/src/osg/PositionAttitudeTransform.cpp (revision 8868)
@@ -16,5 +16,5 @@
 
 PositionAttitudeTransform::PositionAttitudeTransform():
-    _scale(1.0f,1.0f,1.0f)
+    _scale(1.0,1.0,1.0)
 {
 }
@@ -24,15 +24,15 @@
     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;
@@ -42,17 +42,20 @@
 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;
Index: /OpenSceneGraph/trunk/src/osg/Matrix_implementation.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osg/Matrix_implementation.cpp (revision 7301)
+++ /OpenSceneGraph/trunk/src/osg/Matrix_implementation.cpp (revision 8868)
@@ -19,4 +19,5 @@
 #include <osg/GL>
 
+#include <limits>
 #include <stdlib.h>
 
@@ -63,54 +64,69 @@
 #define QW  q._v[3]
 
-void Matrix_implementation::setRotate(const Quat& q_in)
-{
-    Quat q(q_in);
+void Matrix_implementation::setRotate(const Quat& q)
+{
     double length2 = q.length2();
-    if (length2!=1.0 && length2!=0)
-    {
+    if (fabs(length2) <= std::numeric_limits<double>::min())
+    {
+        _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.
-        q /= sqrt(length2);
-    }
-
-    // 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);
+        // 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);
+    }
 
 #if 0
@@ -904,5 +920,5 @@
         0.0,     0.0,     0.0,      1.0);
 
-    preMult(Matrix_implementation::translate(-eye));
+    preMultTranslate(-eye);
 }
 
Index: /OpenSceneGraph/trunk/src/osgText/Text.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgText/Text.cpp (revision 8093)
+++ /OpenSceneGraph/trunk/src/osgText/Text.cpp (revision 8868)
@@ -641,13 +641,12 @@
         }
 
-        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;
             
@@ -694,10 +693,10 @@
                 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));
             }
 
@@ -709,11 +708,11 @@
         }
 
-        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
Index: /OpenSceneGraph/trunk/src/osgText/Text3D.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgText/Text3D.cpp (revision 8441)
+++ /OpenSceneGraph/trunk/src/osgText/Text3D.cpp (revision 8868)
@@ -458,20 +458,9 @@
     
     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);
 
     
Index: /OpenSceneGraph/trunk/src/osgSim/Sector.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgSim/Sector.cpp (revision 8370)
+++ /OpenSceneGraph/trunk/src/osgSim/Sector.cpp (revision 8868)
@@ -235,8 +235,7 @@
   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));
 }
 
Index: /OpenSceneGraph/trunk/src/osgSim/DOFTransform.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgSim/DOFTransform.cpp (revision 6112)
+++ /OpenSceneGraph/trunk/src/osgSim/DOFTransform.cpp (revision 8868)
@@ -133,5 +133,5 @@
 
     //and scale:
-    current.preMult(osg::Matrix::scale(getCurrentScale()));
+    current.preMultScale(getCurrentScale());
 
     l2w.postMult(current);
@@ -202,5 +202,5 @@
 
     //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);
Index: /OpenSceneGraph/trunk/src/osgManipulator/AntiSquish.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgManipulator/AntiSquish.cpp (revision 6383)
+++ /OpenSceneGraph/trunk/src/osgManipulator/AntiSquish.cpp (revision 8868)
@@ -117,13 +117,10 @@
     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();
@@ -133,20 +130,16 @@
         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();
         }
@@ -155,11 +148,8 @@
 
         // Position
-        tmpPivot.makeIdentity();
         if (_usePosition)
-            tmpPivot.setTrans(_position);
+            unsquished.postMult(_position);
         else
-            tmpPivot.setTrans(_pivot);
-
-        unsquished.postMult(tmpPivot); 
+            unsquished.postMult(_pivot);
     }
     else
@@ -167,13 +157,21 @@
         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 );
     }
 
Index: /OpenSceneGraph/trunk/src/osgViewer/View.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgViewer/View.cpp (revision 8633)
+++ /OpenSceneGraph/trunk/src/osgViewer/View.cpp (revision 8868)
@@ -97,5 +97,5 @@
                 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.
Index: /OpenSceneGraph/trunk/src/osgParticle/PrecipitationEffect.cpp
===================================================================
--- /OpenSceneGraph/trunk/src/osgParticle/PrecipitationEffect.cpp (revision 8716)
+++ /OpenSceneGraph/trunk/src/osgParticle/PrecipitationEffect.cpp (revision 8868)
@@ -838,6 +838,6 @@
 
     *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);
Index: /OpenSceneGraph/trunk/examples/osgsimulation/osgsimulation.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgsimulation/osgsimulation.cpp (revision 8087)
+++ /OpenSceneGraph/trunk/examples/osgsimulation/osgsimulation.cpp (revision 8868)
@@ -147,5 +147,5 @@
                     //osg::Matrixd matrix;
                     ellipsoid->computeLocalToWorldTransformFromLatLongHeight(_latitude,_longitude,_height,matrix);
-                    matrix.preMult(osg::Matrix::rotate(_rotation));
+                    matrix.preMultRotate(_rotation);
                     
                     mt->setMatrix(matrix);
Index: /OpenSceneGraph/trunk/examples/osgunittests/UnitTests_osg.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgunittests/UnitTests_osg.cpp (revision 6941)
+++ /OpenSceneGraph/trunk/examples/osgunittests/UnitTests_osg.cpp (revision 8868)
@@ -20,4 +20,6 @@
 
 #include <osg/Matrixd>
+#include <osg/Matrixf>
+#include <osg/Vec3d>
 #include <osg/Vec3>
 #include <sstream>
@@ -85,3 +87,298 @@
 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)
+
+
+}
Index: /OpenSceneGraph/trunk/examples/osghangglide/osghangglide.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osghangglide/osghangglide.cpp (revision 6941)
+++ /OpenSceneGraph/trunk/examples/osghangglide/osghangglide.cpp (revision 8868)
@@ -55,5 +55,5 @@
         {
             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;
@@ -69,5 +69,5 @@
         {
             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;
Index: /OpenSceneGraph/trunk/examples/osglogo/osglogo.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osglogo/osglogo.cpp (revision 7848)
+++ /OpenSceneGraph/trunk/examples/osglogo/osglogo.cpp (revision 8868)
@@ -68,9 +68,8 @@
             }
 
-
-            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;
         }
Index: /OpenSceneGraph/trunk/examples/osgdepthpeeling/osgdepthpeeling.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgdepthpeeling/osgdepthpeeling.cpp (revision 7648)
+++ /OpenSceneGraph/trunk/examples/osgdepthpeeling/osgdepthpeeling.cpp (revision 8868)
@@ -175,25 +175,10 @@
   void rotate(float x, float y)
   {
-    osg::Matrixd 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);
+    osg::Matrix baseMatrix = _modelGroupTransform->getMatrix();
+    
+    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);
Index: /OpenSceneGraph/trunk/examples/osgvertexprogram/osgvertexprogram.cpp
===================================================================
--- /OpenSceneGraph/trunk/examples/osgvertexprogram/osgvertexprogram.cpp (revision 6941)
+++ /OpenSceneGraph/trunk/examples/osgvertexprogram/osgvertexprogram.cpp (revision 8868)
@@ -227,5 +227,5 @@
         {
             osg::Vec3 eyePointLocal = cv->getEyeLocal();
-            matrix.preMult(osg::Matrix::translate(eyePointLocal));
+            matrix.preMultTranslate(eyePointLocal);
         }
         return true;
@@ -239,5 +239,5 @@
         {
             osg::Vec3 eyePointLocal = cv->getEyeLocal();
-            matrix.postMult(osg::Matrix::translate(-eyePointLocal));
+            matrix.postMultTranslate(-eyePointLocal);
         }
         return true;
