Show
Ignore:
Timestamp:
09/17/08 18:14:28 (6 years ago)
Author:
robert
Message:

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 43 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 ...
"

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgManipulator/AntiSquish.cpp

    r6383 r8868  
    117117    if (_usePivot) 
    118118    { 
    119         osg::Matrix tmpPivot; 
    120         tmpPivot.setTrans(-_pivot); 
    121         unsquished.postMult(tmpPivot); 
     119        unsquished.postMultTranslate(-_pivot); 
    122120 
    123121        osg::Matrix tmps, invtmps; 
    124122        so.get(tmps); 
    125         invtmps = osg::Matrix::inverse(tmps); 
    126         if (invtmps.isNaN()) 
    127         { 
     123        if (!invtmps.invert(tmps)) 
     124        { 
    128125            flag = false; 
    129126            return osg::Matrix::identity(); 
     
    133130        unsquished.postMult(invtmps); 
    134131        //S 
    135         unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2])); 
     132        unsquished.postMultScale(s); 
    136133        //SO 
    137134        unsquished.postMult(tmps); 
    138         tmpPivot.makeIdentity(); 
    139         osg::Matrix tmpr; 
    140         r.get(tmpr); 
    141135        //R 
    142         unsquished.postMult(tmpr); 
     136        unsquished.postMultRotate(r); 
    143137        //T 
    144         unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2])); 
     138        unsquished.postMultTranslate(t); 
    145139 
    146140        osg::Matrix invltw; 
    147         invltw = osg::Matrix::inverse(LTW); 
    148         if (invltw.isNaN()) 
    149         { 
    150             flag =false; 
     141        if (!invltw.invert(LTW)) 
     142        { 
     143            flag = false; 
    151144            return osg::Matrix::identity(); 
    152145        } 
     
    155148 
    156149        // Position 
    157         tmpPivot.makeIdentity(); 
    158150        if (_usePosition) 
    159             tmpPivot.setTrans(_position); 
     151            unsquished.postMult(_position); 
    160152        else 
    161             tmpPivot.setTrans(_pivot); 
    162  
    163         unsquished.postMult(tmpPivot);  
     153            unsquished.postMult(_pivot); 
    164154    } 
    165155    else 
     
    167157        osg::Matrix tmps, invtmps; 
    168158        so.get(tmps); 
    169         invtmps = osg::Matrix::inverse(tmps); 
     159        if (!invtmps.invert(tmps)) 
     160        { 
     161            flag = false; 
     162            return osg::Matrix::identity(); 
     163        } 
    170164        unsquished.postMult(invtmps); 
    171         unsquished.postMult(osg::Matrix::scale(s[0], s[1], s[2])); 
     165        unsquished.postMultScale(s); 
    172166        unsquished.postMult(tmps); 
    173         osg::Matrix tmpr; 
    174         r.get(tmpr); 
    175         unsquished.postMult(tmpr); 
    176         unsquished.postMult(osg::Matrix::translate(t[0],t[1],t[2])); 
    177         unsquished.postMult( osg::Matrix::inverse(LTW) ); 
     167        unsquished.postMultRotate(r); 
     168        unsquished.postMultTranslate(t); 
     169        osg::Matrix invltw; 
     170        if (!invltw.invert(LTW)) 
     171        { 
     172            flag = false; 
     173            return osg::Matrix::identity(); 
     174        } 
     175        unsquished.postMult( invltw ); 
    178176    } 
    179177