(Sorry for the double post. I forgot to attach the patch in the last message.)

As many of you may know we have been running into problems with the
lack of double precision in OpenSG. After many months of putting it
off I have started looking into a solution that will have a minimal
affect on current code. I have come up with a first pass at a working
solution. The concept behind the attached patch is to make the
MatrixStore in OSGRenderPartition store matrix accumulations in double
precision. This is mainly because our scene graph is set up like the
following with our camera always located at the origin of the scene.


          Root
             |
      Navigation (Very large) - Actually the inverse of the normal
'camera' position.
        /     |     \
LandTile ...    LandTile  (Very large)

As you can see the final position of the geometry is very close to the
camera. We only need the matrix accumulation from the geometry to be
in double precision. The attached patch contains the following high
level changes:

1) Add the ability to multiply two matrices with different value
types. (Matrix4f * Matrix4d)
2) Change RenderTraversalAction::pushMatrix() and
RenderPartition::pushMatrix() to have a template that allows
accumulating matrices of different value types.
3) Store accumulated matrices in MatrixStack as double precision.
4) Convert back to floating point when creating each RenderTreeNode

What do people think about these changes? Is there a better method to
double precision without changing a *lot* of code?

Thanks,
Aron

P.S. It is worth noting that these changes are for the
fcptr_stable_jun07 branch. If we can all come to a conclusion I can
merge the changes to trunk.
Index: System/Action/RenderTraversal/OSGRenderTraversalAction.inl
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalAction.inl	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalAction.inl	(working copy)
@@ -85,6 +85,13 @@
 
 /*---------------------------- properties ---------------------------------*/
 
+template<class MatrixType> inline
+void RenderTraversalAction::pushMatrix(const MatrixType &matrix)
+{
+    _pActivePartition->pushMatrix(matrix);
+}
+
+
 inline
 void RenderTraversalAction::setKeyGen(UInt32 uiKeyGen)
 {
Index: System/Action/RenderTraversal/OSGRenderTraversalAction.cpp
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalAction.cpp	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalAction.cpp	(working copy)
@@ -708,11 +708,6 @@
     _pActivePartition->releaseLightIndex();
 }
 
-void RenderTraversalAction::pushMatrix(const Matrix &matrix)
-{
-    _pActivePartition->pushMatrix(matrix);
-}
-
 void RenderTraversalAction::popMatrix(void)
 {
     _pActivePartition->popMatrix();
Index: System/Action/RenderTraversal/OSGRenderPartition.cpp
===================================================================
--- System/Action/RenderTraversal/OSGRenderPartition.cpp	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderPartition.cpp	(working copy)
@@ -555,14 +555,32 @@
         Pnt3f         objPos;
         
         actNode->getVolume().getCenter(objPos);
-        
+
+#ifndef DOUBLE_MATRIX_STORE
         _currMatrix.second.mult(objPos);
+#else
+        Pnt3d temp(objPos[0], objPos[1], objPos[2]);
+        _currMatrix.second.mult(temp);
+#endif
         
         pNewElem->setNode       (&*actNode);
         pNewElem->setFunctor    ( func      );
+
+#ifndef DOUBLE_MATRIX_STORE
         pNewElem->setMatrixStore(_currMatrix);
+        pNewElem->setScalar     ( objPos[2] );
+#else
+        // Now that we have accumulated all transformations we can convert back
+        // to a floating point matrix.
+        Matrix4f tempMat;
+        tempMat.convertFrom(_currMatrix.second);
+        std::pair<UInt32, Matrix> temp_ms(_currMatrix.first, tempMat);
+
+        pNewElem->setMatrixStore(temp_ms);
+        pNewElem->setScalar     ( temp[2] );
+#endif
+
         pNewElem->setState      ( pState    );
-        pNewElem->setScalar     ( objPos[2] );
         
         if(_sStateOverrides.top()->empty() == false)
         {
@@ -600,8 +618,12 @@
         }
         
         RenderTreeNode *pNewElem = _pNodePool->create();
-        
+      
+#ifndef DOUBLE_MATRIX_STORE
         Pnt3f           objPos;
+#else
+        Pnt3d           objPos;
+#endif
         
         //_oDrawEnv.getRTAction()->getActNode()->getVolume().getCenter(objPos);
         
@@ -615,7 +637,11 @@
 
         objVol.getBounds(min,max);
 
+#ifndef DOUBLE_MATRIX_STORE
         Pnt3r p[8];
+#else
+        Pnt3d p[8];
+#endif
         p[0].setValues(min[0],min[1],min[2]);
         p[1].setValues(max[0],min[1],min[2]);
         p[2].setValues(min[0],max[1],min[2]);
@@ -646,7 +672,18 @@
         pNewElem->setNode       (&*actNode                 );
 
         pNewElem->setFunctor    ( func                     );
+
+#ifndef DOUBLE_MATRIX_STORE
         pNewElem->setMatrixStore(_currMatrix               );
+#else
+        // Now that we have accumulated all transformations we can convert back
+        // to a floating point matrix.
+        Matrix4f tempMat;
+        tempMat.convertFrom(_currMatrix.second);
+        std::pair<UInt32, Matrix> temp_ms(_currMatrix.first, tempMat);
+        pNewElem->setMatrixStore(temp_ms                   );
+#endif
+
         pNewElem->setState      ( pState                   );
 
         // Normalize scalar to 0..1 for bucket sorting
@@ -692,7 +729,17 @@
 
         pNewElem->setNode       (&* actNode   );
         pNewElem->setFunctor    (   func      );
+
+#ifndef DOUBLE_MATRIX_STORE
         pNewElem->setMatrixStore(  _currMatrix);
+#else
+        // Now that we have accumulated all transformations we can convert back
+        // to a floating point matrix.
+        Matrix4f tempMat;
+        tempMat.convertFrom(_currMatrix.second);
+        std::pair<UInt32, Matrix> temp_ms(_currMatrix.first, tempMat);
+        pNewElem->setMatrixStore(  temp_ms);
+#endif
                
         if(_sStateOverrides.top()->empty() == false)
         {
@@ -989,16 +1036,6 @@
     _accMatrix.mult(_currMatrix.second);
 }
 
-void RenderPartition::pushMatrix(const Matrix &matrix)
-{
-    _vMatrixStack.push_back(_currMatrix);
-    
-    _currMatrix.first = ++_uiMatrixId;
-    _currMatrix.second.mult(matrix);
-   
-    updateTopMatrix();
-}
-
 void RenderPartition::popMatrix(void         )
 {
     _currMatrix.first  = _vMatrixStack.back().first;
Index: System/Action/RenderTraversal/OSGRenderPartition.inl
===================================================================
--- System/Action/RenderTraversal/OSGRenderPartition.inl	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderPartition.inl	(working copy)
@@ -226,11 +226,28 @@
 {
     _oDrawEnv.setupViewing(matrix);
 
-    _currMatrix.second = matrix;
+#ifndef DOUBLE_MATRIX_STORE
+    _currMatrix.second = matrix
+#else
+    Matrix4d temp;
+    temp.convertFrom(matrix);
+    _currMatrix.second = temp;
+#endif
 
     updateTopMatrix();
 }
 
+template<class MatrixType> inline
+void RenderPartition::pushMatrix(const MatrixType &matrix)
+{
+    _vMatrixStack.push_back(_currMatrix);
+    
+    _currMatrix.first = ++_uiMatrixId;
+    _currMatrix.second.mult(matrix);
+   
+    updateTopMatrix();
+}
+
 inline 
 const Matrix4f &RenderPartition::getViewing(void)
 {
Index: System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalActionInit.cpp	(working copy)
@@ -60,6 +60,7 @@
 #include "OSGDistanceLOD.h"
 #include "OSGMaterialGroup.h"
 #include "OSGSwitch.h"
+#include "OSGDoubleTransform.h"
 #include "OSGTransform.h"
 #include "OSGDirectionalLight.h"
 #include "OSGPointLight.h"
@@ -337,6 +338,42 @@
     return ActionBase::Continue;
 }
 
+ActionBase::ResultE DoubleTransformRenderEnter(const NodeCorePtr &pCore,
+                                               Action      *action)
+{
+#ifdef OSG_DUMP_TRAVERSAL
+    FDEBUG_GV(("Enter DoubleTransform %p\n", &(*pCore)));
+#endif
+
+    DoubleTransformPtr pThis = cast_dynamic<DoubleTransformPtr>(pCore);
+
+    RenderTraversalAction *pAction = 
+        dynamic_cast<RenderTraversalAction *>(action);
+
+    pAction->pushVisibility();
+
+    pAction->pushMatrix(pThis->getMatrix());
+
+    return ActionBase::Continue;
+}
+
+ActionBase::ResultE DoubleTransformRenderLeave(const NodeCorePtr &pCore,
+                                               Action      *action)
+{
+#ifdef OSG_DUMP_TRAVERSAL
+    FDEBUG_GV(("Leave DoubleTransform %p\n", &(*pCore)));
+#endif
+
+    RenderTraversalAction *pAction = 
+        dynamic_cast<RenderTraversalAction *>(action);
+
+    pAction->popVisibility();
+
+    pAction->popMatrix();
+
+    return ActionBase::Continue;
+}
+
 ActionBase::ResultE MaterialGroupRenderEnter(const NodeCorePtr &pCore,
                                                    Action      *action)
 {
@@ -1154,6 +1191,15 @@
         Transform::getClassType(), 
         TransformRenderLeave);
 
+    RenderTraversalAction::registerEnterDefault(
+        DoubleTransform::getClassType(), 
+        DoubleTransformRenderEnter);
+
+    RenderTraversalAction::registerLeaveDefault(
+        DoubleTransform::getClassType(), 
+        DoubleTransformRenderLeave);
+
+
     RenderTraversalAction::registerEnterDefault( 
         DirectionalLight::getClassType(), 
         DirectionalLightRenderEnter);
Index: System/Action/RenderTraversal/OSGRenderTraversalAction.h
===================================================================
--- System/Action/RenderTraversal/OSGRenderTraversalAction.h	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderTraversalAction.h	(working copy)
@@ -163,7 +163,8 @@
 
     /*--------------------------- matrix ------------------------------------*/
 
-          void    pushMatrix (const Matrix &matrix);
+    template<class MatrixType>
+          void    pushMatrix (const MatrixType &matrix);
           void    popMatrix  (      void          );
 
     const Matrix &topMatrix  (      void          );
Index: System/Action/RenderTraversal/OSGRenderPartition.h
===================================================================
--- System/Action/RenderTraversal/OSGRenderPartition.h	(revision 1247)
+++ System/Action/RenderTraversal/OSGRenderPartition.h	(working copy)
@@ -61,6 +61,9 @@
 
 #include <stack>
 
+
+#define DOUBLE_MATRIX_STORE
+
 OSG_BEGIN_NAMESPACE
 
 //---------------------------------------------------------------------------
@@ -150,6 +153,9 @@
         to compare actual matrix elements.
     */
     typedef std::pair<UInt32, Matrix>               MatrixStore;
+#ifdef DOUBLE_MATRIX_STORE
+    typedef std::pair<UInt32, Matrix4d>             DoubleMatrixStore;
+#endif
     
     /*! DrawFunctor is the signature for the methods that are called 
         from within the draw tree
@@ -182,7 +188,11 @@
     typedef std::stack<StateOverride *>             OverrideStack;
 
     /*! MatrixStack keeps track of matrices during traversal */
+#ifdef DOUBLE_MATRIX_STORE
+    typedef std::vector<DoubleMatrixStore>          MatrixStack;
+#else
     typedef std::vector<MatrixStore>                MatrixStack;
+#endif
 
     typedef std::vector<RenderPartition *>          GroupStore;
 
@@ -291,8 +301,9 @@
     void execute(void);
 
     /*------------------------- assignment ----------------------------------*/
-    
-          void    pushMatrix(const Matrix &matrix);
+
+    template<class MatrixType>
+          void    pushMatrix(const MatrixType &matrix);
           void    popMatrix (      void          );
 
     const Matrix &topMatrix (      void          );
@@ -405,7 +416,11 @@
 
     UInt32              _uiMatrixId;
 
+#ifdef DOUBLE_MATRIX_STORE
+    DoubleMatrixStore   _currMatrix;
+#else
     MatrixStore         _currMatrix;
+#endif
     Matrix              _accMatrix;
 
     MatrixStack         _vMatrixStack;
Index: Base/Base/OSGMatrix.inl
===================================================================
--- Base/Base/OSGMatrix.inl	(revision 1247)
+++ Base/Base/OSGMatrix.inl	(working copy)
@@ -433,10 +433,11 @@
 /*-------------------------------------------------------------------------*/
 /*                               Helper                                    */
 
-template<class ValueTypeT> inline
-ValueTypeT TransformationMatrix<ValueTypeT>::rowMulCol4(
-    const TransformationMatrix &gRowMat, UInt32 iRow,
-    const TransformationMatrix &gColMat, UInt32 iColumn) const
+template<class ValueTypeT>
+template<class ValueTypeR, class ValueTypeS> inline
+ ValueTypeT TransformationMatrix<ValueTypeT>::rowMulCol4(
+    const TransformationMatrix<ValueTypeR> &gRowMat, UInt32 iRow,
+    const TransformationMatrix<ValueTypeS> &gColMat, UInt32 iColumn) const
 {
     return
         gRowMat[0][iRow] * gColMat[iColumn][0] +
@@ -1997,8 +1998,9 @@
     return true;
 }
 
-template<class ValueTypeT> inline
-void TransformationMatrix<ValueTypeT>::mult(const TransformationMatrix &matrix)
+template<class ValueTypeT>
+template<class ValueTypeR> inline
+void TransformationMatrix<ValueTypeT>::mult(const TransformationMatrix<ValueTypeR> &matrix)
 {
     ValueTypeT rTmpMat[4][4];
 
@@ -2043,9 +2045,10 @@
     _matrix[3][3] = rTmpMat[3][3];
 }
 
-template<class ValueTypeT> inline
+template<class ValueTypeT>
+template<class ValueTypeR> inline
 void TransformationMatrix<ValueTypeT>::multLeft(
-    const TransformationMatrix &matrix)
+    const TransformationMatrix<ValueTypeR> &matrix)
 {
     ValueTypeT rTmpMat[4][4];
 
Index: Base/Base/OSGMatrix.h
===================================================================
--- Base/Base/OSGMatrix.h	(revision 1247)
+++ Base/Base/OSGMatrix.h	(working copy)
@@ -354,8 +354,10 @@
     bool       transpose    (      void                        );
     bool       transposeFrom(const TransformationMatrix &matrix);
 
-    void       mult         (const TransformationMatrix &matrix);
-    void       multLeft     (const TransformationMatrix &matrix);
+    template<class ValueTypeR>
+    void       mult         (const TransformationMatrix<ValueTypeR>& mat);
+    template<class ValueTypeR>
+    void       multLeft     (const TransformationMatrix<ValueTypeR>& mat);
 
     void       add          (const TransformationMatrix &matrix);
     void       scale        (      ValueTypeT            s     );
@@ -416,10 +418,11 @@
     /*! \name                   Internal Math                              */
     /*! \{                                                                 */
 
-    ValueTypeT rowMulCol4(const TransformationMatrix &gRowMat,
-                                UInt32                iRow,
-                          const TransformationMatrix &gColMat,
-                                UInt32                iColumn) const;
+    template<class ValueTypeR, class ValueTypeS>
+    ValueTypeT rowMulCol4(const TransformationMatrix<ValueTypeR> &gRowMat,
+                                 UInt32                iRow,
+                          const TransformationMatrix<ValueTypeS> &gColMat,
+                                 UInt32                iColumn) const;
 
     ValueTypeT det2_calc (const ValueTypeT            a1,
                           const ValueTypeT            a2,
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core

Reply via email to